summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomi Korpipää <tomi.korpipaa@digia.com>2013-08-16 07:14:35 +0300
committerTomi Korpipää <tomi.korpipaa@digia.com>2013-08-16 07:14:35 +0300
commit6c0334496d50aaf4e11dcda7ed642fac565d6145 (patch)
treeaa6e7aeef9b00ba46910c30bd85fedbc53df39a0
parent3288b23502c195d03e097cb372a22f3a1ac4ba87 (diff)
parent29f6433606cebe3299e9915ae32bae7dfaed2770 (diff)
Merge remote-tracking branch 'origin/develop'
-rw-r--r--.gitignore5
-rw-r--r--examples/barchart/barchart.pro3
-rw-r--r--examples/barchart/doc/src/barchart.qdoc27
-rw-r--r--examples/barchart/main.cpp229
-rw-r--r--examples/examples.pri25
-rw-r--r--examples/examples.pro8
-rw-r--r--examples/mapdata/doc/src/mapdata.qdoc27
-rw-r--r--examples/mapdata/main.cpp44
-rw-r--r--examples/mapdata/mapdata.cpp312
-rw-r--r--examples/mapdata/mapdata.h48
-rw-r--r--examples/mapdata/mapdata.pro2
-rw-r--r--examples/qmlbarchart/doc/src/qmlbarchart.qdoc27
-rw-r--r--examples/qmlbarchart/main.cpp13
-rw-r--r--examples/qmlbarchart/qml/qmlbarchart/main.qml246
-rw-r--r--examples/qmlbarchart/qmlbarchart.pro3
-rw-r--r--examples/qmlbarchart/qmlbarchart.qrc5
-rw-r--r--examples/qmlmaps/doc/src/qmlmaps.qdoc29
-rw-r--r--examples/qmlmaps/floorplan.jpgbin0 -> 108298 bytes
-rw-r--r--examples/qmlmaps/main.cpp45
-rw-r--r--examples/qmlmaps/qml/qmlmaps/main.qml114
-rw-r--r--examples/qmlmaps/qmlmaps.desktop11
-rw-r--r--examples/qmlmaps/qmlmaps.pro29
-rw-r--r--examples/qmlmaps/qmlmaps.qrc8
-rw-r--r--examples/qmlmaps/qmlmaps64.pngbin0 -> 3400 bytes
-rw-r--r--examples/qmlmaps/qtquick2applicationviewer/qtquick2applicationviewer.cpp81
-rw-r--r--examples/qmlmaps/qtquick2applicationviewer/qtquick2applicationviewer.h33
-rw-r--r--examples/qmlmaps/qtquick2applicationviewer/qtquick2applicationviewer.pri180
-rw-r--r--examples/qmlscatter/doc/src/qmlscatter.qdoc29
-rw-r--r--examples/qmlscatter/main.cpp46
-rw-r--r--examples/qmlscatter/qml/qmlscatter/main.qml209
-rw-r--r--examples/qmlscatter/qmlscatter.desktop11
-rw-r--r--examples/qmlscatter/qmlscatter.pro23
-rw-r--r--examples/qmlscatter/qmlscatter.qrc5
-rw-r--r--examples/qmlscatter/qmlscatter64.pngbin0 -> 3400 bytes
-rw-r--r--examples/qmlscatter/qtquick2applicationviewer/qtquick2applicationviewer.cpp81
-rw-r--r--examples/qmlscatter/qtquick2applicationviewer/qtquick2applicationviewer.h33
-rw-r--r--examples/qmlscatter/qtquick2applicationviewer/qtquick2applicationviewer.pri180
-rw-r--r--examples/rainfall/data/raindata.txt1358
-rw-r--r--examples/rainfall/doc/src/rainfall.qdoc27
-rw-r--r--examples/rainfall/main.cpp323
-rw-r--r--examples/rainfall/rainfall.pro19
-rw-r--r--examples/rainfall/rainfall.qrc5
-rw-r--r--examples/rainfall/rainfallchart.cpp159
-rw-r--r--examples/rainfall/rainfallchart.h56
-rw-r--r--examples/rainfall/variantbardatamapping.cpp133
-rw-r--r--examples/rainfall/variantbardatamapping.h74
-rw-r--r--examples/rainfall/variantbardataproxy.cpp128
-rw-r--r--examples/rainfall/variantbardataproxy.h66
-rw-r--r--examples/rainfall/variantdataset.cpp63
-rw-r--r--examples/rainfall/variantdataset.h56
-rw-r--r--examples/scatterchart/doc/src/scatterchart.qdoc29
-rw-r--r--examples/scatterchart/main.cpp198
-rw-r--r--examples/scatterchart/scatterchart.cpp325
-rw-r--r--examples/scatterchart/scatterchart.h74
-rw-r--r--examples/scatterchart/scatterchart.pro10
-rw-r--r--examples/spectrum/doc/src/spectrum.qdoc27
-rw-r--r--examples/spectrum/spectrum.pro4
-rw-r--r--examples/spectrum/spectrumapp/engine.cpp42
-rw-r--r--examples/spectrum/spectrumapp/engine.h42
-rw-r--r--examples/spectrum/spectrumapp/frequencyspectrum.cpp42
-rw-r--r--examples/spectrum/spectrumapp/frequencyspectrum.h42
-rw-r--r--examples/spectrum/spectrumapp/main.cpp79
-rw-r--r--examples/spectrum/spectrumapp/spectrum.h44
-rw-r--r--examples/spectrum/spectrumapp/spectrumanalyser.cpp42
-rw-r--r--examples/spectrum/spectrumapp/spectrumanalyser.h42
-rw-r--r--examples/spectrum/spectrumapp/spectrumapp.pro10
-rw-r--r--examples/spectrum/spectrumapp/utils.cpp42
-rw-r--r--examples/spectrum/spectrumapp/utils.h42
-rw-r--r--examples/spectrum/spectrumapp/wavfile.cpp42
-rw-r--r--examples/spectrum/spectrumapp/wavfile.h42
-rw-r--r--examples/surfacechart/chartmodifier.cpp126
-rw-r--r--examples/surfacechart/chartmodifier.h53
-rw-r--r--examples/surfacechart/main.cpp171
-rw-r--r--examples/surfacechart/surfacechart.pro11
-rw-r--r--examples/widget/chart.cpp313
-rw-r--r--examples/widget/chart.h67
-rw-r--r--examples/widget/doc/src/widget.qdoc27
-rw-r--r--examples/widget/main.cpp102
-rw-r--r--examples/widget/widget.pro2
-rw-r--r--src/datavis3d/Doxyfile1196
-rw-r--r--src/datavis3d/Mainpage.dox96
-rw-r--r--src/datavis3d/axis/axis.pri12
-rw-r--r--src/datavis3d/axis/qabstractaxis.cpp84
-rw-r--r--src/datavis3d/axis/qabstractaxis.h86
-rw-r--r--src/datavis3d/axis/qabstractaxis_p.h61
-rw-r--r--src/datavis3d/axis/qcategoryaxis.cpp60
-rw-r--r--src/datavis3d/axis/qcategoryaxis.h54
-rw-r--r--src/datavis3d/axis/qcategoryaxis_p.h49
-rw-r--r--src/datavis3d/axis/qvalueaxis.cpp235
-rw-r--r--src/datavis3d/axis/qvalueaxis.h77
-rw-r--r--src/datavis3d/axis/qvalueaxis_p.h67
-rw-r--r--src/datavis3d/common.pri5
-rw-r--r--src/datavis3d/data/abstractrenderitem.cpp65
-rw-r--r--src/datavis3d/data/abstractrenderitem_p.h74
-rw-r--r--src/datavis3d/data/barrenderitem.cpp46
-rw-r--r--src/datavis3d/data/barrenderitem_p.h84
-rw-r--r--src/datavis3d/data/data.pri52
-rw-r--r--src/datavis3d/data/labelitem.cpp64
-rw-r--r--src/datavis3d/data/labelitem_p.h59
-rw-r--r--src/datavis3d/data/maprenderitem.cpp52
-rw-r--r--src/datavis3d/data/maprenderitem_p.h69
-rw-r--r--src/datavis3d/data/qabstractdataproxy.cpp68
-rw-r--r--src/datavis3d/data/qabstractdataproxy.h69
-rw-r--r--src/datavis3d/data/qabstractdataproxy_p.h58
-rw-r--r--src/datavis3d/data/qbardataitem.cpp99
-rw-r--r--src/datavis3d/data/qbardataitem.h54
-rw-r--r--src/datavis3d/data/qbardataitem_p.h51
-rw-r--r--src/datavis3d/data/qbardataproxy.cpp262
-rw-r--r--src/datavis3d/data/qbardataproxy.h122
-rw-r--r--src/datavis3d/data/qbardataproxy_p.h69
-rw-r--r--src/datavis3d/data/qitemmodelbardatamapping.cpp156
-rw-r--r--src/datavis3d/data/qitemmodelbardatamapping.h77
-rw-r--r--src/datavis3d/data/qitemmodelbardatamapping_p.h59
-rw-r--r--src/datavis3d/data/qitemmodelbardataproxy.cpp290
-rw-r--r--src/datavis3d/data/qitemmodelbardataproxy.h59
-rw-r--r--src/datavis3d/data/qitemmodelbardataproxy_p.h77
-rw-r--r--src/datavis3d/data/qitemmodelmapdatamapping.cpp130
-rw-r--r--src/datavis3d/data/qitemmodelmapdatamapping.h66
-rw-r--r--src/datavis3d/data/qitemmodelmapdatamapping_p.h56
-rw-r--r--src/datavis3d/data/qitemmodelmapdataproxy.cpp275
-rw-r--r--src/datavis3d/data/qitemmodelmapdataproxy.h59
-rw-r--r--src/datavis3d/data/qitemmodelmapdataproxy_p.h81
-rw-r--r--src/datavis3d/data/qitemmodelscatterdatamapping.cpp154
-rw-r--r--src/datavis3d/data/qitemmodelscatterdatamapping.h70
-rw-r--r--src/datavis3d/data/qitemmodelscatterdatamapping_p.h57
-rw-r--r--src/datavis3d/data/qitemmodelscatterdataproxy.cpp305
-rw-r--r--src/datavis3d/data/qitemmodelscatterdataproxy.h60
-rw-r--r--src/datavis3d/data/qitemmodelscatterdataproxy_p.h81
-rw-r--r--src/datavis3d/data/qmapdataitem.cpp100
-rw-r--r--src/datavis3d/data/qmapdataitem.h57
-rw-r--r--src/datavis3d/data/qmapdataitem_p.h52
-rw-r--r--src/datavis3d/data/qmapdataproxy.cpp111
-rw-r--r--src/datavis3d/data/qmapdataproxy.h88
-rw-r--r--src/datavis3d/data/qmapdataproxy_p.h58
-rw-r--r--src/datavis3d/data/qscatterdataitem.cpp111
-rw-r--r--src/datavis3d/data/qscatterdataitem.h57
-rw-r--r--src/datavis3d/data/qscatterdataitem_p.h51
-rw-r--r--src/datavis3d/data/qscatterdataproxy.cpp210
-rw-r--r--src/datavis3d/data/qscatterdataproxy.h87
-rw-r--r--src/datavis3d/data/qscatterdataproxy_p.h65
-rw-r--r--src/datavis3d/data/scatterrenderitem.cpp51
-rw-r--r--src/datavis3d/data/scatterrenderitem_p.h68
-rw-r--r--src/datavis3d/datavis3d.pro4
-rw-r--r--src/datavis3d/doc/qtdatavis3d.qdocconf2
-rw-r--r--src/datavis3d/doc/snippets/doc_src_q3dbars_construction.cpp42
-rw-r--r--src/datavis3d/doc/snippets/doc_src_qtdatavis3d.cpp39
-rw-r--r--src/datavis3d/doc/snippets/doc_src_qtdatavis3d.pro39
-rw-r--r--src/datavis3d/doc/src/qtdatavis3d-index.qdoc30
-rw-r--r--src/datavis3d/doc/src/qtdatavis3d.qdoc27
-rw-r--r--src/datavis3d/doc/src/qtdatavis3dlicense.qdoc27
-rw-r--r--src/datavis3d/documentationGroups.dox150
-rw-r--r--src/datavis3d/engine/abstract3dcontroller.cpp698
-rw-r--r--src/datavis3d/engine/abstract3dcontroller_p.h293
-rw-r--r--src/datavis3d/engine/abstract3drenderer.cpp219
-rw-r--r--src/datavis3d/engine/abstract3drenderer_p.h117
-rw-r--r--src/datavis3d/engine/axisrendercache.cpp153
-rw-r--r--src/datavis3d/engine/axisrendercache_p.h96
-rw-r--r--src/datavis3d/engine/bars3dcontroller.cpp457
-rw-r--r--src/datavis3d/engine/bars3dcontroller_p.h157
-rw-r--r--src/datavis3d/engine/bars3drenderer.cpp1839
-rw-r--r--src/datavis3d/engine/bars3drenderer_p.h200
-rw-r--r--src/datavis3d/engine/bars3dshared.cpp2421
-rw-r--r--src/datavis3d/engine/bars3dshared_p.h326
-rw-r--r--src/datavis3d/engine/drawer.cpp167
-rw-r--r--src/datavis3d/engine/drawer_p.h86
-rw-r--r--src/datavis3d/engine/engine.pri53
-rw-r--r--src/datavis3d/engine/engine.qrc8
-rw-r--r--src/datavis3d/engine/labelitem.cpp76
-rw-r--r--src/datavis3d/engine/labelitem_p.h79
-rw-r--r--src/datavis3d/engine/maps3dcontroller.cpp1763
-rw-r--r--src/datavis3d/engine/maps3dcontroller_p.h253
-rw-r--r--src/datavis3d/engine/maps3drenderer.cpp74
-rw-r--r--src/datavis3d/engine/maps3drenderer_p.h53
-rw-r--r--src/datavis3d/engine/meshes/scatterdot.obj28
-rw-r--r--src/datavis3d/engine/meshes/scatterdotFlat.obj28
-rw-r--r--src/datavis3d/engine/q3dbars.cpp418
-rw-r--r--src/datavis3d/engine/q3dbars.h173
-rw-r--r--src/datavis3d/engine/q3dbars_p.h58
-rw-r--r--src/datavis3d/engine/q3dmaps.cpp1654
-rw-r--r--src/datavis3d/engine/q3dmaps.h122
-rw-r--r--src/datavis3d/engine/q3dmaps_p.h153
-rw-r--r--src/datavis3d/engine/q3dscatter.cpp463
-rw-r--r--src/datavis3d/engine/q3dscatter.h153
-rw-r--r--src/datavis3d/engine/q3dscatter_p.h51
-rw-r--r--src/datavis3d/engine/q3dsurface.cpp181
-rw-r--r--src/datavis3d/engine/q3dsurface.h84
-rw-r--r--src/datavis3d/engine/q3dsurface_p.h62
-rw-r--r--src/datavis3d/engine/q3dwindow.cpp74
-rw-r--r--src/datavis3d/engine/q3dwindow.h48
-rw-r--r--src/datavis3d/engine/q3dwindow_p.h47
-rw-r--r--src/datavis3d/engine/qdataitem.cpp230
-rw-r--r--src/datavis3d/engine/qdataitem.h91
-rw-r--r--src/datavis3d/engine/qdataitem_p.h102
-rw-r--r--src/datavis3d/engine/qdatarow.cpp187
-rw-r--r--src/datavis3d/engine/qdatarow.h78
-rw-r--r--src/datavis3d/engine/qdatarow_p.h91
-rw-r--r--src/datavis3d/engine/qdataset.cpp307
-rw-r--r--src/datavis3d/engine/qdataset.h81
-rw-r--r--src/datavis3d/engine/qdataset_p.h107
-rw-r--r--src/datavis3d/engine/scatter3dcontroller.cpp365
-rw-r--r--src/datavis3d/engine/scatter3dcontroller_p.h124
-rw-r--r--src/datavis3d/engine/scatter3drenderer.cpp1648
-rw-r--r--src/datavis3d/engine/scatter3drenderer_p.h178
-rw-r--r--src/datavis3d/engine/shaders/colorOnY_ES2.frag1
-rw-r--r--src/datavis3d/engine/shaders/selection.frag1
-rw-r--r--src/datavis3d/engine/shaders/surface.frag39
-rw-r--r--src/datavis3d/engine/shaders/surface.vert30
-rw-r--r--src/datavis3d/engine/shaders/surfaceFlat.frag38
-rw-r--r--src/datavis3d/engine/shaders/surfaceFlat.vert30
-rw-r--r--src/datavis3d/engine/shaders/surfaceGrid.frag16
-rw-r--r--src/datavis3d/engine/shaders/surfaceGrid.vert26
-rw-r--r--src/datavis3d/engine/surface3dcontroller.cpp211
-rw-r--r--src/datavis3d/engine/surface3dcontroller_p.h121
-rw-r--r--src/datavis3d/engine/surface3drenderer.cpp894
-rw-r--r--src/datavis3d/engine/surface3drenderer_p.h189
-rw-r--r--src/datavis3d/engine/theme.cpp95
-rw-r--r--src/datavis3d/engine/theme_p.h65
-rw-r--r--src/datavis3d/global/datavis3dglobal_p.h52
-rw-r--r--src/datavis3d/global/global.pri7
-rw-r--r--src/datavis3d/global/qdatavis3denums.h115
-rw-r--r--src/datavis3d/global/qdatavis3dglobal.h81
-rw-r--r--src/datavis3d/global/qdatavis3namespace.h147
-rw-r--r--src/datavis3d/global/qtdatavis3dnamespace.qdoc163
-rw-r--r--src/datavis3d/utils/abstractobjecthelper.cpp81
-rw-r--r--src/datavis3d/utils/abstractobjecthelper_p.h65
-rw-r--r--src/datavis3d/utils/camerahelper.cpp154
-rw-r--r--src/datavis3d/utils/camerahelper_p.h88
-rw-r--r--src/datavis3d/utils/meshloader.cpp43
-rw-r--r--src/datavis3d/utils/meshloader_p.h47
-rw-r--r--src/datavis3d/utils/objecthelper.cpp90
-rw-r--r--src/datavis3d/utils/objecthelper_p.h69
-rw-r--r--src/datavis3d/utils/shaderhelper.cpp43
-rw-r--r--src/datavis3d/utils/shaderhelper_p.h47
-rw-r--r--src/datavis3d/utils/surfaceobject.cpp349
-rw-r--r--src/datavis3d/utils/surfaceobject_p.h65
-rw-r--r--src/datavis3d/utils/texturehelper.cpp82
-rw-r--r--src/datavis3d/utils/texturehelper_p.h54
-rw-r--r--src/datavis3d/utils/utils.cpp73
-rw-r--r--src/datavis3d/utils/utils.pri8
-rw-r--r--src/datavis3d/utils/utils_p.h50
-rw-r--r--src/datavis3d/utils/vertexindexer.cpp45
-rw-r--r--src/datavis3d/utils/vertexindexer_p.h47
-rw-r--r--src/datavis3dqml2/datavis3dqml2.pro30
-rw-r--r--src/datavis3dqml2/datavis3dqml2_plugin.cpp67
-rw-r--r--src/datavis3dqml2/datavis3dqml2_plugin.h82
-rw-r--r--src/datavis3dqml2/declarativebars.cpp450
-rw-r--r--src/datavis3dqml2/declarativebars.h233
-rw-r--r--src/datavis3dqml2/declarativebars_p.h228
-rw-r--r--src/datavis3dqml2/declarativebarsrenderer.cpp86
-rw-r--r--src/datavis3dqml2/declarativebarsrenderer_p.h65
-rw-r--r--src/datavis3dqml2/declarativemaps.cpp241
-rw-r--r--src/datavis3dqml2/declarativemaps.h105
-rw-r--r--src/datavis3dqml2/declarativemaps_p.h139
-rw-r--r--src/datavis3dqml2/declarativemapsrenderer.cpp79
-rw-r--r--src/datavis3dqml2/declarativemapsrenderer_p.h62
-rw-r--r--src/datavis3dqml2/declarativescatter.cpp328
-rw-r--r--src/datavis3dqml2/declarativescatter_p.h175
-rw-r--r--src/datavis3dqml2/declarativescatterrenderer.cpp87
-rw-r--r--src/datavis3dqml2/declarativescatterrenderer_p.h65
-rw-r--r--src/src.pro2
260 files changed, 25732 insertions, 11454 deletions
diff --git a/.gitignore b/.gitignore
index 24601177..064012c7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -244,3 +244,8 @@ work
.obj/
+mkspecs/
+examples/spectrum/*.dll*
+examples/spectrum/*.exe*
+examples/spectrum/*.lib
+examples/spectrum/*.exp \ No newline at end of file
diff --git a/examples/barchart/barchart.pro b/examples/barchart/barchart.pro
index 381b3402..12b296c5 100644
--- a/examples/barchart/barchart.pro
+++ b/examples/barchart/barchart.pro
@@ -3,6 +3,7 @@
}
SOURCES += main.cpp
-QT += datavis3d
INSTALLS += target
+
+QT += widgets
diff --git a/examples/barchart/doc/src/barchart.qdoc b/examples/barchart/doc/src/barchart.qdoc
index 498388bb..6c2c8760 100644
--- a/examples/barchart/doc/src/barchart.qdoc
+++ b/examples/barchart/doc/src/barchart.qdoc
@@ -1,27 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
-** This file is part of the documentation of the QtDataVis3D module.
+** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:FDL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: http://www.gnu.org/copyleft/fdl.html.
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
diff --git a/examples/barchart/main.cpp b/examples/barchart/main.cpp
index 6887bb0b..77230b5d 100644
--- a/examples/barchart/main.cpp
+++ b/examples/barchart/main.cpp
@@ -1,47 +1,29 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
-** This file is part of the documentation of the QtDataVis3D module.
+** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
-** of its contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
-#include "q3dbars.h"
-#include "qdataset.h"
+#include <QtDataVis3D/q3dbars.h>
+#include <QtDataVis3D/qcategoryaxis.h>
+#include <QtDataVis3D/qitemmodelbardataproxy.h>
+#include <QtDataVis3D/qvalueaxis.h>
-#include <QGuiApplication>
+#include <QApplication>
+#include <QVBoxLayout>
+#include <QTableWidget>
#include <QScreen>
#include <QTimer>
#include <QFont>
@@ -57,11 +39,11 @@ using namespace QtDataVis3D;
class ChartDataGenerator : public QObject
{
public:
- explicit ChartDataGenerator(Q3DBars *barchart);
+ explicit ChartDataGenerator(Q3DBars *barchart, QTableWidget *tableWidget);
~ChartDataGenerator();
- void addDataSet();
- void addBars();
+ void setupModel();
+ void addRow();
void changeStyle();
void changePresetCamera();
void changeTheme();
@@ -75,16 +57,18 @@ private:
QTimer *m_themeTimer;
int m_columnCount;
int m_rowCount;
+ QTableWidget *m_tableWidget; // not owned
};
-ChartDataGenerator::ChartDataGenerator(Q3DBars *barchart)
+ChartDataGenerator::ChartDataGenerator(Q3DBars *barchart, QTableWidget *tableWidget)
: m_chart(barchart),
m_dataTimer(0),
m_styleTimer(0),
m_presetTimer(0),
m_themeTimer(0),
- m_columnCount(21),
- m_rowCount(21)
+ m_columnCount(100),
+ m_rowCount(50),
+ m_tableWidget(tableWidget)
{
// Set up bar specifications; make the bars as wide as they are deep,
// and add a small space between the bars
@@ -92,20 +76,21 @@ ChartDataGenerator::ChartDataGenerator(Q3DBars *barchart)
#ifndef USE_STATIC_DATA
// Set up sample space; make it as deep as it's wide
- m_chart->setupSampleSpace(m_columnCount, m_rowCount);
+ m_chart->setupSampleSpace(m_rowCount, m_columnCount);
+ m_tableWidget->setColumnCount(m_columnCount);
#endif
// Set bar type to smooth bar
#ifndef CYCLE_THROUGH_STYLES
- m_chart->setBarType(Pyramids, false);
+ m_chart->setBarType(QDataVis::Pyramids, false);
#endif
#ifndef USE_STATIC_DATA
// Set selection mode to full
- m_chart->setSelectionMode(ModeBarRowAndColumn);
+ m_chart->setSelectionMode(QDataVis::ModeItemRowAndColumn);
#else
// Set selection mode to zoom row
- m_chart->setSelectionMode(ModeZoomRow);
+ m_chart->setSelectionMode(QDataVis::ModeZoomRow);
m_chart->setFont(QFont("Courier", 25));
#endif
@@ -113,11 +98,11 @@ ChartDataGenerator::ChartDataGenerator(Q3DBars *barchart)
// Set bar colors
m_chart->setBarColor(QColor(Qt::gray), QColor(Qt::red), QColor(Qt::darkBlue));
#else
- m_chart->setLabelTransparency(TransparencyNone);
+ m_chart->setLabelTransparency(QDataVis::TransparencyNone);
#endif
// Set preset camera position
- m_chart->setCameraPreset(PresetFront);
+ m_chart->setCameraPreset(QDataVis::PresetFront);
}
ChartDataGenerator::~ChartDataGenerator()
@@ -146,11 +131,11 @@ void ChartDataGenerator::start()
#ifndef USE_STATIC_DATA
m_dataTimer = new QTimer();
m_dataTimer->setTimerType(Qt::CoarseTimer);
- m_dataTimer->setInterval(100);
- QObject::connect(m_dataTimer, &QTimer::timeout, this, &ChartDataGenerator::addBars);
- m_dataTimer->start(100);
+ m_dataTimer->setInterval(20);
+ QObject::connect(m_dataTimer, &QTimer::timeout, this, &ChartDataGenerator::addRow);
+ m_dataTimer->start(20);
#else
- addDataSet();
+ setupModel();
#endif
#ifdef CYCLE_THROUGH_STYLES
@@ -182,84 +167,53 @@ void ChartDataGenerator::start()
#endif
}
-void ChartDataGenerator::addDataSet()
+void ChartDataGenerator::setupModel()
{
-#if 0
- // Prepare data to be visualized
- // Use float vector adder
- QVector< QVector<float> > data;
- QVector<float> row;
- // TODO: Keep here for testing
- for (int j = 0; j < m_rowCount; j++) {
- for (int i = 0; i < m_columnCount; i++) {
- row.prepend(((float)i / (float)m_columnCount) * 100 + (float)(rand() % 30));
- //row.append(1.0f);
- }
- data.append(row);
- row.clear();
- }
- // Set up sample space based on inserted data
- m_chart->setupSampleSpace(m_columnCount, m_rowCount);
- // Add data to chart
- m_chart->addDataSet(data);
-#else
- // Prepare data to be visualized
- // Use QDataSet adder
-
- // Set window title
- m_chart->setWindowTitle(QStringLiteral("Hours playing banjo"));
-
// Set up row and column names
- QVector<QString> days;
+ QStringList days;
days << "Monday" << "Tuesday" << "Wednesday" << "Thursday" << "Friday" << "Saturday" << "Sunday";
- QVector<QString> weeks;
+ QStringList weeks;
weeks << "week 1" << "week 2" << "week 3" << "week 4" << "week 5";
// Set up data Mon Tue Wed Thu Fri Sat Sun
- float hours[5][7] = {{2.0f, 1.0f, 3.0f, 0.2f, 1.0f, 5.0f, 7.0f}, // week 1
+ float hours[5][7] = {{2.0f, 1.0f, 3.0f, 0.2f, 1.0f, 5.0f, 10.0f}, // week 1
{0.5f, 1.0f, 3.0f, 1.0f, 2.0f, 2.0f, 3.0f}, // week 2
{1.0f, 1.0f, 2.0f, 1.0f, 4.0f, 4.0f, 4.0f}, // week 3
- {0.0f, 0.0f, 0.0f, 0.0f, 2.0f, 2.0f, 0.3f}, // week 4
+ {0.0f, 1.0f, 0.0f, 0.0f, 2.0f, 2.0f, 0.3f}, // week 4
{3.0f, 3.0f, 6.0f, 2.0f, 2.0f, 1.0f, 1.0f}}; // week 5
- // Set tick count and step, we want a line every hour -> 7 ticks, step 1 hour
- m_chart->setTickCount(7, 1.0f);
-
- // Create data set
- QDataSet *dataSet = new QDataSet();
-
// Add labels
- dataSet->setLabels("Week of year", "Day of week", "Hours playing banjo", weeks, days);
+ m_chart->rowAxis()->setTitle("Week of year");
+ m_chart->columnAxis()->setTitle("Day of week");
+ m_chart->valueAxis()->setTitle("Hours playing banjo");
+ m_chart->valueAxis()->setSegmentCount(5);
+ m_chart->rowAxis()->setCategoryLabels(weeks);
+ m_chart->columnAxis()->setCategoryLabels(days);
+
+ m_tableWidget->setRowCount(5);
+ m_tableWidget->setColumnCount(7);
+ m_tableWidget->setHorizontalHeaderLabels(days);
+ m_tableWidget->setVerticalHeaderLabels(weeks);
- // Create data rows
- QDataRow *dataRow;
for (int week = 0; week < weeks.size(); week++) {
- dataRow = new QDataRow(weeks.at(week));
- // Create data items
for (int day = 0; day < days.size(); day++) {
- // Add data to rows
- dataRow->addItem(new QDataItem(hours[week][day], "h"));//, " + days.at(day)));
+ QModelIndex index = m_tableWidget->model()->index(week, day);
+ m_tableWidget->model()->setData(index, hours[week][day]);
}
- // Add row to set
- dataSet->addRow(dataRow);
- // Get next pointer
- dataRow++;
}
// Set up sample space based on prepared data
- m_chart->setupSampleSpace(days.size(), weeks.size());
-
- // Add data to chart
- m_chart->addDataSet(dataSet);
-#endif
+ m_chart->setupSampleSpace(weeks.size(), days.size());
}
-void ChartDataGenerator::addBars()
+void ChartDataGenerator::addRow()
{
- QVector<float> data;
- for (int i = 0; i < m_columnCount; i++)
- data.append(((float)i / (float)m_columnCount) / 2.0f + (float)(rand() % 30) / 100);
- m_chart->addDataRow(data);
+ m_tableWidget->model()->insertRow(0);
+ for (int i = 0; i < m_columnCount; i++) {
+ QModelIndex index = m_tableWidget->model()->index(0, i);
+ m_tableWidget->model()->setData(index,
+ ((qreal)i / (qreal)m_columnCount) / 2.0 + (qreal)(rand() % 30) / 100.0);
+ }
}
void ChartDataGenerator::changeStyle()
@@ -267,28 +221,28 @@ void ChartDataGenerator::changeStyle()
static int model = 0;
switch (model) {
case 0:
- m_chart->setBarType(Cylinders, false);
+ m_chart->setBarType(QDataVis::Cylinders, false);
break;
case 1:
- m_chart->setBarType(Cylinders, true);
+ m_chart->setBarType(QDataVis::Cylinders, true);
break;
case 2:
- m_chart->setBarType(Cones, false);
+ m_chart->setBarType(QDataVis::Cones, false);
break;
case 3:
- m_chart->setBarType(Cones, true);
+ m_chart->setBarType(QDataVis::Cones, true);
break;
case 4:
- m_chart->setBarType(Bars, false);
+ m_chart->setBarType(QDataVis::Bars, false);
break;
case 5:
- m_chart->setBarType(Bars, true);
+ m_chart->setBarType(QDataVis::Bars, true);
break;
case 6:
- m_chart->setBarType(Pyramids, false);
+ m_chart->setBarType(QDataVis::Pyramids, false);
break;
case 7:
- m_chart->setBarType(Pyramids, true);
+ m_chart->setBarType(QDataVis::Pyramids, true);
break;
}
model++;
@@ -300,9 +254,9 @@ void ChartDataGenerator::changePresetCamera()
{
static int preset = 0;
- m_chart->setCameraPreset((CameraPreset)preset);
+ m_chart->setCameraPreset((QDataVis::CameraPreset)preset);
- if (++preset > (int)PresetDirectlyAboveCCW45)
+ if (++preset > (int)QDataVis::PresetDirectlyAboveCCW45)
preset = 0;
}
@@ -310,24 +264,45 @@ void ChartDataGenerator::changeTheme()
{
static int theme = 0;
- m_chart->setTheme((ColorTheme)theme);
+ m_chart->setTheme((QDataVis::ColorTheme)theme);
- if (++theme > (int)ThemeLight)
+ if (++theme > (int)QDataVis::ThemeLight)
theme = 0;
}
int main(int argc, char **argv)
{
- QGuiApplication app(argc, argv);
+ QApplication app(argc, argv);
+
+ QWidget *widget = new QWidget;
+ QVBoxLayout *layout = new QVBoxLayout(widget);
+
+ Q3DBars *chart = new Q3DBars();
+ QSize screenSize = chart->screen()->size();
- Q3DBars barchart;
- QSize screenSize = barchart.screen()->size();
- barchart.resize(screenSize.width() / 1.5, screenSize.height() / 1.5);
- barchart.setPosition(screenSize.width() / 6, screenSize.height() / 6);
- barchart.show();
+ QWidget *container = QWidget::createWindowContainer(chart);
+ container->setMinimumSize(QSize(screenSize.width() / 2, screenSize.height() / 2));
+ container->setMaximumSize(screenSize);
+ container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ container->setFocusPolicy(Qt::StrongFocus);
- ChartDataGenerator *generator = new ChartDataGenerator(&barchart);
+ widget->setWindowTitle(QStringLiteral("Hours playing banjo"));
+
+ QTableWidget *tableWidget = new QTableWidget(0, 0, widget);
+
+ layout->addWidget(tableWidget);
+ layout->addWidget(container, 1);
+
+ // We don't need to initialize the mapping object in any way, as it defaults
+ // to row/column support and uses the Qt::DisplayRole role for value role by default.
+ QItemModelBarDataMapping mapping;
+ QItemModelBarDataProxy *proxy = new QItemModelBarDataProxy(tableWidget->model(), &mapping);
+ chart->setDataProxy(proxy);
+
+ ChartDataGenerator *generator = new ChartDataGenerator(chart, tableWidget);
generator->start();
+ widget->show();
+
return app.exec();
}
diff --git a/examples/examples.pri b/examples/examples.pri
index f20862e7..48d2f29a 100644
--- a/examples/examples.pri
+++ b/examples/examples.pri
@@ -11,6 +11,10 @@ win32 {
DESTDIR = $$OUT_PWD
}
+LIBS += -L$$OUT_PWD/../../lib
+
+QT += datavis3d
+
contains(TARGET, qml.*) {
uri = com.digia.QtDataVis3D
lib_name = datavis3dqml2
@@ -46,7 +50,8 @@ contains(TARGET, qml.*) {
src_lib = lib$${lib_name}.dylib
}
} else {
- src_lib = $${lib_name}.so
+ # linux, android
+ src_lib = lib$${lib_name}.so
}
}
copy_lib.target = $$make_qmldir_path/$$src_lib
@@ -54,14 +59,12 @@ contains(TARGET, qml.*) {
copy_lib.commands = $(COPY_FILE) \"$$replace(copy_lib.depends, /, $$QMAKE_DIR_SEP)\" \"$$replace(copy_lib.target, /, $$QMAKE_DIR_SEP)\"
QMAKE_EXTRA_TARGETS += copy_lib
PRE_TARGETDEPS += $$copy_lib.target
-}
-#android {
-# contains(TARGET, qml.*) {
-# charts_qmldir.files = $$CHART_BUILD_QML_PLUGIN_DIR/qmldir
-# charts_qmldir.path = /assets/imports/QtCommercial/Chart
-# charts_qmlplugin.files = $$CHART_BUILD_QML_PLUGIN_DIR/libqtcommercialchartqml.so
-# charts_qmlplugin.path = /libs/$$ANDROID_TARGET_ARCH
-# INSTALLS += charts_qmldir charts_qmlplugin
-# }
-#}
+ android {
+ android_qmldir.files = $$copy_qmldir_examples.target
+ android_qmldir.path = /assets/imports/$$make_qmldir_target
+ android_qmlplugin.files = $$copy_lib.target
+ android_qmlplugin.path = $$target.path
+ INSTALLS += android_qmldir android_qmlplugin
+ }
+}
diff --git a/examples/examples.pro b/examples/examples.pro
index dd772368..4db7ed2f 100644
--- a/examples/examples.pro
+++ b/examples/examples.pro
@@ -3,6 +3,10 @@ SUBDIRS += barchart \
rainfall \
widget \
mapdata \
- qmlbarchart
+ qmlbarchart \
+ #qmlmaps \
+ qmlscatter \
+ surfacechart \
+ scatterchart
-qtHaveModule(multimedia): SUBDIRS += spectrum
+qtHaveModule(multimedia):!android: SUBDIRS += spectrum
diff --git a/examples/mapdata/doc/src/mapdata.qdoc b/examples/mapdata/doc/src/mapdata.qdoc
index be424509..3014cadb 100644
--- a/examples/mapdata/doc/src/mapdata.qdoc
+++ b/examples/mapdata/doc/src/mapdata.qdoc
@@ -1,27 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
-** This file is part of the documentation of the QtDataVis3D module.
+** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:FDL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: http://www.gnu.org/copyleft/fdl.html.
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
diff --git a/examples/mapdata/main.cpp b/examples/mapdata/main.cpp
index 976b2165..d176bd55 100644
--- a/examples/mapdata/main.cpp
+++ b/examples/mapdata/main.cpp
@@ -1,40 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
-** This file is part of the documentation of QtDataVis3D module.
+** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
-** of its contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
@@ -199,6 +177,8 @@ int main(int argc, char **argv)
QObject::connect(shadowQuality, SIGNAL(currentIndexChanged(int)), modifier,
SLOT(changeShadowQuality(int)));
+ QObject::connect(modifier, &MapsModifier::shadowQuality, shadowQuality,
+ &QComboBox::setCurrentIndex);
QObject::connect(fontList, &QFontComboBox::currentFontChanged, modifier,
&MapsModifier::changeFont);
diff --git a/examples/mapdata/mapdata.cpp b/examples/mapdata/mapdata.cpp
index 8f4aee7c..6f0157da 100644
--- a/examples/mapdata/mapdata.cpp
+++ b/examples/mapdata/mapdata.cpp
@@ -1,44 +1,23 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
-** This file is part of the documentation of QtDataVis3D module.
+** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
-** of its contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
#include "mapdata.h"
+#include <QtDataVis3D/qmapdataproxy.h>
#include <QImage>
#include <QFile>
@@ -64,6 +43,8 @@ MapsModifier::MapsModifier(Q3DMaps *maps)
m_chart->setBarSpecs(m_barSpecs, Q3DMaps::AdjustAll);
m_chart->setMeshFileName(QStringLiteral(":/meshes/weirdthing"));
#endif
+ QMapDataProxy *proxy = new QMapDataProxy;
+ m_chart->setDataProxy(proxy);
}
MapsModifier::~MapsModifier()
@@ -78,132 +59,156 @@ void MapsModifier::start()
void MapsModifier::addData()
{
- QDataItem *item;
- item = new QDataItem();
+ QMapDataArray *dataArray = new QMapDataArray;
+ QMapDataItem *item;
+ item = new QMapDataItem();
item->setValue(191050);
- item->setLabel("Oulu", true);
- item->setPosition(QPoint(963, 1604));
- m_chart->addDataItem(item);
+ item->setLabel("Oulu");
+ item->setMapPosition(QPointF(963, 1604));
+ dataArray->append(*item);
+ delete item;
- item = new QDataItem();
+ item = new QMapDataItem();
item->setValue(22274);
- item->setLabel("Kemi", true);
- item->setPosition(QPoint(857, 1383));
- m_chart->addDataItem(item);
+ item->setLabel("Kemi");
+ item->setMapPosition(QPointF(857, 1383));
+ dataArray->append(*item);
+ delete item;
- item = new QDataItem();
+ item = new QMapDataItem();
item->setValue(60887);
- item->setLabel("Rovaniemi", true);
- item->setPosition(QPoint(1061, 1119));
- m_chart->addDataItem(item);
+ item->setLabel("Rovaniemi");
+ item->setMapPosition(QPointF(1061, 1119));
+ dataArray->append(*item);
+ delete item;
- item = new QDataItem();
+ item = new QMapDataItem();
item->setValue(16176);
- item->setLabel("Kuusamo", true);
- item->setPosition(QPoint(1459, 1284));
- m_chart->addDataItem(item);
+ item->setLabel("Kuusamo");
+ item->setMapPosition(QPointF(1459, 1284));
+ dataArray->append(*item);
+ delete item;
- item = new QDataItem();
+ item = new QMapDataItem();
item->setValue(3998);
- item->setLabel("Ivalo", true);
- item->setPosition(QPoint(1239, 474));
- m_chart->addDataItem(item);
+ item->setLabel("Ivalo");
+ item->setMapPosition(QPointF(1239, 474));
+ dataArray->append(*item);
+ delete item;
- item = new QDataItem();
+ item = new QMapDataItem();
item->setValue(37978);
- item->setLabel("Kajaani", true);
- item->setPosition(QPoint(1285, 1859));
- m_chart->addDataItem(item);
+ item->setLabel("Kajaani");
+ item->setMapPosition(QPointF(1285, 1859));
+ dataArray->append(*item);
+ delete item;
- item = new QDataItem();
+ item = new QMapDataItem();
item->setValue(46809);
- item->setLabel("Kokkola", true);
- item->setPosition(QPoint(580, 1973));
- m_chart->addDataItem(item);
+ item->setLabel("Kokkola");
+ item->setMapPosition(QPointF(580, 1973));
+ dataArray->append(*item);
+ delete item;
- item = new QDataItem();
+ item = new QMapDataItem();
item->setValue(105236);
- item->setLabel("Kuopio", true);
- item->setPosition(QPoint(1292, 2283));
- m_chart->addDataItem(item);
+ item->setLabel("Kuopio");
+ item->setMapPosition(QPointF(1292, 2283));
+ dataArray->append(*item);
+ delete item;
- item = new QDataItem();
+ item = new QMapDataItem();
item->setValue(133557);
- item->setLabel("Jyväskylä", true);
- item->setPosition(QPoint(991, 2496));
- m_chart->addDataItem(item);
+ item->setLabel("Jyväskylä");
+ item->setMapPosition(QPointF(991, 2496));
+ dataArray->append(*item);
+ delete item;
- item = new QDataItem();
+ item = new QMapDataItem();
item->setValue(65771);
- item->setLabel("Vaasa", true);
- item->setPosition(QPoint(441, 2184));
- m_chart->addDataItem(item);
+ item->setLabel("Vaasa");
+ item->setMapPosition(QPointF(441, 2184));
+ dataArray->append(*item);
+ delete item;
- item = new QDataItem();
+ item = new QMapDataItem();
item->setValue(217603);
- item->setLabel("Tampere", true);
- item->setPosition(QPoint(686, 2656));
- m_chart->addDataItem(item);
+ item->setLabel("Tampere");
+ item->setMapPosition(QPointF(686, 2656));
+ dataArray->append(*item);
+ delete item;
- item = new QDataItem();
+ item = new QMapDataItem();
item->setValue(180350);
- item->setLabel("Turku", true);
- item->setPosition(QPoint(430, 3046));
- m_chart->addDataItem(item);
+ item->setLabel("Turku");
+ item->setMapPosition(QPointF(430, 3046));
+ dataArray->append(*item);
+ delete item;
- item = new QDataItem();
+ item = new QMapDataItem();
item->setValue(72400);
- item->setLabel("Lappeenranta", true);
- item->setPosition(QPoint(1365, 2852));
- m_chart->addDataItem(item);
+ item->setLabel("Lappeenranta");
+ item->setMapPosition(QPoint(1365, 2852));
+ dataArray->append(*item);
+ delete item;
- item = new QDataItem();
+ item = new QMapDataItem();
item->setValue(14754);
- item->setLabel("Tammisaari", true);
- item->setPosition(QPoint(605, 3215));
- m_chart->addDataItem(item);
+ item->setLabel("Tammisaari");
+ item->setMapPosition(QPointF(605, 3215));
+ dataArray->append(*item);
+ delete item;
- item = new QDataItem();
+ item = new QMapDataItem();
item->setValue(1879);
- item->setLabel("Enontekiö", true);
- item->setPosition(QPoint(752, 556));
- m_chart->addDataItem(item);
+ item->setLabel("Enontekiö");
+ item->setMapPosition(QPointF(752, 556));
+ dataArray->append(*item);
+ delete item;
- item = new QDataItem();
+ item = new QMapDataItem();
item->setValue(36624);
- item->setLabel("Savonlinna", true);
- item->setPosition(QPoint(1445, 2586));
- m_chart->addDataItem(item);
+ item->setLabel("Savonlinna");
+ item->setMapPosition(QPointF(1445, 2586));
+ dataArray->append(*item);
+ delete item;
- item = new QDataItem();
+ item = new QMapDataItem();
item->setValue(605022);
- item->setLabel("Helsinki", true);
- item->setPosition(QPoint(822, 3130));
- m_chart->addDataItem(item);
+ item->setLabel("Helsinki");
+ item->setMapPosition(QPointF(822, 3130));
+ dataArray->append(*item);
+ delete item;
- item = new QDataItem();
+ item = new QMapDataItem();
item->setValue(54887);
- item->setLabel("Kotka", true);
- item->setPosition(QPoint(1162, 3051));
- m_chart->addDataItem(item);
+ item->setLabel("Kotka");
+ item->setMapPosition(QPointF(1162, 3051));
+ dataArray->append(*item);
+ delete item;
- item = new QDataItem();
+ item = new QMapDataItem();
item->setValue(11372);
- item->setLabel("Maarianhamina", true);
- item->setPosition(QPoint(56, 3101));
- m_chart->addDataItem(item);
+ item->setLabel("Maarianhamina");
+ item->setMapPosition(QPointF(56, 3101));
+ dataArray->append(*item);
+ delete item;
- item = new QDataItem();
+ item = new QMapDataItem();
item->setValue(9266);
- item->setLabel("Hanko", true);
- item->setPosition(QPoint(527, 3228));
- m_chart->addDataItem(item);
+ item->setLabel("Hanko");
+ item->setMapPosition(QPointF(527, 3228));
+ dataArray->append(*item);
+ delete item;
- item = new QDataItem();
+ item = new QMapDataItem();
item->setValue(1287);
- item->setLabel("Utsjoki", true);
- item->setPosition(QPoint(1180, 72));
- m_chart->addDataItem(item);
+ item->setLabel("Utsjoki");
+ item->setMapPosition(QPointF(1180, 72));
+ dataArray->append(*item);
+ delete item;
+
+ static_cast<QMapDataProxy *>(m_chart->dataProxy())->resetArray(dataArray);
}
void MapsModifier::changeStyle()
@@ -211,40 +216,40 @@ void MapsModifier::changeStyle()
static int model = 0;
switch (model) {
case 0:
- m_chart->setBarType(Cylinders, false);
+ m_chart->setBarType(QDataVis::Cylinders, false);
break;
case 1:
- m_chart->setBarType(Cylinders, true);
+ m_chart->setBarType(QDataVis::Cylinders, true);
break;
case 2:
- m_chart->setBarType(Cones, false);
+ m_chart->setBarType(QDataVis::Cones, false);
break;
case 3:
- m_chart->setBarType(Cones, true);
+ m_chart->setBarType(QDataVis::Cones, true);
break;
case 4:
- m_chart->setBarType(Bars, false);
+ m_chart->setBarType(QDataVis::Bars, false);
break;
case 5:
- m_chart->setBarType(Bars, true);
+ m_chart->setBarType(QDataVis::Bars, true);
break;
case 6:
- m_chart->setBarType(Pyramids, false);
+ m_chart->setBarType(QDataVis::Pyramids, false);
break;
case 7:
- m_chart->setBarType(Pyramids, true);
+ m_chart->setBarType(QDataVis::Pyramids, true);
break;
case 8:
- m_chart->setBarType(BevelBars, false);
+ m_chart->setBarType(QDataVis::BevelBars, false);
break;
case 9:
- m_chart->setBarType(BevelBars, true);
+ m_chart->setBarType(QDataVis::BevelBars, true);
break;
case 10:
- m_chart->setBarType(Spheres, false);
+ m_chart->setBarType(QDataVis::Spheres, false);
break;
case 11:
- m_chart->setBarType(Spheres, true);
+ m_chart->setBarType(QDataVis::Spheres, true);
break;
}
model++;
@@ -254,32 +259,32 @@ void MapsModifier::changeStyle()
void MapsModifier::changePresetCamera()
{
- static int preset = PresetFrontLow;
+ static int preset = QDataVis::PresetFrontLow;
- m_chart->setCameraPreset((CameraPreset)preset);
+ m_chart->setCameraPreset((QDataVis::CameraPreset)preset);
- if (++preset > PresetDirectlyAboveCCW45)
- preset = PresetFrontLow;
+ if (++preset > QDataVis::PresetDirectlyAboveCCW45)
+ preset = QDataVis::PresetFrontLow;
}
void MapsModifier::changeTheme()
{
- static int theme = ThemeSystem;
+ static int theme = QDataVis::ThemeSystem;
- m_chart->setTheme((ColorTheme)theme);
+ m_chart->setTheme((QDataVis::ColorTheme)theme);
- if (++theme > ThemeLight)
- theme = ThemeSystem;
+ if (++theme > QDataVis::ThemeLight)
+ theme = QDataVis::ThemeSystem;
}
void MapsModifier::changeTransparency()
{
- static int transparency = TransparencyNone;
+ static int transparency = QDataVis::TransparencyNone;
- m_chart->setLabelTransparency((LabelTransparency)transparency);
+ m_chart->setLabelTransparency((QDataVis::LabelTransparency)transparency);
- if (++transparency > TransparencyNoBackground)
- transparency = TransparencyFromTheme;
+ if (++transparency > QDataVis::TransparencyNoBackground)
+ transparency = QDataVis::TransparencyFromTheme;
}
void MapsModifier::changeValueDimension(int dimension)
@@ -303,19 +308,34 @@ void MapsModifier::changeFontSize(int fontsize)
void MapsModifier::changeShadowQuality(int quality)
{
- ShadowQuality sq = ShadowNone;
+ QDataVis::ShadowQuality sq = QDataVis::ShadowNone;
switch (quality) {
case 1:
- sq = ShadowLow;
+ sq = QDataVis::ShadowLow;
break;
case 2:
- sq = ShadowMedium;
+ sq = QDataVis::ShadowMedium;
break;
case 3:
- sq = ShadowHigh;
+ sq = QDataVis::ShadowHigh;
break;
}
- m_chart->setShadowQuality(sq);
+ QDataVis::ShadowQuality realquality = m_chart->setShadowQuality(sq);
+ // Check if it setting quality was successful
+ if (realquality != sq) {
+ switch (realquality) {
+ case QDataVis::ShadowLow:
+ quality = 1;
+ break;
+ case QDataVis::ShadowMedium:
+ quality = 2;
+ break;
+ case QDataVis::ShadowHigh:
+ quality = 3;
+ break;
+ }
+ emit shadowQuality(quality);
+ }
}
//void MapsModifier::setGridEnabled(int enabled)
diff --git a/examples/mapdata/mapdata.h b/examples/mapdata/mapdata.h
index 3b3c7219..8aed69fe 100644
--- a/examples/mapdata/mapdata.h
+++ b/examples/mapdata/mapdata.h
@@ -1,48 +1,25 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
-** This file is part of the documentation of QtDataVis3D module.
+** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
-** of its contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
#ifndef CHARTMODIFIER_H
#define CHARTMODIFIER_H
-#include "q3dmaps.h"
-#include "qdataset.h"
+#include <QtDataVis3D/q3dmaps.h>
#include <QFont>
#include <QDebug>
@@ -75,6 +52,9 @@ public slots:
void changeValueDimension(int dimension);
void changeShadowQuality(int quality);
+signals:
+ void shadowQuality(int quality);
+
private:
Q3DMaps *m_chart;
QRect m_imageRect;
diff --git a/examples/mapdata/mapdata.pro b/examples/mapdata/mapdata.pro
index 7ed5984e..091fdc7c 100644
--- a/examples/mapdata/mapdata.pro
+++ b/examples/mapdata/mapdata.pro
@@ -5,7 +5,7 @@
SOURCES += main.cpp mapdata.cpp
HEADERS += mapdata.h
-QT += datavis3d widgets
+QT += widgets
INSTALLS += target
diff --git a/examples/qmlbarchart/doc/src/qmlbarchart.qdoc b/examples/qmlbarchart/doc/src/qmlbarchart.qdoc
index 42bb05aa..becc5d8b 100644
--- a/examples/qmlbarchart/doc/src/qmlbarchart.qdoc
+++ b/examples/qmlbarchart/doc/src/qmlbarchart.qdoc
@@ -1,27 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
-** This file is part of the documentation of the QtDataVis3D module.
+** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:FDL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: http://www.gnu.org/copyleft/fdl.html.
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
diff --git a/examples/qmlbarchart/main.cpp b/examples/qmlbarchart/main.cpp
index d813443e..b58e66f8 100644
--- a/examples/qmlbarchart/main.cpp
+++ b/examples/qmlbarchart/main.cpp
@@ -6,26 +6,27 @@
**
** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE$
-** Licensees holding valid Qt Commercial licenses may use this file in
-** accordance with the Qt Commercial License Agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.
**
** If you have questions regarding the use of this file, please use
** contact form at http://qt.digia.com
-** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtGui/QGuiApplication>
#include "qtquick2applicationviewer.h"
+#ifdef Q_OS_ANDROID
+#include <QDir>
+#include <QQmlEngine>
+#endif
#include <QDebug>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
- qDebug() << "Hello world.";
QtQuick2ApplicationViewer viewer;
#ifdef Q_OS_ANDROID
@@ -36,7 +37,7 @@ int main(int argc, char *argv[])
viewer.addImportPath(QString::fromLatin1("%1/%2").arg(QCoreApplication::applicationDirPath(),
QString::fromLatin1("qml")));
#endif
- viewer.setMainQmlFile(QStringLiteral("qml/qmlbarchart/main.qml"));
+ viewer.setSource(QUrl("qrc:/qml/main.qml"));
viewer.setResizeMode(QQuickView::SizeRootObjectToView);
viewer.show();
diff --git a/examples/qmlbarchart/qml/qmlbarchart/main.qml b/examples/qmlbarchart/qml/qmlbarchart/main.qml
index 990c78e6..f10f98b9 100644
--- a/examples/qmlbarchart/qml/qmlbarchart/main.qml
+++ b/examples/qmlbarchart/qml/qmlbarchart/main.qml
@@ -6,116 +6,200 @@
**
** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE$
-** Licensees holding valid Qt Commercial licenses may use this file in
-** accordance with the Qt Commercial License Agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.
**
** If you have questions regarding the use of this file, please use
** contact form at http://qt.digia.com
-** $QT_END_LICENSE$
**
****************************************************************************/
-import QtQuick 2.0
+import QtQuick 2.1
import QtQuick.Window 2.1
+import QtQuick.Controls 1.0
import com.digia.QtDataVis3D 1.0
Item {
id: mainview
- //title: "My MainWindow"
- width: 640
- height: 480
+ width: 800
+ height: 600
visible: true
- Bars3D {
- id: testchart
- width: mainview.width
- height: mainview.height
+ Item {
+ id: dataView
+ width: parent.width - tableView.width
+ height: parent.height
+ anchors.right: parent.right;
- DataItem {
- id: testitem
- label: "Test"
- value: 10
+ BarDataMapping {
+ id: valueMapping
+ rowRole: "year"
+ columnRole: "month"
+ valueRole: "expenses"
+ rowCategories: ["2000", "2001", "2002", "2003", "2004"]
+ columnCategories: ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
}
- DataItem {
- id: testitem2
- label: "Test2"
- value: -10
- }
- DataItem {
- id: testitem3
- label: "Test3"
- value: 5
+
+ ListModel {
+ id: dataModel
+ ListElement{ year: "2000"; month: "Jan"; expenses: "3"; income: "8" }
+ ListElement{ year: "2000"; month: "Feb"; expenses: "8"; income: "14" }
+ ListElement{ year: "2000"; month: "Mar"; expenses: "10"; income: "20" }
+ ListElement{ year: "2000"; month: "Apr"; expenses: "12"; income: "24" }
+ ListElement{ year: "2000"; month: "May"; expenses: "10"; income: "19" }
+ ListElement{ year: "2000"; month: "Jun"; expenses: "5"; income: "8" }
+ ListElement{ year: "2000"; month: "Jul"; expenses: "1"; income: "4" }
+ ListElement{ year: "2000"; month: "Aug"; expenses: "7"; income: "12" }
+ ListElement{ year: "2000"; month: "Sep"; expenses: "4"; income: "16" }
+ ListElement{ year: "2000"; month: "Oct"; expenses: "22"; income: "33" }
+ ListElement{ year: "2000"; month: "Nov"; expenses: "16"; income: "25" }
+ ListElement{ year: "2000"; month: "Dec"; expenses: "2"; income: "7" }
+
+ ListElement{ year: "2001"; month: "Jan"; expenses: "4"; income: "5" }
+ ListElement{ year: "2001"; month: "Feb"; expenses: "4"; income: "7" }
+ ListElement{ year: "2001"; month: "Mar"; expenses: "11"; income: "14" }
+ ListElement{ year: "2001"; month: "Apr"; expenses: "16"; income: "22" }
+ ListElement{ year: "2001"; month: "May"; expenses: "3"; income: "5" }
+ ListElement{ year: "2001"; month: "Jun"; expenses: "4"; income: "8" }
+ ListElement{ year: "2001"; month: "Jul"; expenses: "7"; income: "9" }
+ ListElement{ year: "2001"; month: "Aug"; expenses: "9"; income: "13" }
+ ListElement{ year: "2001"; month: "Sep"; expenses: "1"; income: "6" }
+ ListElement{ year: "2001"; month: "Oct"; expenses: "14"; income: "25" }
+ ListElement{ year: "2001"; month: "Nov"; expenses: "19"; income: "29" }
+ ListElement{ year: "2001"; month: "Dec"; expenses: "5"; income: "7" }
+
+ ListElement{ year: "2002"; month: "Jan"; expenses: "14"; income: "22" }
+ ListElement{ year: "2002"; month: "Feb"; expenses: "5"; income: "7" }
+ ListElement{ year: "2002"; month: "Mar"; expenses: "1"; income: "9" }
+ ListElement{ year: "2002"; month: "Apr"; expenses: "1"; income: "12" }
+ ListElement{ year: "2002"; month: "May"; expenses: "5"; income: "9" }
+ ListElement{ year: "2002"; month: "Jun"; expenses: "5"; income: "8" }
+ ListElement{ year: "2002"; month: "Jul"; expenses: "3"; income: "7" }
+ ListElement{ year: "2002"; month: "Aug"; expenses: "1"; income: "5" }
+ ListElement{ year: "2002"; month: "Sep"; expenses: "2"; income: "4" }
+ ListElement{ year: "2002"; month: "Oct"; expenses: "10"; income: "13" }
+ ListElement{ year: "2002"; month: "Nov"; expenses: "12"; income: "17" }
+ ListElement{ year: "2002"; month: "Dec"; expenses: "6"; income: "9" }
+
+ ListElement{ year: "2003"; month: "Jan"; expenses: "2"; income: "6" }
+ ListElement{ year: "2003"; month: "Feb"; expenses: "4"; income: "8" }
+ ListElement{ year: "2003"; month: "Mar"; expenses: "7"; income: "12" }
+ ListElement{ year: "2003"; month: "Apr"; expenses: "9"; income: "15" }
+ // rest of 2003 missing on purpose, as well as whole of 2004
}
- DataItem {
- id: testitem4
- label: "Test4"
- value: -7
+ CategoryAxis {
+ id: rowAxis
+ categoryLabels: ["2000", "2001", "2002", "2003", "2004"]
}
- DataItem {
- id: testitem5
- label: "Test5"
- value: 8
+ CategoryAxis {
+ id: columnAxis
+ categoryLabels: ["January", "February", "March", "April", "May", "June",
+ "July", "August", "September", "October", "November", "December"]
}
- DataItem {
- id: testitem6
- label: "Test6"
- value: 1
+ ValueAxis {
+ id: valueAxis
+ min: 0
+ max: 35
+ labelFormat: "M\u20AC"
}
+ Bars3D {
+ id: testchart
+ width: dataView.width
+ height: dataView.height
+ gridVisible: true
+ shadowQuality: Bars3D.ShadowNone
+ selectionMode: Bars3D.ModeItem
+ labelTransparency: Bars3D.TransparencyNone
+ rows: 5
+ columns: 12
+ mapping: valueMapping
+ barThickness: Qt.size(0.5, 1.0)
+ barSpacing: Qt.size(0.5, 0.5)
+ barSpacingRelative: false
+ barType: Bars3D.BevelBars
+ axisX: rowAxis
+ axisY: valueAxis
+ axisZ: columnAxis
+ }
+ }
- DataRow {
- id: testrow1
- function addData() {
- testrow1.addItem(testitem);
- testrow1.addItem(testitem2);
- testrow1.addItem(testitem3);
- testrow1.addItem(testitem4);
- testrow1.addItem(testitem5);
- testrow1.addItem(testitem6);
- }
+ Component.onCompleted: {
+ testchart.data = dataModel
+ }
+
+ TableView {
+ id: tableView
+ x: 0
+ y: 0
+ width: 270
+ height: 500
+ TableViewColumn{ role: "year" ; title: "Year" ; width: 40 }
+ TableViewColumn{ role: "month" ; title: "Month" ; width: 80 }
+ TableViewColumn{ role: "expenses" ; title: "Expenses" ; width: 70 }
+ TableViewColumn{ role: "income" ; title: "Income" ; width: 60 }
+ model: dataModel
+ }
+
+ Rectangle {
+ id: shadowToggle
+ color: "#FFFFFF"
+ x: 0
+ y: tableView.height
+ width: tableView.width
+ height: 50
+
+ TextArea {
+ id: shadowButtonText
+ text: "Toggle Shadows"
+ anchors.fill: parent
+ textColor: "#000000"
}
- //visible: true
- //x: mainview.x + mainview.width
- //y: mainview.y
-
- grid: false
- shadowQuality: Bars3D.ShadowNone
- selectionMode: Bars3D.ModeNone
- labelTransparency: Bars3D.TransparencyNone
-
- function setUpBars3D() {
- /*console.log(parent)
- console.log(container.x)
- console.log(container.y)
- console.log(Window.x)
- console.log(Window.y)
- console.log(Screen.desktopAvailableHeight)
- console.log(Screen.desktopAvailableWidth)
- console.log(mainview.x)
- console.log(mainview.y)
- console.log(x)
- console.log(y)*/
- testchart.setupSampleSpace(6, 1);
- testchart.addDataRow(testrow1);
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ if (testchart.shadowQuality == Bars3D.ShadowNone) {
+ testchart.shadowQuality = Bars3D.ShadowLow;
+ shadowButtonText.textColor = "#FFFFFF";
+ shadowToggle.color = "#000000";
+ } else {
+ testchart.shadowQuality = Bars3D.ShadowNone;
+ shadowButtonText.textColor = "#000000";
+ shadowToggle.color = "#FFFFFF";
+ }
+ }
}
}
+ Rectangle {
+ id: mappingToggle
+ color: "#FFFFFF"
+ x: 0
+ y: shadowToggle.height + shadowToggle.y
+ width: shadowToggle.width
+ height: 50
- MouseArea {
- anchors.fill: parent
- onClicked: {
- Qt.quit();
+ TextArea {
+ id: mappingButtonText
+ text: "Show Income"
+ anchors.fill: parent
+ textColor: "#000000"
}
- }
- Component.onCompleted: {
- // This allows us to flip the texture to be displayed correctly in scene graph
- // TODO: Find a way to do it in code..
- //rotation.angle = 180
- testrow1.addData();
- testchart.setUpBars3D();
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ if (valueMapping.valueRole == "expenses") {
+ valueMapping.valueRole = "income"
+ mappingButtonText.text = "Show Expenses"
+ } else {
+ valueMapping.valueRole = "expenses"
+ mappingButtonText.text = "Show Income"
+ }
+ }
+ }
}
}
diff --git a/examples/qmlbarchart/qmlbarchart.pro b/examples/qmlbarchart/qmlbarchart.pro
index 2c729f6b..ef609ef6 100644
--- a/examples/qmlbarchart/qmlbarchart.pro
+++ b/examples/qmlbarchart/qmlbarchart.pro
@@ -24,3 +24,6 @@ SOURCES += main.cpp
# Please do not modify the following two lines. Required for deployment.
include(qtquick2applicationviewer/qtquick2applicationviewer.pri)
qtcAddDeployment()
+
+RESOURCES += \
+ qmlbarchart.qrc
diff --git a/examples/qmlbarchart/qmlbarchart.qrc b/examples/qmlbarchart/qmlbarchart.qrc
new file mode 100644
index 00000000..b96401d5
--- /dev/null
+++ b/examples/qmlbarchart/qmlbarchart.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/qml">
+ <file alias="main.qml">qml/qmlbarchart/main.qml</file>
+ </qresource>
+</RCC>
diff --git a/examples/qmlmaps/doc/src/qmlmaps.qdoc b/examples/qmlmaps/doc/src/qmlmaps.qdoc
new file mode 100644
index 00000000..f27dc126
--- /dev/null
+++ b/examples/qmlmaps/doc/src/qmlmaps.qdoc
@@ -0,0 +1,29 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+/*!
+ \example qmlmaps
+ \title Qt Quick 2 Maps Example
+
+ The Qt Quick 2 maps example shows how to make a simple maps visualization using Q3DMaps using Qt
+ Quick 2.
+
+ \image qmlmaps-example.png
+
+ TODO
+*/
diff --git a/examples/qmlmaps/floorplan.jpg b/examples/qmlmaps/floorplan.jpg
new file mode 100644
index 00000000..578d8252
--- /dev/null
+++ b/examples/qmlmaps/floorplan.jpg
Binary files differ
diff --git a/examples/qmlmaps/main.cpp b/examples/qmlmaps/main.cpp
new file mode 100644
index 00000000..b58e66f8
--- /dev/null
+++ b/examples/qmlmaps/main.cpp
@@ -0,0 +1,45 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include <QtGui/QGuiApplication>
+#include "qtquick2applicationviewer.h"
+#ifdef Q_OS_ANDROID
+#include <QDir>
+#include <QQmlEngine>
+#endif
+#include <QDebug>
+
+int main(int argc, char *argv[])
+{
+ QGuiApplication app(argc, argv);
+
+ QtQuick2ApplicationViewer viewer;
+#ifdef Q_OS_ANDROID
+ viewer.addImportPath(QString::fromLatin1("assets:/qml"));
+ viewer.engine()->addPluginPath(QString::fromLatin1("%1/../%2").arg(QDir::homePath(),
+ QString::fromLatin1("lib")));
+#else
+ viewer.addImportPath(QString::fromLatin1("%1/%2").arg(QCoreApplication::applicationDirPath(),
+ QString::fromLatin1("qml")));
+#endif
+ viewer.setSource(QUrl("qrc:/qml/main.qml"));
+ viewer.setResizeMode(QQuickView::SizeRootObjectToView);
+ viewer.show();
+
+ return app.exec();
+}
diff --git a/examples/qmlmaps/qml/qmlmaps/main.qml b/examples/qmlmaps/qml/qmlmaps/main.qml
new file mode 100644
index 00000000..9a8fa93b
--- /dev/null
+++ b/examples/qmlmaps/qml/qmlmaps/main.qml
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import QtQuick.Controls 1.0
+import com.digia.QtDataVis3D 1.0
+
+Item {
+ id: mainview
+ width: 800
+ height: 500
+ visible: true
+ //title: "Noise levels from construction site"
+
+ Item {
+ id: dataView
+ width: parent.width
+ height: parent.height - shadowToggle.height
+ anchors.bottom: parent.bottom
+
+ Image {
+ id: testimage
+ source: "qrc:/images/floorplan.jpg"
+ visible: false
+ }
+
+ MapDataMapping {
+ id: mapMapping
+ labelRole: "label"
+ valueRole: "value"
+ xPosRole: "xPos"
+ yPosRole: "yPos"
+ }
+
+ ListModel {
+ id: dataModel
+ ListElement{ label: "dB"; value: 76; xPos: 95.0; yPos: 490.0 }
+ ListElement{ label: "dB"; value: 88; xPos: 185.0; yPos: 105.0 }
+ ListElement{ label: "dB"; value: 85; xPos: 700.0; yPos: 465.0 }
+ ListElement{ label: "dB"; value: 92; xPos: 505.0; yPos: 225.0 }
+ }
+
+ Maps3D {
+ id: testmap
+ width: dataView.width
+ height: dataView.height
+ fontSize: 300.0
+ mapping: mapMapping
+
+ Component.onCompleted: {
+ console.log("testmap complete");
+ console.log(testimage);
+ console.log(testimage.sourceSize);
+ setBarSpecs(Qt.vector3d(10.0, 10.0, 10.0));
+ setAreaSpecs(Qt.rect(0, 0, testimage.sourceSize.width, testimage.sourceSize.height),
+ testimage);
+ //setImage(testimage);
+ setImage(":/images/floorplan.jpg");
+ shadowQuality = Maps3D.ShadowNone
+ selectionMode = Maps3D.ModeBar
+ labelTransparency = Maps3D.TransparencyNoBackground//.TransparencyFromTheme
+ data = dataModel
+ }
+ }
+ }
+
+ Component.onCompleted: {
+ console.log("mainview complete");
+ }
+
+ Rectangle {
+ id: shadowToggle
+ color: "#FFFFFF"
+ x: 0
+ y: 0
+ width: parent.width
+ height: 60
+
+ TextArea {
+ id: buttonText
+ text: "Toggle Shadows"
+ anchors.fill: parent
+ textColor: "#000000"
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ if (testmap.shadowQuality === Maps3D.ShadowNone) {
+ testmap.shadowQuality = Maps3D.ShadowLow;
+ buttonText.textColor = "#999999";
+ } else {
+ testmap.shadowQuality = Maps3D.ShadowNone;
+ buttonText.textColor = "#000000";
+ }
+ }
+ }
+ }
+}
diff --git a/examples/qmlmaps/qmlmaps.desktop b/examples/qmlmaps/qmlmaps.desktop
new file mode 100644
index 00000000..25959510
--- /dev/null
+++ b/examples/qmlmaps/qmlmaps.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Version=1.0
+Type=Application
+Terminal=false
+Name=qmlmaps
+Exec=/opt/qmlmaps/bin/qmlmaps
+Icon=qmlmaps64
+X-Window-Icon=
+X-HildonDesk-ShowInToolbar=true
+X-Osso-Type=application/x-executable
diff --git a/examples/qmlmaps/qmlmaps.pro b/examples/qmlmaps/qmlmaps.pro
new file mode 100644
index 00000000..44963d48
--- /dev/null
+++ b/examples/qmlmaps/qmlmaps.pro
@@ -0,0 +1,29 @@
+!include( ../examples.pri ) {
+ error( "Couldn't find the examples.pri file!" )
+}
+
+# Add more folders to ship with the application, here
+folder_01.source = qml/qmlmaps
+folder_01.target = qml
+DEPLOYMENTFOLDERS = folder_01
+
+# Additional import path used to resolve QML modules in Creator's code model
+QML_IMPORT_PATH =
+
+# If your application uses the Qt Mobility libraries, uncomment the following
+# lines and add the respective components to the MOBILITY variable.
+# CONFIG += mobility
+# MOBILITY +=
+
+# The .cpp file which was generated for your project. Feel free to hack it.
+SOURCES += main.cpp
+
+# Installation path
+# target.path =
+
+# Please do not modify the following two lines. Required for deployment.
+include(qtquick2applicationviewer/qtquick2applicationviewer.pri)
+qtcAddDeployment()
+
+RESOURCES += \
+ qmlmaps.qrc
diff --git a/examples/qmlmaps/qmlmaps.qrc b/examples/qmlmaps/qmlmaps.qrc
new file mode 100644
index 00000000..81f1f83c
--- /dev/null
+++ b/examples/qmlmaps/qmlmaps.qrc
@@ -0,0 +1,8 @@
+<RCC>
+ <qresource prefix="/images">
+ <file>floorplan.jpg</file>
+ </qresource>
+ <qresource prefix="/qml">
+ <file alias="main.qml">qml/qmlmaps/main.qml</file>
+ </qresource>
+</RCC>
diff --git a/examples/qmlmaps/qmlmaps64.png b/examples/qmlmaps/qmlmaps64.png
new file mode 100644
index 00000000..707d5c4e
--- /dev/null
+++ b/examples/qmlmaps/qmlmaps64.png
Binary files differ
diff --git a/examples/qmlmaps/qtquick2applicationviewer/qtquick2applicationviewer.cpp b/examples/qmlmaps/qtquick2applicationviewer/qtquick2applicationviewer.cpp
new file mode 100644
index 00000000..10709d7a
--- /dev/null
+++ b/examples/qmlmaps/qtquick2applicationviewer/qtquick2applicationviewer.cpp
@@ -0,0 +1,81 @@
+// checksum 0x4f6f version 0x90005
+/*
+ This file was generated by the Qt Quick 2 Application wizard of Qt Creator.
+ QtQuick2ApplicationViewer is a convenience class containing mobile device specific
+ code such as screen orientation handling. Also QML paths and debugging are
+ handled here.
+ It is recommended not to modify this file, since newer versions of Qt Creator
+ may offer an updated version of it.
+*/
+
+#include "qtquick2applicationviewer.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDir>
+#include <QtQml/QQmlEngine>
+
+class QtQuick2ApplicationViewerPrivate
+{
+ QString mainQmlFile;
+ friend class QtQuick2ApplicationViewer;
+ static QString adjustPath(const QString &path);
+};
+
+QString QtQuick2ApplicationViewerPrivate::adjustPath(const QString &path)
+{
+#if defined(Q_OS_MAC)
+ if (!QDir::isAbsolutePath(path))
+ return QString::fromLatin1("%1/../Resources/%2")
+ .arg(QCoreApplication::applicationDirPath(), path);
+#elif defined(Q_OS_BLACKBERRY)
+ if (!QDir::isAbsolutePath(path))
+ return QString::fromLatin1("app/native/%1").arg(path);
+#elif !defined(Q_OS_ANDROID)
+ QString pathInInstallDir =
+ QString::fromLatin1("%1/../%2").arg(QCoreApplication::applicationDirPath(), path);
+ if (QFileInfo(pathInInstallDir).exists())
+ return pathInInstallDir;
+ pathInInstallDir =
+ QString::fromLatin1("%1/%2").arg(QCoreApplication::applicationDirPath(), path);
+ if (QFileInfo(pathInInstallDir).exists())
+ return pathInInstallDir;
+#endif
+ return path;
+}
+
+QtQuick2ApplicationViewer::QtQuick2ApplicationViewer(QWindow *parent)
+ : QQuickView(parent)
+ , d(new QtQuick2ApplicationViewerPrivate())
+{
+ connect(engine(), SIGNAL(quit()), SLOT(close()));
+ setResizeMode(QQuickView::SizeRootObjectToView);
+}
+
+QtQuick2ApplicationViewer::~QtQuick2ApplicationViewer()
+{
+ delete d;
+}
+
+void QtQuick2ApplicationViewer::setMainQmlFile(const QString &file)
+{
+ d->mainQmlFile = QtQuick2ApplicationViewerPrivate::adjustPath(file);
+#ifdef Q_OS_ANDROID
+ setSource(QUrl(QLatin1String("assets:/")+d->mainQmlFile));
+#else
+ setSource(QUrl::fromLocalFile(d->mainQmlFile));
+#endif
+}
+
+void QtQuick2ApplicationViewer::addImportPath(const QString &path)
+{
+ engine()->addImportPath(QtQuick2ApplicationViewerPrivate::adjustPath(path));
+}
+
+void QtQuick2ApplicationViewer::showExpanded()
+{
+#if defined(Q_WS_SIMULATOR) || defined(Q_OS_QNX)
+ showFullScreen();
+#else
+ show();
+#endif
+}
diff --git a/examples/qmlmaps/qtquick2applicationviewer/qtquick2applicationviewer.h b/examples/qmlmaps/qtquick2applicationviewer/qtquick2applicationviewer.h
new file mode 100644
index 00000000..cf66f140
--- /dev/null
+++ b/examples/qmlmaps/qtquick2applicationviewer/qtquick2applicationviewer.h
@@ -0,0 +1,33 @@
+// checksum 0xfde6 version 0x90005
+/*
+ This file was generated by the Qt Quick 2 Application wizard of Qt Creator.
+ QtQuick2ApplicationViewer is a convenience class containing mobile device specific
+ code such as screen orientation handling. Also QML paths and debugging are
+ handled here.
+ It is recommended not to modify this file, since newer versions of Qt Creator
+ may offer an updated version of it.
+*/
+
+#ifndef QTQUICK2APPLICATIONVIEWER_H
+#define QTQUICK2APPLICATIONVIEWER_H
+
+#include <QtQuick/QQuickView>
+
+class QtQuick2ApplicationViewer : public QQuickView
+{
+ Q_OBJECT
+
+public:
+ explicit QtQuick2ApplicationViewer(QWindow *parent = 0);
+ virtual ~QtQuick2ApplicationViewer();
+
+ void setMainQmlFile(const QString &file);
+ void addImportPath(const QString &path);
+
+ void showExpanded();
+
+private:
+ class QtQuick2ApplicationViewerPrivate *d;
+};
+
+#endif // QTQUICK2APPLICATIONVIEWER_H
diff --git a/examples/qmlmaps/qtquick2applicationviewer/qtquick2applicationviewer.pri b/examples/qmlmaps/qtquick2applicationviewer/qtquick2applicationviewer.pri
new file mode 100644
index 00000000..e5f7990f
--- /dev/null
+++ b/examples/qmlmaps/qtquick2applicationviewer/qtquick2applicationviewer.pri
@@ -0,0 +1,180 @@
+# checksum 0x7b0d version 0x90005
+# This file was generated by the Qt Quick 2 Application wizard of Qt Creator.
+# The code below adds the QtQuick2ApplicationViewer to the project and handles
+# the activation of QML debugging.
+# It is recommended not to modify this file, since newer versions of Qt Creator
+# may offer an updated version of it.
+
+QT += qml quick
+
+SOURCES += $$PWD/qtquick2applicationviewer.cpp
+HEADERS += $$PWD/qtquick2applicationviewer.h
+INCLUDEPATH += $$PWD
+# This file was generated by an application wizard of Qt Creator.
+# The code below handles deployment to Android and Maemo, aswell as copying
+# of the application data to shadow build directories on desktop.
+# It is recommended not to modify this file, since newer versions of Qt Creator
+# may offer an updated version of it.
+
+defineTest(qtcAddDeployment) {
+for(deploymentfolder, DEPLOYMENTFOLDERS) {
+ item = item$${deploymentfolder}
+ greaterThan(QT_MAJOR_VERSION, 4) {
+ itemsources = $${item}.files
+ } else {
+ itemsources = $${item}.sources
+ }
+ $$itemsources = $$eval($${deploymentfolder}.source)
+ itempath = $${item}.path
+ $$itempath= $$eval($${deploymentfolder}.target)
+ export($$itemsources)
+ export($$itempath)
+ DEPLOYMENT += $$item
+}
+
+MAINPROFILEPWD = $$PWD
+
+android-no-sdk {
+ for(deploymentfolder, DEPLOYMENTFOLDERS) {
+ item = item$${deploymentfolder}
+ itemfiles = $${item}.files
+ $$itemfiles = $$eval($${deploymentfolder}.source)
+ itempath = $${item}.path
+ $$itempath = /data/user/qt/$$eval($${deploymentfolder}.target)
+ export($$itemfiles)
+ export($$itempath)
+ INSTALLS += $$item
+ }
+
+ target.path = /data/user/qt
+
+ export(target.path)
+ INSTALLS += target
+} else:android {
+ for(deploymentfolder, DEPLOYMENTFOLDERS) {
+ item = item$${deploymentfolder}
+ itemfiles = $${item}.files
+ $$itemfiles = $$eval($${deploymentfolder}.source)
+ itempath = $${item}.path
+ $$itempath = /assets/$$eval($${deploymentfolder}.target)
+ export($$itemfiles)
+ export($$itempath)
+ INSTALLS += $$item
+ }
+
+ x86 {
+ target.path = /libs/x86
+ } else: armeabi-v7a {
+ target.path = /libs/armeabi-v7a
+ } else {
+ target.path = /libs/armeabi
+ }
+
+ export(target.path)
+ INSTALLS += target
+} else:win32 {
+ copyCommand =
+ for(deploymentfolder, DEPLOYMENTFOLDERS) {
+ source = $$MAINPROFILEPWD/$$eval($${deploymentfolder}.source)
+ source = $$replace(source, /, \\)
+ sourcePathSegments = $$split(source, \\)
+ target = $$OUT_PWD/$$eval($${deploymentfolder}.target)/$$last(sourcePathSegments)
+ target = $$replace(target, /, \\)
+ target ~= s,\\\\\\.?\\\\,\\,
+ !isEqual(source,$$target) {
+ !isEmpty(copyCommand):copyCommand += &&
+ isEqual(QMAKE_DIR_SEP, \\) {
+ copyCommand += $(COPY_DIR) \"$$source\" \"$$target\"
+ } else {
+ source = $$replace(source, \\\\, /)
+ target = $$OUT_PWD/$$eval($${deploymentfolder}.target)
+ target = $$replace(target, \\\\, /)
+ copyCommand += test -d \"$$target\" || mkdir -p \"$$target\" && cp -r \"$$source\" \"$$target\"
+ }
+ }
+ }
+ !isEmpty(copyCommand) {
+ copyCommand = @echo Copying application data... && $$copyCommand
+ copydeploymentfolders.commands = $$copyCommand
+ first.depends = $(first) copydeploymentfolders
+ export(first.depends)
+ export(copydeploymentfolders.commands)
+ QMAKE_EXTRA_TARGETS += first copydeploymentfolders
+ }
+} else:unix {
+ maemo5 {
+ desktopfile.files = $${TARGET}.desktop
+ desktopfile.path = /usr/share/applications/hildon
+ icon.files = $${TARGET}64.png
+ icon.path = /usr/share/icons/hicolor/64x64/apps
+ } else:!isEmpty(MEEGO_VERSION_MAJOR) {
+ desktopfile.files = $${TARGET}_harmattan.desktop
+ desktopfile.path = /usr/share/applications
+ icon.files = $${TARGET}80.png
+ icon.path = /usr/share/icons/hicolor/80x80/apps
+ } else { # Assumed to be a Desktop Unix
+ copyCommand =
+ for(deploymentfolder, DEPLOYMENTFOLDERS) {
+ source = $$MAINPROFILEPWD/$$eval($${deploymentfolder}.source)
+ source = $$replace(source, \\\\, /)
+ macx {
+ target = $$OUT_PWD/$${TARGET}.app/Contents/Resources/$$eval($${deploymentfolder}.target)
+ } else {
+ target = $$OUT_PWD/$$eval($${deploymentfolder}.target)
+ }
+ target = $$replace(target, \\\\, /)
+ sourcePathSegments = $$split(source, /)
+ targetFullPath = $$target/$$last(sourcePathSegments)
+ targetFullPath ~= s,/\\.?/,/,
+ !isEqual(source,$$targetFullPath) {
+ !isEmpty(copyCommand):copyCommand += &&
+ copyCommand += $(MKDIR) \"$$target\"
+ copyCommand += && $(COPY_DIR) \"$$source\" \"$$target\"
+ }
+ }
+ !isEmpty(copyCommand) {
+ copyCommand = @echo Copying application data... && $$copyCommand
+ copydeploymentfolders.commands = $$copyCommand
+ first.depends = $(first) copydeploymentfolders
+ export(first.depends)
+ export(copydeploymentfolders.commands)
+ QMAKE_EXTRA_TARGETS += first copydeploymentfolders
+ }
+ }
+ !isEmpty(target.path) {
+ installPrefix = $${target.path}
+ } else {
+ installPrefix = /opt/$${TARGET}
+ }
+ for(deploymentfolder, DEPLOYMENTFOLDERS) {
+ item = item$${deploymentfolder}
+ itemfiles = $${item}.files
+ $$itemfiles = $$eval($${deploymentfolder}.source)
+ itempath = $${item}.path
+ $$itempath = $${installPrefix}/$$eval($${deploymentfolder}.target)
+ export($$itemfiles)
+ export($$itempath)
+ INSTALLS += $$item
+ }
+
+ !isEmpty(desktopfile.path) {
+ export(icon.files)
+ export(icon.path)
+ export(desktopfile.files)
+ export(desktopfile.path)
+ INSTALLS += icon desktopfile
+ }
+
+ isEmpty(target.path) {
+ target.path = $${installPrefix}/bin
+ export(target.path)
+ }
+ INSTALLS += target
+}
+
+export (ICON)
+export (INSTALLS)
+export (DEPLOYMENT)
+export (LIBS)
+export (QMAKE_EXTRA_TARGETS)
+}
diff --git a/examples/qmlscatter/doc/src/qmlscatter.qdoc b/examples/qmlscatter/doc/src/qmlscatter.qdoc
new file mode 100644
index 00000000..d52798c2
--- /dev/null
+++ b/examples/qmlscatter/doc/src/qmlscatter.qdoc
@@ -0,0 +1,29 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+/*!
+ \example qmlscatter
+ \title Qt Quick 2 Scatter Example
+
+ The Qt Quick 2 scatter example shows how to make a simple scatter chart visualization using
+ Q3DScatter using Qt Quick 2.
+
+ \image qmlscatter-example.png
+
+ TODO
+*/
diff --git a/examples/qmlscatter/main.cpp b/examples/qmlscatter/main.cpp
new file mode 100644
index 00000000..d48bea3d
--- /dev/null
+++ b/examples/qmlscatter/main.cpp
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include <QtGui/QGuiApplication>
+#include "qtquick2applicationviewer.h"
+#ifdef Q_OS_ANDROID
+#include <QDir>
+#include <QQmlEngine>
+#endif
+#include <QDebug>
+
+int main(int argc, char *argv[])
+{
+ QGuiApplication app(argc, argv);
+
+ QtQuick2ApplicationViewer viewer;
+#ifdef Q_OS_ANDROID
+ viewer.addImportPath(QString::fromLatin1("assets:/qml"));
+ viewer.engine()->addPluginPath(QString::fromLatin1("%1/../%2").arg(QDir::homePath(),
+ QString::fromLatin1("lib")));
+#else
+ viewer.addImportPath(QString::fromLatin1("%1/%2").arg(QCoreApplication::applicationDirPath(),
+ QString::fromLatin1("qml")));
+#endif
+ viewer.setSource(QUrl("qrc:/qml/main.qml"));
+ viewer.setResizeMode(QQuickView::SizeRootObjectToView);
+ viewer.setMinimumSize(QSize(640, 480));
+ viewer.show();
+
+ return app.exec();
+}
diff --git a/examples/qmlscatter/qml/qmlscatter/main.qml b/examples/qmlscatter/qml/qmlscatter/main.qml
new file mode 100644
index 00000000..6238529d
--- /dev/null
+++ b/examples/qmlscatter/qml/qmlscatter/main.qml
@@ -0,0 +1,209 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+import QtQuick 2.1
+import QtQuick.Controls 1.0
+import com.digia.QtDataVis3D 1.0
+
+Item {
+ id: mainview
+ width: 800
+ height: 700
+ visible: true
+
+ Item {
+ id: dataView
+ width: parent.width
+ height: parent.height - shadowToggle.height
+ anchors.bottom: parent.bottom
+
+ ScatterDataMapping {
+ id: scatterMapping
+ xPosRole: "xPos"
+ yPosRole: "yPos"
+ zPosRole: "zPos"
+ }
+
+ ListModel {
+ id: dataModel
+ ListElement{ xPos: -10.0; yPos: 4.9; zPos: -5.0 }
+ ListElement{ xPos: 10.0; yPos: 4.9; zPos: -5.0 }
+ ListElement{ xPos: -10.0; yPos: 4.9; zPos: 5.0 }
+ ListElement{ xPos: 10.0; yPos: 4.9; zPos: 5.0 }
+ ListElement{ xPos: -10.0; yPos: -4.9; zPos: -5.0 }
+ ListElement{ xPos: 10.0; yPos: -4.9; zPos: -5.0 }
+ ListElement{ xPos: -10.0; yPos: -4.9; zPos: 5.0 }
+ ListElement{ xPos: 10.0; yPos: -4.9; zPos: 5.0 }
+
+ ListElement{ xPos: -1.0; yPos: 0.3; zPos: -0.5 }
+ ListElement{ xPos: 1.0; yPos: 2.105; zPos: 0.5 }
+ ListElement{ xPos: 0.5; yPos: -0.65; zPos: -0.5 }
+ ListElement{ xPos: -0.5; yPos: 1.225; zPos: 0.5 }
+ ListElement{ xPos: 0.0; yPos: 0.0; zPos: 0.0 }
+ ListElement{ xPos: 0.0; yPos: 2.0; zPos: 0.0 }
+ ListElement{ xPos: 0.0; yPos: -0.5; zPos: 0.0 }
+
+ ListElement{ xPos: 6.0; yPos: 0.0; zPos: 4.0 }
+ ListElement{ xPos: 5.8; yPos: 0.2; zPos: 5.0 }
+ ListElement{ xPos: 5.6; yPos: 0.4; zPos: 4.5 }
+ ListElement{ xPos: 5.4; yPos: 0.6; zPos: 3.8 }
+ ListElement{ xPos: 5.2; yPos: 0.8; zPos: 4.8 }
+ ListElement{ xPos: 5.0; yPos: 0.3; zPos: 4.1 }
+ ListElement{ xPos: 4.9; yPos: -0.3; zPos: 4.9 }
+ ListElement{ xPos: 4.7; yPos: -0.5; zPos: 3.5 }
+ ListElement{ xPos: 4.5; yPos: -0.7; zPos: 3.3 }
+ ListElement{ xPos: 4.3; yPos: -0.4; zPos: 3.7 }
+ }
+
+ Scatter3D {
+ id: testscatter
+ width: dataView.width
+ height: dataView.height
+ fontSize: 30.0
+ mapping: scatterMapping
+ shadowQuality: Scatter3D.ShadowNone
+ selectionMode: Scatter3D.ModeItem
+ labelTransparency: Scatter3D.TransparencyNoBackground
+
+ Component.onCompleted: {
+ console.log("testscatter complete");
+ data = dataModel
+ }
+ }
+ }
+
+ Rectangle {
+ id: shadowToggle
+ width: 120
+ height: 30
+
+ TextArea {
+ id: shadowText
+ text: "Toggle Shadows On"
+ anchors.fill: parent
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ if (testscatter.shadowQuality === Scatter3D.ShadowNone) {
+ testscatter.shadowQuality = Scatter3D.ShadowMedium;
+ shadowText.text = "Toggle Shadows Off";
+ } else {
+ testscatter.shadowQuality = Scatter3D.ShadowNone;
+ shadowText.text = "Toggle Shadows On";
+ }
+ }
+ }
+ }
+ Rectangle {
+ id: smoothToggle
+ width: 140
+ height: 30
+ anchors.left: shadowToggle.right
+
+ TextArea {
+ id: smoothText
+ text: "Toggle Smooth Objects On"
+ anchors.fill: parent
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ if (testscatter.objectSmooth === false) {
+ smoothText.text = "Toggle Smooth Objects Off"
+ testscatter.objectSmooth = true;
+ } else {
+ smoothText.text = "Toggle Smooth Objects On"
+ testscatter.objectSmooth = false;
+ }
+ }
+ }
+ }
+ Rectangle {
+ id: cameraToggle
+ width: 130
+ height: 30
+ anchors.left: smoothToggle.right
+
+ TextArea {
+ text: "Toggle Camera Preset"
+ anchors.fill: parent
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ if (testscatter.cameraPreset === Scatter3D.PresetFront) {
+ testscatter.cameraPreset = Scatter3D.PresetIsometricRightHigh;
+ } else {
+ testscatter.cameraPreset = Scatter3D.PresetFront;
+ }
+ }
+ }
+ }
+ Rectangle {
+ id: themeToggle
+ width: 120
+ height: 30
+ anchors.left: cameraToggle.right
+
+ TextArea {
+ text: "Toggle Theme"
+ anchors.fill: parent
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ if (testscatter.theme === Scatter3D.ThemeBlueCerulean) {
+ testscatter.theme = Scatter3D.ThemeSystem;
+ } else {
+ testscatter.theme = Scatter3D.ThemeBlueCerulean;
+ }
+ }
+ }
+ }
+ Rectangle {
+ id: backgroundToggle
+ width: 130
+ height: 30
+ anchors.left: themeToggle.right
+
+ TextArea {
+ id: backgroundText
+ text: "Toggle Background Off"
+ anchors.fill: parent
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: {
+ if (testscatter.backgroundVisible === true) {
+ testscatter.backgroundVisible = false;
+ backgroundText.text = "Toggle Background On";
+ } else {
+ testscatter.backgroundVisible = true;
+ backgroundText.text = "Toggle Background Off";
+ }
+ }
+ }
+ }
+
+}
diff --git a/examples/qmlscatter/qmlscatter.desktop b/examples/qmlscatter/qmlscatter.desktop
new file mode 100644
index 00000000..0f9e5498
--- /dev/null
+++ b/examples/qmlscatter/qmlscatter.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Version=1.0
+Type=Application
+Terminal=false
+Name=qmlscatter
+Exec=/opt/qmlscatter/bin/qmlscatter
+Icon=qmlscatter64
+X-Window-Icon=
+X-HildonDesk-ShowInToolbar=true
+X-Osso-Type=application/x-executable
diff --git a/examples/qmlscatter/qmlscatter.pro b/examples/qmlscatter/qmlscatter.pro
new file mode 100644
index 00000000..6f89fbae
--- /dev/null
+++ b/examples/qmlscatter/qmlscatter.pro
@@ -0,0 +1,23 @@
+!include( ../examples.pri ) {
+ error( "Couldn't find the examples.pri file!" )
+}
+
+# Add more folders to ship with the application, here
+folder_01.source = qml/qmlscatter
+folder_01.target = qml
+DEPLOYMENTFOLDERS = folder_01
+
+# Additional import path used to resolve QML modules in Creator's code model
+QML_IMPORT_PATH =
+
+# The .cpp file which was generated for your project. Feel free to hack it.
+SOURCES += main.cpp
+
+# Installation path
+# target.path =
+
+# Please do not modify the following two lines. Required for deployment.
+include(qtquick2applicationviewer/qtquick2applicationviewer.pri)
+qtcAddDeployment()
+
+RESOURCES += qmlscatter.qrc
diff --git a/examples/qmlscatter/qmlscatter.qrc b/examples/qmlscatter/qmlscatter.qrc
new file mode 100644
index 00000000..62f5931b
--- /dev/null
+++ b/examples/qmlscatter/qmlscatter.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/qml">
+ <file alias="main.qml">qml/qmlscatter/main.qml</file>
+ </qresource>
+</RCC>
diff --git a/examples/qmlscatter/qmlscatter64.png b/examples/qmlscatter/qmlscatter64.png
new file mode 100644
index 00000000..707d5c4e
--- /dev/null
+++ b/examples/qmlscatter/qmlscatter64.png
Binary files differ
diff --git a/examples/qmlscatter/qtquick2applicationviewer/qtquick2applicationviewer.cpp b/examples/qmlscatter/qtquick2applicationviewer/qtquick2applicationviewer.cpp
new file mode 100644
index 00000000..10709d7a
--- /dev/null
+++ b/examples/qmlscatter/qtquick2applicationviewer/qtquick2applicationviewer.cpp
@@ -0,0 +1,81 @@
+// checksum 0x4f6f version 0x90005
+/*
+ This file was generated by the Qt Quick 2 Application wizard of Qt Creator.
+ QtQuick2ApplicationViewer is a convenience class containing mobile device specific
+ code such as screen orientation handling. Also QML paths and debugging are
+ handled here.
+ It is recommended not to modify this file, since newer versions of Qt Creator
+ may offer an updated version of it.
+*/
+
+#include "qtquick2applicationviewer.h"
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDir>
+#include <QtQml/QQmlEngine>
+
+class QtQuick2ApplicationViewerPrivate
+{
+ QString mainQmlFile;
+ friend class QtQuick2ApplicationViewer;
+ static QString adjustPath(const QString &path);
+};
+
+QString QtQuick2ApplicationViewerPrivate::adjustPath(const QString &path)
+{
+#if defined(Q_OS_MAC)
+ if (!QDir::isAbsolutePath(path))
+ return QString::fromLatin1("%1/../Resources/%2")
+ .arg(QCoreApplication::applicationDirPath(), path);
+#elif defined(Q_OS_BLACKBERRY)
+ if (!QDir::isAbsolutePath(path))
+ return QString::fromLatin1("app/native/%1").arg(path);
+#elif !defined(Q_OS_ANDROID)
+ QString pathInInstallDir =
+ QString::fromLatin1("%1/../%2").arg(QCoreApplication::applicationDirPath(), path);
+ if (QFileInfo(pathInInstallDir).exists())
+ return pathInInstallDir;
+ pathInInstallDir =
+ QString::fromLatin1("%1/%2").arg(QCoreApplication::applicationDirPath(), path);
+ if (QFileInfo(pathInInstallDir).exists())
+ return pathInInstallDir;
+#endif
+ return path;
+}
+
+QtQuick2ApplicationViewer::QtQuick2ApplicationViewer(QWindow *parent)
+ : QQuickView(parent)
+ , d(new QtQuick2ApplicationViewerPrivate())
+{
+ connect(engine(), SIGNAL(quit()), SLOT(close()));
+ setResizeMode(QQuickView::SizeRootObjectToView);
+}
+
+QtQuick2ApplicationViewer::~QtQuick2ApplicationViewer()
+{
+ delete d;
+}
+
+void QtQuick2ApplicationViewer::setMainQmlFile(const QString &file)
+{
+ d->mainQmlFile = QtQuick2ApplicationViewerPrivate::adjustPath(file);
+#ifdef Q_OS_ANDROID
+ setSource(QUrl(QLatin1String("assets:/")+d->mainQmlFile));
+#else
+ setSource(QUrl::fromLocalFile(d->mainQmlFile));
+#endif
+}
+
+void QtQuick2ApplicationViewer::addImportPath(const QString &path)
+{
+ engine()->addImportPath(QtQuick2ApplicationViewerPrivate::adjustPath(path));
+}
+
+void QtQuick2ApplicationViewer::showExpanded()
+{
+#if defined(Q_WS_SIMULATOR) || defined(Q_OS_QNX)
+ showFullScreen();
+#else
+ show();
+#endif
+}
diff --git a/examples/qmlscatter/qtquick2applicationviewer/qtquick2applicationviewer.h b/examples/qmlscatter/qtquick2applicationviewer/qtquick2applicationviewer.h
new file mode 100644
index 00000000..cf66f140
--- /dev/null
+++ b/examples/qmlscatter/qtquick2applicationviewer/qtquick2applicationviewer.h
@@ -0,0 +1,33 @@
+// checksum 0xfde6 version 0x90005
+/*
+ This file was generated by the Qt Quick 2 Application wizard of Qt Creator.
+ QtQuick2ApplicationViewer is a convenience class containing mobile device specific
+ code such as screen orientation handling. Also QML paths and debugging are
+ handled here.
+ It is recommended not to modify this file, since newer versions of Qt Creator
+ may offer an updated version of it.
+*/
+
+#ifndef QTQUICK2APPLICATIONVIEWER_H
+#define QTQUICK2APPLICATIONVIEWER_H
+
+#include <QtQuick/QQuickView>
+
+class QtQuick2ApplicationViewer : public QQuickView
+{
+ Q_OBJECT
+
+public:
+ explicit QtQuick2ApplicationViewer(QWindow *parent = 0);
+ virtual ~QtQuick2ApplicationViewer();
+
+ void setMainQmlFile(const QString &file);
+ void addImportPath(const QString &path);
+
+ void showExpanded();
+
+private:
+ class QtQuick2ApplicationViewerPrivate *d;
+};
+
+#endif // QTQUICK2APPLICATIONVIEWER_H
diff --git a/examples/qmlscatter/qtquick2applicationviewer/qtquick2applicationviewer.pri b/examples/qmlscatter/qtquick2applicationviewer/qtquick2applicationviewer.pri
new file mode 100644
index 00000000..e5f7990f
--- /dev/null
+++ b/examples/qmlscatter/qtquick2applicationviewer/qtquick2applicationviewer.pri
@@ -0,0 +1,180 @@
+# checksum 0x7b0d version 0x90005
+# This file was generated by the Qt Quick 2 Application wizard of Qt Creator.
+# The code below adds the QtQuick2ApplicationViewer to the project and handles
+# the activation of QML debugging.
+# It is recommended not to modify this file, since newer versions of Qt Creator
+# may offer an updated version of it.
+
+QT += qml quick
+
+SOURCES += $$PWD/qtquick2applicationviewer.cpp
+HEADERS += $$PWD/qtquick2applicationviewer.h
+INCLUDEPATH += $$PWD
+# This file was generated by an application wizard of Qt Creator.
+# The code below handles deployment to Android and Maemo, aswell as copying
+# of the application data to shadow build directories on desktop.
+# It is recommended not to modify this file, since newer versions of Qt Creator
+# may offer an updated version of it.
+
+defineTest(qtcAddDeployment) {
+for(deploymentfolder, DEPLOYMENTFOLDERS) {
+ item = item$${deploymentfolder}
+ greaterThan(QT_MAJOR_VERSION, 4) {
+ itemsources = $${item}.files
+ } else {
+ itemsources = $${item}.sources
+ }
+ $$itemsources = $$eval($${deploymentfolder}.source)
+ itempath = $${item}.path
+ $$itempath= $$eval($${deploymentfolder}.target)
+ export($$itemsources)
+ export($$itempath)
+ DEPLOYMENT += $$item
+}
+
+MAINPROFILEPWD = $$PWD
+
+android-no-sdk {
+ for(deploymentfolder, DEPLOYMENTFOLDERS) {
+ item = item$${deploymentfolder}
+ itemfiles = $${item}.files
+ $$itemfiles = $$eval($${deploymentfolder}.source)
+ itempath = $${item}.path
+ $$itempath = /data/user/qt/$$eval($${deploymentfolder}.target)
+ export($$itemfiles)
+ export($$itempath)
+ INSTALLS += $$item
+ }
+
+ target.path = /data/user/qt
+
+ export(target.path)
+ INSTALLS += target
+} else:android {
+ for(deploymentfolder, DEPLOYMENTFOLDERS) {
+ item = item$${deploymentfolder}
+ itemfiles = $${item}.files
+ $$itemfiles = $$eval($${deploymentfolder}.source)
+ itempath = $${item}.path
+ $$itempath = /assets/$$eval($${deploymentfolder}.target)
+ export($$itemfiles)
+ export($$itempath)
+ INSTALLS += $$item
+ }
+
+ x86 {
+ target.path = /libs/x86
+ } else: armeabi-v7a {
+ target.path = /libs/armeabi-v7a
+ } else {
+ target.path = /libs/armeabi
+ }
+
+ export(target.path)
+ INSTALLS += target
+} else:win32 {
+ copyCommand =
+ for(deploymentfolder, DEPLOYMENTFOLDERS) {
+ source = $$MAINPROFILEPWD/$$eval($${deploymentfolder}.source)
+ source = $$replace(source, /, \\)
+ sourcePathSegments = $$split(source, \\)
+ target = $$OUT_PWD/$$eval($${deploymentfolder}.target)/$$last(sourcePathSegments)
+ target = $$replace(target, /, \\)
+ target ~= s,\\\\\\.?\\\\,\\,
+ !isEqual(source,$$target) {
+ !isEmpty(copyCommand):copyCommand += &&
+ isEqual(QMAKE_DIR_SEP, \\) {
+ copyCommand += $(COPY_DIR) \"$$source\" \"$$target\"
+ } else {
+ source = $$replace(source, \\\\, /)
+ target = $$OUT_PWD/$$eval($${deploymentfolder}.target)
+ target = $$replace(target, \\\\, /)
+ copyCommand += test -d \"$$target\" || mkdir -p \"$$target\" && cp -r \"$$source\" \"$$target\"
+ }
+ }
+ }
+ !isEmpty(copyCommand) {
+ copyCommand = @echo Copying application data... && $$copyCommand
+ copydeploymentfolders.commands = $$copyCommand
+ first.depends = $(first) copydeploymentfolders
+ export(first.depends)
+ export(copydeploymentfolders.commands)
+ QMAKE_EXTRA_TARGETS += first copydeploymentfolders
+ }
+} else:unix {
+ maemo5 {
+ desktopfile.files = $${TARGET}.desktop
+ desktopfile.path = /usr/share/applications/hildon
+ icon.files = $${TARGET}64.png
+ icon.path = /usr/share/icons/hicolor/64x64/apps
+ } else:!isEmpty(MEEGO_VERSION_MAJOR) {
+ desktopfile.files = $${TARGET}_harmattan.desktop
+ desktopfile.path = /usr/share/applications
+ icon.files = $${TARGET}80.png
+ icon.path = /usr/share/icons/hicolor/80x80/apps
+ } else { # Assumed to be a Desktop Unix
+ copyCommand =
+ for(deploymentfolder, DEPLOYMENTFOLDERS) {
+ source = $$MAINPROFILEPWD/$$eval($${deploymentfolder}.source)
+ source = $$replace(source, \\\\, /)
+ macx {
+ target = $$OUT_PWD/$${TARGET}.app/Contents/Resources/$$eval($${deploymentfolder}.target)
+ } else {
+ target = $$OUT_PWD/$$eval($${deploymentfolder}.target)
+ }
+ target = $$replace(target, \\\\, /)
+ sourcePathSegments = $$split(source, /)
+ targetFullPath = $$target/$$last(sourcePathSegments)
+ targetFullPath ~= s,/\\.?/,/,
+ !isEqual(source,$$targetFullPath) {
+ !isEmpty(copyCommand):copyCommand += &&
+ copyCommand += $(MKDIR) \"$$target\"
+ copyCommand += && $(COPY_DIR) \"$$source\" \"$$target\"
+ }
+ }
+ !isEmpty(copyCommand) {
+ copyCommand = @echo Copying application data... && $$copyCommand
+ copydeploymentfolders.commands = $$copyCommand
+ first.depends = $(first) copydeploymentfolders
+ export(first.depends)
+ export(copydeploymentfolders.commands)
+ QMAKE_EXTRA_TARGETS += first copydeploymentfolders
+ }
+ }
+ !isEmpty(target.path) {
+ installPrefix = $${target.path}
+ } else {
+ installPrefix = /opt/$${TARGET}
+ }
+ for(deploymentfolder, DEPLOYMENTFOLDERS) {
+ item = item$${deploymentfolder}
+ itemfiles = $${item}.files
+ $$itemfiles = $$eval($${deploymentfolder}.source)
+ itempath = $${item}.path
+ $$itempath = $${installPrefix}/$$eval($${deploymentfolder}.target)
+ export($$itemfiles)
+ export($$itempath)
+ INSTALLS += $$item
+ }
+
+ !isEmpty(desktopfile.path) {
+ export(icon.files)
+ export(icon.path)
+ export(desktopfile.files)
+ export(desktopfile.path)
+ INSTALLS += icon desktopfile
+ }
+
+ isEmpty(target.path) {
+ target.path = $${installPrefix}/bin
+ export(target.path)
+ }
+ INSTALLS += target
+}
+
+export (ICON)
+export (INSTALLS)
+export (DEPLOYMENT)
+export (LIBS)
+export (QMAKE_EXTRA_TARGETS)
+}
diff --git a/examples/rainfall/data/raindata.txt b/examples/rainfall/data/raindata.txt
new file mode 100644
index 00000000..7f581bff
--- /dev/null
+++ b/examples/rainfall/data/raindata.txt
@@ -0,0 +1,1358 @@
+# Fictitious rainfall per month from 1900 to 2012 in three cities
+# Format: year, month, city 1 rainfall, city 2 rainfall, city 3 rainfall
+1900, 1, 58, 60, 40
+1900, 2, 48, 101, 47
+1900, 3, 58, 90, 25
+1900, 4, 59, 81, 33
+1900, 5, 51, 90, 24
+1900, 6, 91, 92, 55
+1900, 7, 92, 124, 34
+1900, 8, 89, 124, 30
+1900, 9, 50, 89, 16
+1900, 10, 69, 100, 55
+1900, 11, 78, 86, 15
+1900, 12, 63, 62, 30
+1901, 1, 34, 56, 50
+1901, 2, 31, 93, 54
+1901, 3, 72, 98, 34
+1901, 4, 88, 104, 18
+1901, 5, 66, 107, 20
+1901, 6, 121, 123, 34
+1901, 7, 100, 133, 46
+1901, 8, 129, 90, 64
+1901, 9, 98, 75, 56
+1901, 10, 77, 84, 56
+1901, 11, 42, 62, 38
+1901, 12, 62, 94, 22
+1902, 1, 58, 80, 37
+1902, 2, 43, 56, 16
+1902, 3, 53, 92, 9
+1902, 4, 81, 87, 33
+1902, 5, 85, 86, 60
+1902, 6, 98, 98, 32
+1902, 7, 100, 100, 54
+1902, 8, 107, 116, 69
+1902, 9, 86, 101, 43
+1902, 10, 71, 112, 34
+1902, 11, 43, 61, 7
+1902, 12, 30, 77, 21
+1903, 1, 38, 89, 12
+1903, 2, 43, 95, 29
+1903, 3, 67, 81, 49
+1903, 4, 59, 104, 32
+1903, 5, 79, 80, 64
+1903, 6, 117, 123, 53
+1903, 7, 104, 101, 49
+1903, 8, 111, 137, 56
+1903, 9, 68, 72, 23
+1903, 10, 81, 100, 62
+1903, 11, 68, 67, 50
+1903, 12, 34, 76, 42
+1904, 1, 65, 66, 33
+1904, 2, 41, 95, 18
+1904, 3, 46, 101, 31
+1904, 4, 53, 72, 32
+1904, 5, 82, 104, 52
+1904, 6, 123, 102, 32
+1904, 7, 109, 127, 30
+1904, 8, 100, 114, 67
+1904, 9, 91, 99, 45
+1904, 10, 79, 84, 62
+1904, 11, 38, 86, 30
+1904, 12, 71, 56, 14
+1905, 1, 59, 64, 39
+1905, 2, 75, 73, 32
+1905, 3, 30, 102, 36
+1905, 4, 86, 83, 39
+1905, 5, 93, 66, 31
+1905, 6, 118, 137, 36
+1905, 7, 129, 95, 31
+1905, 8, 104, 128, 56
+1905, 9, 59, 87, 61
+1905, 10, 54, 86, 56
+1905, 11, 46, 78, 51
+1905, 12, 57, 94, 47
+1906, 1, 75, 79, 17
+1906, 2, 72, 91, 44
+1906, 3, 52, 77, 32
+1906, 4, 63, 94, 41
+1906, 5, 83, 92, 48
+1906, 6, 121, 98, 65
+1906, 7, 93, 129, 60
+1906, 8, 104, 100, 48
+1906, 9, 90, 102, 59
+1906, 10, 58, 74, 42
+1906, 11, 52, 57, 9
+1906, 12, 53, 87, 28
+1907, 1, 74, 82, 50
+1907, 2, 45, 76, 10
+1907, 3, 38, 62, 37
+1907, 4, 58, 93, 59
+1907, 5, 66, 69, 21
+1907, 6, 102, 112, 42
+1907, 7, 125, 129, 30
+1907, 8, 108, 128, 51
+1907, 9, 81, 98, 23
+1907, 10, 58, 84, 45
+1907, 11, 68, 70, 51
+1907, 12, 70, 76, 29
+1908, 1, 49, 75, 11
+1908, 2, 56, 73, 45
+1908, 3, 79, 93, 29
+1908, 4, 93, 82, 39
+1908, 5, 70, 87, 52
+1908, 6, 113, 107, 34
+1908, 7, 120, 97, 40
+1908, 8, 92, 95, 74
+1908, 9, 88, 83, 16
+1908, 10, 57, 67, 33
+1908, 11, 30, 55, 12
+1908, 12, 37, 85, 54
+1909, 1, 67, 79, 47
+1909, 2, 68, 101, 7
+1909, 3, 59, 94, 14
+1909, 4, 58, 93, 49
+1909, 5, 79, 71, 32
+1909, 6, 129, 126, 68
+1909, 7, 82, 138, 52
+1909, 8, 96, 124, 73
+1909, 9, 85, 72, 27
+1909, 10, 92, 107, 61
+1909, 11, 42, 97, 51
+1909, 12, 31, 96, 33
+1910, 1, 71, 104, 27
+1910, 2, 76, 103, 6
+1910, 3, 53, 70, 13
+1910, 4, 71, 102, 37
+1910, 5, 63, 96, 34
+1910, 6, 112, 106, 59
+1910, 7, 81, 94, 28
+1910, 8, 98, 107, 26
+1910, 9, 63, 77, 21
+1910, 10, 60, 72, 39
+1910, 11, 36, 66, 12
+1910, 12, 62, 99, 36
+1911, 1, 78, 101, 48
+1911, 2, 35, 61, 38
+1911, 3, 48, 86, 24
+1911, 4, 78, 93, 31
+1911, 5, 90, 92, 49
+1911, 6, 89, 115, 64
+1911, 7, 129, 90, 46
+1911, 8, 88, 116, 35
+1911, 9, 91, 109, 64
+1911, 10, 95, 78, 45
+1911, 11, 55, 103, 8
+1911, 12, 36, 79, 10
+1912, 1, 30, 90, 15
+1912, 2, 49, 76, 37
+1912, 3, 79, 68, 45
+1912, 4, 74, 90, 52
+1912, 5, 61, 99, 30
+1912, 6, 112, 93, 39
+1912, 7, 88, 110, 48
+1912, 8, 99, 138, 47
+1912, 9, 92, 93, 56
+1912, 10, 86, 98, 46
+1912, 11, 31, 104, 14
+1912, 12, 60, 101, 19
+1913, 1, 71, 103, 37
+1913, 2, 42, 104, 26
+1913, 3, 68, 66, 31
+1913, 4, 81, 108, 57
+1913, 5, 77, 88, 64
+1913, 6, 98, 94, 46
+1913, 7, 127, 111, 36
+1913, 8, 91, 95, 48
+1913, 9, 51, 110, 23
+1913, 10, 77, 73, 46
+1913, 11, 36, 103, 11
+1913, 12, 45, 66, 40
+1914, 1, 55, 78, 21
+1914, 2, 40, 80, 6
+1914, 3, 71, 84, 12
+1914, 4, 56, 111, 23
+1914, 5, 79, 84, 17
+1914, 6, 124, 105, 62
+1914, 7, 121, 95, 68
+1914, 8, 81, 121, 37
+1914, 9, 64, 65, 52
+1914, 10, 56, 106, 27
+1914, 11, 53, 97, 52
+1914, 12, 75, 104, 39
+1915, 1, 37, 86, 6
+1915, 2, 74, 85, 30
+1915, 3, 75, 77, 49
+1915, 4, 72, 104, 37
+1915, 5, 88, 95, 41
+1915, 6, 111, 122, 53
+1915, 7, 112, 108, 43
+1915, 8, 119, 107, 51
+1915, 9, 85, 95, 43
+1915, 10, 76, 69, 48
+1915, 11, 42, 88, 48
+1915, 12, 42, 68, 13
+1916, 1, 70, 100, 30
+1916, 2, 64, 77, 10
+1916, 3, 45, 104, 26
+1916, 4, 74, 98, 53
+1916, 5, 52, 86, 26
+1916, 6, 105, 139, 56
+1916, 7, 123, 90, 36
+1916, 8, 87, 99, 32
+1916, 9, 73, 107, 30
+1916, 10, 79, 109, 51
+1916, 11, 45, 69, 43
+1916, 12, 62, 85, 11
+1917, 1, 73, 87, 5
+1917, 2, 61, 102, 18
+1917, 3, 48, 71, 50
+1917, 4, 83, 95, 33
+1917, 5, 97, 102, 38
+1917, 6, 117, 114, 66
+1917, 7, 127, 107, 66
+1917, 8, 120, 101, 36
+1917, 9, 79, 102, 44
+1917, 10, 56, 114, 38
+1917, 11, 66, 69, 36
+1917, 12, 33, 71, 52
+1918, 1, 67, 76, 42
+1918, 2, 71, 95, 33
+1918, 3, 51, 56, 28
+1918, 4, 95, 66, 50
+1918, 5, 77, 92, 51
+1918, 6, 91, 92, 64
+1918, 7, 103, 97, 51
+1918, 8, 90, 116, 55
+1918, 9, 72, 108, 34
+1918, 10, 60, 76, 55
+1918, 11, 63, 100, 44
+1918, 12, 30, 65, 12
+1919, 1, 58, 89, 48
+1919, 2, 45, 102, 29
+1919, 3, 48, 101, 47
+1919, 4, 68, 105, 64
+1919, 5, 71, 112, 18
+1919, 6, 129, 90, 73
+1919, 7, 120, 95, 73
+1919, 8, 96, 109, 35
+1919, 9, 70, 92, 20
+1919, 10, 61, 90, 41
+1919, 11, 37, 103, 6
+1919, 12, 70, 95, 25
+1920, 1, 43, 86, 52
+1920, 2, 69, 87, 51
+1920, 3, 61, 79, 27
+1920, 4, 65, 103, 51
+1920, 5, 60, 66, 21
+1920, 6, 80, 129, 50
+1920, 7, 106, 127, 56
+1920, 8, 110, 120, 39
+1920, 9, 71, 110, 64
+1920, 10, 79, 78, 58
+1920, 11, 51, 69, 41
+1920, 12, 56, 83, 8
+1921, 1, 65, 94, 10
+1921, 2, 32, 61, 44
+1921, 3, 76, 75, 24
+1921, 4, 52, 76, 55
+1921, 5, 50, 81, 46
+1921, 6, 128, 123, 48
+1921, 7, 92, 122, 38
+1921, 8, 102, 107, 50
+1921, 9, 93, 88, 44
+1921, 10, 96, 92, 24
+1921, 11, 64, 90, 38
+1921, 12, 34, 58, 38
+1922, 1, 75, 68, 50
+1922, 2, 40, 89, 29
+1922, 3, 31, 72, 46
+1922, 4, 80, 101, 22
+1922, 5, 94, 89, 61
+1922, 6, 85, 100, 65
+1922, 7, 111, 132, 32
+1922, 8, 83, 110, 45
+1922, 9, 81, 90, 32
+1922, 10, 60, 88, 22
+1922, 11, 45, 59, 37
+1922, 12, 34, 73, 36
+1923, 1, 46, 92, 47
+1923, 2, 75, 73, 5
+1923, 3, 58, 65, 21
+1923, 4, 83, 99, 47
+1923, 5, 64, 71, 37
+1923, 6, 124, 120, 57
+1923, 7, 114, 132, 32
+1923, 8, 113, 136, 56
+1923, 9, 54, 91, 43
+1923, 10, 57, 107, 26
+1923, 11, 75, 85, 43
+1923, 12, 38, 71, 29
+1924, 1, 66, 95, 49
+1924, 2, 72, 92, 48
+1924, 3, 34, 86, 17
+1924, 4, 58, 69, 23
+1924, 5, 77, 71, 25
+1924, 6, 117, 125, 27
+1924, 7, 105, 105, 33
+1924, 8, 83, 124, 25
+1924, 9, 99, 107, 57
+1924, 10, 55, 75, 59
+1924, 11, 47, 93, 5
+1924, 12, 71, 73, 46
+1925, 1, 30, 78, 41
+1925, 2, 33, 59, 48
+1925, 3, 39, 59, 8
+1925, 4, 82, 82, 35
+1925, 5, 65, 76, 21
+1925, 6, 99, 97, 62
+1925, 7, 82, 104, 63
+1925, 8, 116, 111, 67
+1925, 9, 97, 82, 25
+1925, 10, 63, 78, 55
+1925, 11, 32, 86, 50
+1925, 12, 52, 63, 13
+1926, 1, 76, 94, 52
+1926, 2, 50, 62, 34
+1926, 3, 41, 95, 52
+1926, 4, 84, 68, 17
+1926, 5, 52, 76, 33
+1926, 6, 97, 125, 49
+1926, 7, 92, 137, 37
+1926, 8, 90, 127, 30
+1926, 9, 60, 98, 42
+1926, 10, 54, 113, 33
+1926, 11, 62, 91, 52
+1926, 12, 62, 87, 48
+1927, 1, 54, 64, 30
+1927, 2, 60, 99, 30
+1927, 3, 45, 81, 36
+1927, 4, 61, 82, 58
+1927, 5, 57, 65, 57
+1927, 6, 125, 90, 56
+1927, 7, 104, 132, 68
+1927, 8, 127, 96, 66
+1927, 9, 77, 96, 15
+1927, 10, 68, 95, 55
+1927, 11, 55, 76, 38
+1927, 12, 78, 82, 36
+1928, 1, 67, 56, 45
+1928, 2, 51, 96, 51
+1928, 3, 63, 72, 15
+1928, 4, 85, 85, 30
+1928, 5, 54, 72, 46
+1928, 6, 90, 100, 26
+1928, 7, 103, 133, 29
+1928, 8, 94, 110, 29
+1928, 9, 71, 103, 63
+1928, 10, 79, 69, 62
+1928, 11, 49, 55, 24
+1928, 12, 33, 63, 12
+1929, 1, 48, 62, 20
+1929, 2, 77, 62, 51
+1929, 3, 70, 75, 8
+1929, 4, 83, 81, 23
+1929, 5, 64, 92, 56
+1929, 6, 126, 106, 35
+1929, 7, 96, 118, 45
+1929, 8, 80, 120, 46
+1929, 9, 94, 88, 62
+1929, 10, 50, 102, 33
+1929, 11, 62, 76, 47
+1929, 12, 70, 68, 33
+1930, 1, 51, 100, 30
+1930, 2, 60, 57, 46
+1930, 3, 65, 78, 38
+1930, 4, 70, 67, 37
+1930, 5, 83, 106, 62
+1930, 6, 127, 126, 51
+1930, 7, 108, 137, 61
+1930, 8, 81, 117, 69
+1930, 9, 51, 93, 37
+1930, 10, 56, 78, 63
+1930, 11, 38, 65, 18
+1930, 12, 32, 72, 19
+1931, 1, 76, 57, 15
+1931, 2, 62, 71, 53
+1931, 3, 32, 70, 25
+1931, 4, 76, 96, 51
+1931, 5, 85, 76, 61
+1931, 6, 112, 111, 57
+1931, 7, 85, 108, 42
+1931, 8, 125, 114, 29
+1931, 9, 89, 92, 27
+1931, 10, 95, 83, 19
+1931, 11, 34, 103, 25
+1931, 12, 33, 102, 50
+1932, 1, 38, 87, 6
+1932, 2, 66, 101, 15
+1932, 3, 40, 63, 27
+1932, 4, 60, 107, 15
+1932, 5, 98, 83, 27
+1932, 6, 122, 104, 48
+1932, 7, 92, 137, 46
+1932, 8, 104, 129, 29
+1932, 9, 63, 95, 39
+1932, 10, 76, 83, 35
+1932, 11, 62, 65, 43
+1932, 12, 75, 78, 7
+1933, 1, 71, 90, 7
+1933, 2, 72, 67, 32
+1933, 3, 32, 102, 25
+1933, 4, 67, 107, 39
+1933, 5, 78, 95, 43
+1933, 6, 115, 104, 33
+1933, 7, 127, 135, 74
+1933, 8, 99, 137, 52
+1933, 9, 57, 94, 51
+1933, 10, 76, 96, 28
+1933, 11, 40, 70, 12
+1933, 12, 30, 64, 12
+1934, 1, 70, 62, 35
+1934, 2, 34, 71, 7
+1934, 3, 66, 96, 7
+1934, 4, 60, 75, 36
+1934, 5, 67, 110, 15
+1934, 6, 93, 124, 31
+1934, 7, 123, 109, 69
+1934, 8, 80, 97, 57
+1934, 9, 69, 82, 51
+1934, 10, 95, 67, 53
+1934, 11, 61, 65, 24
+1934, 12, 71, 82, 14
+1935, 1, 53, 59, 46
+1935, 2, 36, 76, 7
+1935, 3, 66, 102, 7
+1935, 4, 80, 85, 55
+1935, 5, 65, 104, 30
+1935, 6, 86, 134, 68
+1935, 7, 128, 109, 44
+1935, 8, 117, 111, 45
+1935, 9, 60, 72, 53
+1935, 10, 56, 83, 62
+1935, 11, 74, 69, 42
+1935, 12, 49, 100, 11
+1936, 1, 38, 64, 28
+1936, 2, 67, 101, 39
+1936, 3, 33, 65, 54
+1936, 4, 74, 110, 25
+1936, 5, 62, 69, 39
+1936, 6, 107, 101, 73
+1936, 7, 102, 90, 47
+1936, 8, 88, 135, 47
+1936, 9, 62, 88, 32
+1936, 10, 96, 102, 19
+1936, 11, 72, 59, 51
+1936, 12, 56, 66, 45
+1937, 1, 50, 80, 23
+1937, 2, 56, 86, 39
+1937, 3, 30, 79, 16
+1937, 4, 69, 100, 19
+1937, 5, 99, 114, 22
+1937, 6, 128, 92, 33
+1937, 7, 128, 98, 44
+1937, 8, 92, 133, 56
+1937, 9, 67, 89, 17
+1937, 10, 79, 89, 40
+1937, 11, 48, 58, 36
+1937, 12, 79, 96, 51
+1938, 1, 78, 85, 34
+1938, 2, 41, 67, 5
+1938, 3, 41, 57, 45
+1938, 4, 88, 113, 16
+1938, 5, 73, 78, 28
+1938, 6, 92, 100, 42
+1938, 7, 118, 124, 68
+1938, 8, 89, 105, 65
+1938, 9, 73, 110, 45
+1938, 10, 98, 81, 60
+1938, 11, 54, 85, 16
+1938, 12, 70, 65, 42
+1939, 1, 39, 64, 18
+1939, 2, 33, 92, 27
+1939, 3, 39, 100, 34
+1939, 4, 97, 101, 21
+1939, 5, 70, 84, 29
+1939, 6, 103, 126, 57
+1939, 7, 114, 102, 70
+1939, 8, 110, 105, 36
+1939, 9, 99, 79, 54
+1939, 10, 57, 88, 16
+1939, 11, 73, 59, 6
+1939, 12, 46, 78, 22
+1940, 1, 57, 77, 49
+1940, 2, 68, 80, 46
+1940, 3, 73, 100, 5
+1940, 4, 77, 66, 17
+1940, 5, 79, 111, 43
+1940, 6, 112, 125, 65
+1940, 7, 85, 111, 52
+1940, 8, 85, 96, 53
+1940, 9, 58, 75, 53
+1940, 10, 67, 82, 36
+1940, 11, 78, 89, 16
+1940, 12, 62, 104, 10
+1941, 1, 51, 61, 35
+1941, 2, 36, 88, 18
+1941, 3, 73, 65, 11
+1941, 4, 97, 68, 49
+1941, 5, 80, 110, 47
+1941, 6, 100, 112, 64
+1941, 7, 123, 104, 40
+1941, 8, 93, 99, 45
+1941, 9, 86, 99, 33
+1941, 10, 98, 76, 64
+1941, 11, 72, 101, 24
+1941, 12, 77, 78, 40
+1942, 1, 48, 98, 8
+1942, 2, 55, 69, 46
+1942, 3, 36, 77, 24
+1942, 4, 76, 111, 23
+1942, 5, 99, 85, 49
+1942, 6, 83, 125, 72
+1942, 7, 125, 97, 41
+1942, 8, 106, 98, 68
+1942, 9, 87, 105, 35
+1942, 10, 93, 73, 28
+1942, 11, 44, 71, 23
+1942, 12, 58, 92, 47
+1943, 1, 65, 72, 28
+1943, 2, 53, 74, 46
+1943, 3, 56, 76, 33
+1943, 4, 62, 94, 34
+1943, 5, 97, 109, 23
+1943, 6, 105, 95, 41
+1943, 7, 104, 128, 37
+1943, 8, 83, 117, 56
+1943, 9, 56, 97, 58
+1943, 10, 67, 99, 22
+1943, 11, 70, 68, 53
+1943, 12, 52, 89, 20
+1944, 1, 69, 83, 53
+1944, 2, 74, 57, 13
+1944, 3, 57, 67, 13
+1944, 4, 85, 103, 25
+1944, 5, 57, 113, 21
+1944, 6, 116, 102, 60
+1944, 7, 105, 92, 59
+1944, 8, 90, 125, 68
+1944, 9, 73, 93, 32
+1944, 10, 90, 84, 30
+1944, 11, 51, 83, 13
+1944, 12, 36, 82, 41
+1945, 1, 70, 82, 45
+1945, 2, 56, 82, 44
+1945, 3, 55, 103, 21
+1945, 4, 95, 93, 27
+1945, 5, 88, 86, 59
+1945, 6, 127, 98, 25
+1945, 7, 90, 112, 60
+1945, 8, 104, 132, 53
+1945, 9, 87, 96, 29
+1945, 10, 97, 81, 29
+1945, 11, 36, 82, 7
+1945, 12, 47, 72, 6
+1946, 1, 39, 65, 46
+1946, 2, 62, 74, 47
+1946, 3, 75, 83, 20
+1946, 4, 77, 107, 61
+1946, 5, 63, 110, 54
+1946, 6, 92, 131, 55
+1946, 7, 101, 111, 42
+1946, 8, 118, 118, 69
+1946, 9, 74, 109, 58
+1946, 10, 61, 67, 38
+1946, 11, 49, 94, 34
+1946, 12, 73, 81, 27
+1947, 1, 56, 72, 48
+1947, 2, 78, 97, 36
+1947, 3, 57, 102, 51
+1947, 4, 71, 92, 45
+1947, 5, 58, 81, 39
+1947, 6, 93, 136, 53
+1947, 7, 117, 132, 41
+1947, 8, 91, 104, 33
+1947, 9, 65, 95, 40
+1947, 10, 64, 87, 26
+1947, 11, 46, 87, 7
+1947, 12, 43, 78, 10
+1948, 1, 40, 79, 12
+1948, 2, 67, 63, 52
+1948, 3, 73, 66, 24
+1948, 4, 97, 86, 52
+1948, 5, 73, 105, 35
+1948, 6, 99, 129, 69
+1948, 7, 122, 109, 64
+1948, 8, 104, 134, 33
+1948, 9, 62, 79, 62
+1948, 10, 61, 71, 45
+1948, 11, 36, 91, 54
+1948, 12, 51, 95, 25
+1949, 1, 38, 73, 41
+1949, 2, 39, 76, 49
+1949, 3, 77, 84, 53
+1949, 4, 89, 69, 20
+1949, 5, 75, 114, 47
+1949, 6, 100, 117, 73
+1949, 7, 116, 105, 55
+1949, 8, 116, 95, 71
+1949, 9, 69, 98, 55
+1949, 10, 66, 111, 51
+1949, 11, 60, 77, 18
+1949, 12, 56, 97, 53
+1950, 1, 79, 82, 42
+1950, 2, 55, 71, 10
+1950, 3, 59, 104, 23
+1950, 4, 77, 107, 34
+1950, 5, 58, 72, 39
+1950, 6, 101, 139, 42
+1950, 7, 102, 135, 55
+1950, 8, 111, 133, 30
+1950, 9, 61, 89, 15
+1950, 10, 86, 113, 56
+1950, 11, 72, 63, 35
+1950, 12, 59, 80, 23
+1951, 1, 55, 80, 24
+1951, 2, 53, 83, 29
+1951, 3, 71, 68, 24
+1951, 4, 67, 98, 29
+1951, 5, 80, 91, 64
+1951, 6, 96, 108, 51
+1951, 7, 125, 103, 43
+1951, 8, 102, 124, 36
+1951, 9, 61, 77, 17
+1951, 10, 67, 77, 36
+1951, 11, 40, 90, 26
+1951, 12, 64, 69, 38
+1952, 1, 62, 86, 36
+1952, 2, 31, 74, 32
+1952, 3, 65, 70, 35
+1952, 4, 59, 99, 21
+1952, 5, 88, 82, 43
+1952, 6, 124, 94, 66
+1952, 7, 99, 90, 30
+1952, 8, 127, 107, 32
+1952, 9, 54, 74, 53
+1952, 10, 92, 80, 43
+1952, 11, 50, 59, 29
+1952, 12, 79, 87, 8
+1953, 1, 55, 94, 42
+1953, 2, 33, 77, 33
+1953, 3, 55, 70, 5
+1953, 4, 97, 87, 29
+1953, 5, 56, 88, 57
+1953, 6, 83, 116, 41
+1953, 7, 99, 126, 60
+1953, 8, 105, 99, 62
+1953, 9, 66, 79, 39
+1953, 10, 65, 91, 25
+1953, 11, 58, 62, 17
+1953, 12, 40, 78, 31
+1954, 1, 59, 59, 39
+1954, 2, 73, 92, 25
+1954, 3, 67, 86, 18
+1954, 4, 54, 99, 45
+1954, 5, 64, 68, 50
+1954, 6, 122, 102, 35
+1954, 7, 113, 134, 45
+1954, 8, 123, 102, 58
+1954, 9, 84, 102, 32
+1954, 10, 90, 110, 62
+1954, 11, 45, 103, 46
+1954, 12, 62, 96, 53
+1955, 1, 55, 74, 9
+1955, 2, 67, 97, 52
+1955, 3, 42, 62, 15
+1955, 4, 85, 75, 16
+1955, 5, 80, 102, 21
+1955, 6, 81, 103, 52
+1955, 7, 97, 99, 36
+1955, 8, 82, 91, 39
+1955, 9, 98, 95, 44
+1955, 10, 56, 70, 57
+1955, 11, 53, 74, 21
+1955, 12, 32, 100, 47
+1956, 1, 43, 102, 11
+1956, 2, 62, 104, 37
+1956, 3, 64, 64, 13
+1956, 4, 89, 72, 50
+1956, 5, 74, 75, 60
+1956, 6, 114, 95, 61
+1956, 7, 123, 99, 39
+1956, 8, 104, 110, 49
+1956, 9, 81, 87, 22
+1956, 10, 88, 78, 43
+1956, 11, 36, 69, 43
+1956, 12, 53, 88, 43
+1957, 1, 69, 66, 7
+1957, 2, 79, 80, 13
+1957, 3, 38, 98, 10
+1957, 4, 93, 108, 30
+1957, 5, 80, 95, 36
+1957, 6, 125, 124, 52
+1957, 7, 96, 100, 74
+1957, 8, 85, 91, 58
+1957, 9, 81, 93, 24
+1957, 10, 70, 71, 54
+1957, 11, 32, 66, 33
+1957, 12, 49, 75, 45
+1958, 1, 43, 89, 25
+1958, 2, 55, 86, 12
+1958, 3, 73, 84, 31
+1958, 4, 57, 99, 24
+1958, 5, 81, 81, 33
+1958, 6, 108, 118, 27
+1958, 7, 112, 114, 51
+1958, 8, 96, 136, 40
+1958, 9, 77, 105, 44
+1958, 10, 73, 90, 58
+1958, 11, 59, 93, 20
+1958, 12, 47, 73, 54
+1959, 1, 64, 68, 16
+1959, 2, 55, 95, 18
+1959, 3, 71, 64, 49
+1959, 4, 94, 71, 22
+1959, 5, 83, 67, 35
+1959, 6, 95, 130, 38
+1959, 7, 101, 130, 43
+1959, 8, 93, 95, 61
+1959, 9, 58, 100, 48
+1959, 10, 69, 94, 18
+1959, 11, 36, 77, 13
+1959, 12, 60, 81, 26
+1960, 1, 58, 83, 25
+1960, 2, 69, 85, 49
+1960, 3, 43, 57, 36
+1960, 4, 90, 72, 62
+1960, 5, 94, 102, 37
+1960, 6, 121, 128, 65
+1960, 7, 88, 133, 57
+1960, 8, 87, 127, 35
+1960, 9, 62, 79, 39
+1960, 10, 54, 113, 21
+1960, 11, 64, 60, 24
+1960, 12, 54, 68, 18
+1961, 1, 70, 93, 18
+1961, 2, 63, 72, 15
+1961, 3, 43, 102, 19
+1961, 4, 53, 87, 45
+1961, 5, 52, 66, 27
+1961, 6, 110, 100, 58
+1961, 7, 92, 133, 35
+1961, 8, 116, 98, 66
+1961, 9, 93, 82, 29
+1961, 10, 85, 96, 48
+1961, 11, 74, 88, 17
+1961, 12, 32, 77, 31
+1962, 1, 69, 59, 31
+1962, 2, 42, 90, 53
+1962, 3, 33, 79, 22
+1962, 4, 67, 75, 26
+1962, 5, 91, 114, 40
+1962, 6, 118, 134, 72
+1962, 7, 128, 118, 30
+1962, 8, 84, 115, 27
+1962, 9, 75, 82, 38
+1962, 10, 52, 76, 48
+1962, 11, 45, 96, 29
+1962, 12, 71, 103, 15
+1963, 1, 75, 84, 7
+1963, 2, 42, 70, 10
+1963, 3, 36, 66, 41
+1963, 4, 51, 110, 45
+1963, 5, 59, 88, 42
+1963, 6, 118, 126, 41
+1963, 7, 123, 114, 61
+1963, 8, 96, 111, 66
+1963, 9, 91, 109, 30
+1963, 10, 93, 66, 15
+1963, 11, 62, 64, 49
+1963, 12, 68, 91, 22
+1964, 1, 43, 101, 12
+1964, 2, 33, 83, 20
+1964, 3, 36, 100, 12
+1964, 4, 81, 93, 55
+1964, 5, 81, 110, 42
+1964, 6, 93, 127, 37
+1964, 7, 122, 103, 74
+1964, 8, 118, 90, 58
+1964, 9, 76, 71, 57
+1964, 10, 84, 103, 36
+1964, 11, 51, 88, 14
+1964, 12, 56, 88, 22
+1965, 1, 38, 80, 28
+1965, 2, 73, 102, 25
+1965, 3, 67, 81, 13
+1965, 4, 84, 67, 40
+1965, 5, 93, 104, 54
+1965, 6, 92, 127, 58
+1965, 7, 123, 90, 40
+1965, 8, 91, 121, 70
+1965, 9, 55, 111, 54
+1965, 10, 54, 104, 16
+1965, 11, 71, 56, 13
+1965, 12, 45, 100, 44
+1966, 1, 41, 86, 42
+1966, 2, 70, 95, 35
+1966, 3, 37, 89, 16
+1966, 4, 50, 101, 55
+1966, 5, 81, 91, 31
+1966, 6, 111, 91, 72
+1966, 7, 110, 92, 59
+1966, 8, 91, 92, 57
+1966, 9, 60, 80, 60
+1966, 10, 70, 80, 41
+1966, 11, 48, 72, 13
+1966, 12, 48, 95, 37
+1967, 1, 74, 68, 16
+1967, 2, 61, 77, 21
+1967, 3, 62, 103, 20
+1967, 4, 72, 72, 22
+1967, 5, 81, 89, 32
+1967, 6, 88, 122, 67
+1967, 7, 90, 125, 50
+1967, 8, 88, 125, 57
+1967, 9, 59, 94, 20
+1967, 10, 94, 83, 27
+1967, 11, 74, 71, 46
+1967, 12, 72, 93, 50
+1968, 1, 58, 104, 50
+1968, 2, 37, 103, 10
+1968, 3, 68, 94, 10
+1968, 4, 94, 75, 44
+1968, 5, 55, 77, 37
+1968, 6, 85, 111, 61
+1968, 7, 87, 99, 53
+1968, 8, 87, 126, 39
+1968, 9, 64, 104, 44
+1968, 10, 64, 93, 49
+1968, 11, 37, 64, 11
+1968, 12, 40, 63, 19
+1969, 1, 56, 78, 48
+1969, 2, 56, 70, 12
+1969, 3, 32, 75, 11
+1969, 4, 52, 65, 29
+1969, 5, 67, 76, 44
+1969, 6, 107, 119, 61
+1969, 7, 115, 91, 50
+1969, 8, 85, 129, 59
+1969, 9, 60, 100, 19
+1969, 10, 93, 108, 31
+1969, 11, 67, 64, 12
+1969, 12, 47, 81, 44
+1970, 1, 42, 96, 23
+1970, 2, 73, 94, 10
+1970, 3, 34, 79, 54
+1970, 4, 59, 81, 16
+1970, 5, 99, 103, 48
+1970, 6, 82, 108, 51
+1970, 7, 99, 108, 39
+1970, 8, 99, 117, 26
+1970, 9, 96, 98, 44
+1970, 10, 92, 86, 19
+1970, 11, 33, 55, 5
+1970, 12, 78, 95, 29
+1971, 1, 56, 66, 15
+1971, 2, 67, 86, 5
+1971, 3, 77, 85, 17
+1971, 4, 64, 99, 48
+1971, 5, 74, 76, 26
+1971, 6, 94, 134, 32
+1971, 7, 110, 114, 43
+1971, 8, 84, 120, 58
+1971, 9, 85, 100, 21
+1971, 10, 87, 77, 61
+1971, 11, 69, 83, 36
+1971, 12, 51, 61, 9
+1972, 1, 62, 104, 9
+1972, 2, 32, 73, 28
+1972, 3, 77, 84, 46
+1972, 4, 82, 71, 36
+1972, 5, 55, 79, 40
+1972, 6, 124, 118, 74
+1972, 7, 85, 124, 39
+1972, 8, 112, 128, 68
+1972, 9, 51, 95, 24
+1972, 10, 73, 87, 26
+1972, 11, 66, 65, 51
+1972, 12, 65, 85, 10
+1973, 1, 68, 62, 51
+1973, 2, 78, 101, 46
+1973, 3, 43, 97, 5
+1973, 4, 81, 95, 52
+1973, 5, 77, 84, 45
+1973, 6, 103, 131, 42
+1973, 7, 105, 92, 55
+1973, 8, 121, 130, 56
+1973, 9, 82, 104, 35
+1973, 10, 98, 107, 58
+1973, 11, 67, 104, 43
+1973, 12, 63, 91, 51
+1974, 1, 65, 104, 25
+1974, 2, 62, 73, 15
+1974, 3, 69, 97, 42
+1974, 4, 89, 113, 39
+1974, 5, 75, 71, 63
+1974, 6, 112, 108, 51
+1974, 7, 116, 99, 52
+1974, 8, 87, 120, 55
+1974, 9, 77, 72, 16
+1974, 10, 97, 86, 27
+1974, 11, 33, 57, 5
+1974, 12, 43, 88, 40
+1975, 1, 54, 59, 53
+1975, 2, 75, 88, 52
+1975, 3, 50, 59, 21
+1975, 4, 55, 87, 53
+1975, 5, 91, 82, 52
+1975, 6, 96, 125, 51
+1975, 7, 116, 110, 25
+1975, 8, 117, 120, 71
+1975, 9, 98, 85, 36
+1975, 10, 82, 101, 32
+1975, 11, 70, 100, 28
+1975, 12, 32, 92, 24
+1976, 1, 33, 85, 42
+1976, 2, 40, 91, 11
+1976, 3, 69, 99, 5
+1976, 4, 68, 76, 33
+1976, 5, 56, 87, 40
+1976, 6, 113, 110, 67
+1976, 7, 80, 108, 63
+1976, 8, 88, 94, 29
+1976, 9, 84, 73, 26
+1976, 10, 95, 75, 45
+1976, 11, 79, 65, 31
+1976, 12, 75, 59, 37
+1977, 1, 30, 96, 48
+1977, 2, 60, 56, 23
+1977, 3, 60, 104, 50
+1977, 4, 77, 112, 57
+1977, 5, 81, 84, 31
+1977, 6, 129, 108, 64
+1977, 7, 88, 96, 59
+1977, 8, 123, 121, 45
+1977, 9, 89, 82, 41
+1977, 10, 62, 81, 17
+1977, 11, 77, 65, 19
+1977, 12, 48, 82, 14
+1978, 1, 57, 67, 49
+1978, 2, 41, 60, 47
+1978, 3, 33, 77, 43
+1978, 4, 83, 99, 30
+1978, 5, 69, 70, 45
+1978, 6, 107, 130, 49
+1978, 7, 98, 117, 44
+1978, 8, 105, 116, 53
+1978, 9, 66, 99, 18
+1978, 10, 69, 86, 28
+1978, 11, 44, 103, 23
+1978, 12, 70, 95, 15
+1979, 1, 33, 63, 15
+1979, 2, 59, 92, 9
+1979, 3, 39, 64, 7
+1979, 4, 59, 103, 61
+1979, 5, 61, 80, 36
+1979, 6, 99, 124, 70
+1979, 7, 121, 134, 50
+1979, 8, 82, 132, 30
+1979, 9, 76, 106, 61
+1979, 10, 69, 82, 56
+1979, 11, 42, 78, 27
+1979, 12, 39, 71, 32
+1980, 1, 60, 91, 33
+1980, 2, 79, 84, 21
+1980, 3, 41, 66, 35
+1980, 4, 93, 89, 60
+1980, 5, 93, 109, 58
+1980, 6, 96, 139, 41
+1980, 7, 114, 94, 45
+1980, 8, 127, 136, 71
+1980, 9, 99, 75, 62
+1980, 10, 97, 97, 45
+1980, 11, 47, 89, 31
+1980, 12, 73, 80, 22
+1981, 1, 69, 89, 52
+1981, 2, 34, 96, 14
+1981, 3, 38, 91, 33
+1981, 4, 82, 85, 34
+1981, 5, 83, 91, 46
+1981, 6, 95, 128, 31
+1981, 7, 98, 95, 63
+1981, 8, 90, 96, 71
+1981, 9, 57, 93, 27
+1981, 10, 52, 91, 28
+1981, 11, 50, 89, 16
+1981, 12, 65, 66, 35
+1982, 1, 49, 69, 24
+1982, 2, 53, 99, 7
+1982, 3, 74, 55, 18
+1982, 4, 81, 82, 27
+1982, 5, 55, 101, 29
+1982, 6, 107, 109, 48
+1982, 7, 117, 114, 61
+1982, 8, 105, 117, 46
+1982, 9, 51, 83, 44
+1982, 10, 74, 97, 17
+1982, 11, 75, 100, 11
+1982, 12, 45, 76, 16
+1983, 1, 52, 91, 5
+1983, 2, 74, 75, 27
+1983, 3, 56, 92, 23
+1983, 4, 97, 89, 59
+1983, 5, 68, 66, 17
+1983, 6, 83, 99, 28
+1983, 7, 119, 105, 29
+1983, 8, 120, 108, 39
+1983, 9, 97, 91, 26
+1983, 10, 75, 97, 15
+1983, 11, 55, 63, 21
+1983, 12, 65, 63, 54
+1984, 1, 68, 73, 11
+1984, 2, 65, 56, 23
+1984, 3, 44, 81, 7
+1984, 4, 55, 111, 55
+1984, 5, 75, 106, 59
+1984, 6, 92, 95, 74
+1984, 7, 115, 92, 62
+1984, 8, 112, 92, 26
+1984, 9, 99, 102, 40
+1984, 10, 58, 86, 51
+1984, 11, 66, 76, 13
+1984, 12, 63, 92, 27
+1985, 1, 63, 69, 39
+1985, 2, 60, 64, 43
+1985, 3, 73, 71, 28
+1985, 4, 76, 98, 45
+1985, 5, 80, 86, 61
+1985, 6, 116, 103, 60
+1985, 7, 122, 127, 41
+1985, 8, 115, 118, 48
+1985, 9, 53, 110, 47
+1985, 10, 70, 114, 44
+1985, 11, 66, 104, 6
+1985, 12, 32, 92, 37
+1986, 1, 68, 72, 25
+1986, 2, 73, 91, 48
+1986, 3, 76, 59, 9
+1986, 4, 69, 93, 36
+1986, 5, 90, 94, 39
+1986, 6, 101, 91, 42
+1986, 7, 110, 126, 32
+1986, 8, 87, 136, 33
+1986, 9, 65, 107, 60
+1986, 10, 88, 65, 54
+1986, 11, 65, 96, 49
+1986, 12, 34, 58, 46
+1987, 1, 63, 90, 30
+1987, 2, 33, 74, 25
+1987, 3, 75, 84, 46
+1987, 4, 86, 67, 21
+1987, 5, 63, 98, 17
+1987, 6, 81, 105, 58
+1987, 7, 106, 120, 64
+1987, 8, 85, 99, 36
+1987, 9, 97, 94, 24
+1987, 10, 61, 67, 53
+1987, 11, 77, 85, 15
+1987, 12, 72, 79, 41
+1988, 1, 72, 66, 44
+1988, 2, 65, 85, 16
+1988, 3, 31, 90, 41
+1988, 4, 78, 99, 37
+1988, 5, 68, 106, 51
+1988, 6, 88, 113, 35
+1988, 7, 121, 105, 42
+1988, 8, 84, 132, 65
+1988, 9, 69, 100, 41
+1988, 10, 83, 101, 15
+1988, 11, 30, 86, 37
+1988, 12, 72, 75, 26
+1989, 1, 74, 100, 10
+1989, 2, 69, 94, 48
+1989, 3, 46, 65, 34
+1989, 4, 50, 85, 59
+1989, 5, 82, 112, 62
+1989, 6, 126, 119, 50
+1989, 7, 124, 125, 43
+1989, 8, 108, 100, 73
+1989, 9, 87, 103, 52
+1989, 10, 86, 69, 40
+1989, 11, 78, 56, 33
+1989, 12, 78, 77, 53
+1990, 1, 67, 65, 7
+1990, 2, 40, 60, 38
+1990, 3, 55, 83, 7
+1990, 4, 50, 70, 54
+1990, 5, 71, 108, 24
+1990, 6, 84, 126, 27
+1990, 7, 117, 109, 71
+1990, 8, 109, 96, 25
+1990, 9, 83, 96, 44
+1990, 10, 92, 114, 38
+1990, 11, 62, 65, 24
+1990, 12, 76, 65, 25
+1991, 1, 37, 69, 48
+1991, 2, 35, 63, 17
+1991, 3, 66, 69, 13
+1991, 4, 78, 80, 39
+1991, 5, 95, 78, 25
+1991, 6, 127, 113, 68
+1991, 7, 88, 102, 40
+1991, 8, 125, 95, 61
+1991, 9, 54, 96, 40
+1991, 10, 85, 109, 53
+1991, 11, 75, 65, 10
+1991, 12, 72, 90, 44
+1992, 1, 33, 64, 52
+1992, 2, 39, 81, 43
+1992, 3, 68, 82, 15
+1992, 4, 72, 94, 32
+1992, 5, 97, 76, 58
+1992, 6, 125, 111, 55
+1992, 7, 127, 129, 29
+1992, 8, 128, 122, 52
+1992, 9, 81, 105, 38
+1992, 10, 99, 107, 42
+1992, 11, 54, 101, 47
+1992, 12, 35, 81, 42
+1993, 1, 53, 69, 40
+1993, 2, 77, 75, 44
+1993, 3, 59, 94, 46
+1993, 4, 90, 110, 40
+1993, 5, 95, 105, 24
+1993, 6, 126, 102, 68
+1993, 7, 98, 139, 66
+1993, 8, 113, 117, 74
+1993, 9, 87, 109, 33
+1993, 10, 96, 73, 63
+1993, 11, 42, 97, 21
+1993, 12, 36, 85, 10
+1994, 1, 36, 88, 31
+1994, 2, 67, 74, 21
+1994, 3, 40, 87, 13
+1994, 4, 95, 109, 37
+1994, 5, 56, 79, 64
+1994, 6, 127, 96, 32
+1994, 7, 87, 108, 70
+1994, 8, 106, 131, 70
+1994, 9, 58, 78, 20
+1994, 10, 58, 67, 23
+1994, 11, 75, 96, 42
+1994, 12, 31, 92, 30
+1995, 1, 62, 95, 27
+1995, 2, 30, 89, 48
+1995, 3, 71, 91, 46
+1995, 4, 56, 105, 20
+1995, 5, 83, 66, 25
+1995, 6, 84, 90, 42
+1995, 7, 128, 128, 30
+1995, 8, 97, 117, 29
+1995, 9, 93, 93, 50
+1995, 10, 83, 89, 50
+1995, 11, 70, 72, 47
+1995, 12, 33, 96, 34
+1996, 1, 38, 93, 19
+1996, 2, 69, 103, 41
+1996, 3, 31, 82, 25
+1996, 4, 96, 67, 41
+1996, 5, 76, 91, 21
+1996, 6, 98, 109, 66
+1996, 7, 90, 110, 42
+1996, 8, 97, 128, 67
+1996, 9, 70, 73, 32
+1996, 10, 65, 65, 58
+1996, 11, 45, 84, 26
+1996, 12, 48, 72, 29
+1997, 1, 42, 77, 17
+1997, 2, 48, 62, 23
+1997, 3, 57, 74, 40
+1997, 4, 69, 106, 51
+1997, 5, 77, 108, 19
+1997, 6, 126, 95, 63
+1997, 7, 121, 110, 56
+1997, 8, 129, 119, 70
+1997, 9, 66, 74, 52
+1997, 10, 72, 68, 64
+1997, 11, 77, 89, 17
+1997, 12, 37, 88, 10
+1998, 1, 49, 93, 35
+1998, 2, 55, 84, 18
+1998, 3, 64, 81, 21
+1998, 4, 75, 106, 44
+1998, 5, 97, 80, 60
+1998, 6, 83, 132, 29
+1998, 7, 99, 119, 62
+1998, 8, 92, 139, 63
+1998, 9, 77, 68, 16
+1998, 10, 66, 78, 29
+1998, 11, 38, 75, 36
+1998, 12, 70, 94, 9
+1999, 1, 69, 66, 42
+1999, 2, 76, 98, 43
+1999, 3, 34, 88, 43
+1999, 4, 69, 97, 29
+1999, 5, 57, 93, 48
+1999, 6, 127, 112, 49
+1999, 7, 125, 133, 46
+1999, 8, 116, 137, 62
+1999, 9, 74, 88, 27
+1999, 10, 93, 82, 64
+1999, 11, 75, 75, 38
+1999, 12, 51, 55, 6
+2000, 1, 55, 94, 42
+2000, 2, 41, 85, 16
+2000, 3, 51, 81, 49
+2000, 4, 86, 93, 26
+2000, 5, 98, 92, 46
+2000, 6, 86, 130, 38
+2000, 7, 108, 107, 37
+2000, 8, 112, 123, 53
+2000, 9, 93, 105, 39
+2000, 10, 54, 67, 51
+2000, 11, 69, 60, 40
+2000, 12, 64, 92, 38
+2001, 1, 35, 58, 15
+2001, 2, 69, 57, 11
+2001, 3, 60, 81, 45
+2001, 4, 68, 98, 27
+2001, 5, 78, 110, 21
+2001, 6, 124, 124, 72
+2001, 7, 94, 102, 45
+2001, 8, 124, 93, 69
+2001, 9, 62, 84, 33
+2001, 10, 56, 71, 35
+2001, 11, 63, 96, 34
+2001, 12, 76, 101, 38
+2002, 1, 46, 83, 34
+2002, 2, 57, 97, 25
+2002, 3, 33, 59, 23
+2002, 4, 67, 76, 61
+2002, 5, 52, 66, 43
+2002, 6, 103, 120, 66
+2002, 7, 96, 118, 48
+2002, 8, 84, 107, 28
+2002, 9, 74, 91, 30
+2002, 10, 62, 109, 21
+2002, 11, 73, 99, 39
+2002, 12, 49, 84, 11
+2003, 1, 51, 55, 54
+2003, 2, 74, 58, 18
+2003, 3, 45, 55, 24
+2003, 4, 56, 108, 52
+2003, 5, 94, 84, 38
+2003, 6, 113, 136, 50
+2003, 7, 112, 94, 43
+2003, 8, 120, 121, 69
+2003, 9, 99, 75, 28
+2003, 10, 60, 65, 25
+2003, 11, 50, 96, 10
+2003, 12, 35, 79, 33
+2004, 1, 44, 84, 53
+2004, 2, 38, 87, 7
+2004, 3, 77, 58, 16
+2004, 4, 84, 91, 17
+2004, 5, 72, 107, 59
+2004, 6, 108, 98, 70
+2004, 7, 97, 92, 26
+2004, 8, 109, 106, 30
+2004, 9, 99, 71, 53
+2004, 10, 95, 108, 22
+2004, 11, 42, 80, 47
+2004, 12, 32, 69, 23
+2005, 1, 72, 98, 13
+2005, 2, 54, 55, 31
+2005, 3, 43, 76, 34
+2005, 4, 92, 90, 40
+2005, 5, 55, 67, 32
+2005, 6, 124, 105, 70
+2005, 7, 126, 115, 30
+2005, 8, 106, 109, 59
+2005, 9, 79, 75, 31
+2005, 10, 86, 100, 16
+2005, 11, 69, 93, 49
+2005, 12, 56, 101, 41
+2006, 1, 70, 78, 6
+2006, 2, 52, 90, 14
+2006, 3, 50, 58, 14
+2006, 4, 85, 101, 21
+2006, 5, 79, 84, 28
+2006, 6, 112, 121, 41
+2006, 7, 97, 104, 33
+2006, 8, 109, 109, 47
+2006, 9, 62, 70, 24
+2006, 10, 60, 99, 58
+2006, 11, 74, 86, 53
+2006, 12, 74, 81, 49
+2007, 1, 49, 74, 9
+2007, 2, 45, 64, 50
+2007, 3, 59, 72, 9
+2007, 4, 74, 90, 63
+2007, 5, 86, 99, 62
+2007, 6, 84, 127, 44
+2007, 7, 101, 97, 26
+2007, 8, 82, 105, 70
+2007, 9, 88, 91, 30
+2007, 10, 53, 84, 51
+2007, 11, 67, 102, 20
+2007, 12, 61, 56, 20
+2008, 1, 38, 66, 5
+2008, 2, 35, 100, 49
+2008, 3, 69, 62, 18
+2008, 4, 69, 90, 17
+2008, 5, 78, 101, 53
+2008, 6, 99, 129, 53
+2008, 7, 89, 112, 64
+2008, 8, 91, 117, 41
+2008, 9, 69, 71, 15
+2008, 10, 73, 95, 41
+2008, 11, 31, 96, 13
+2008, 12, 37, 91, 43
+2009, 1, 55, 78, 48
+2009, 2, 64, 56, 21
+2009, 3, 46, 89, 7
+2009, 4, 61, 81, 27
+2009, 5, 70, 112, 58
+2009, 6, 124, 97, 30
+2009, 7, 91, 92, 46
+2009, 8, 122, 104, 47
+2009, 9, 79, 83, 40
+2009, 10, 68, 73, 16
+2009, 11, 51, 89, 52
+2009, 12, 32, 82, 9
+2010, 1, 39, 56, 8
+2010, 2, 63, 56, 41
+2010, 3, 65, 57, 46
+2010, 4, 98, 84, 32
+2010, 5, 71, 96, 58
+2010, 6, 113, 130, 51
+2010, 7, 105, 115, 28
+2010, 8, 93, 100, 36
+2010, 9, 76, 107, 54
+2010, 10, 64, 84, 31
+2010, 11, 73, 88, 29
+2010, 12, 43, 86, 8
+2011, 1, 76, 55, 29
+2011, 2, 77, 100, 23
+2011, 3, 33, 66, 5
+2011, 4, 52, 102, 48
+2011, 5, 97, 82, 44
+2011, 6, 117, 105, 71
+2011, 7, 92, 127, 50
+2011, 8, 83, 132, 48
+2011, 9, 54, 109, 60
+2011, 10, 53, 68, 48
+2011, 11, 75, 102, 32
+2011, 12, 30, 98, 26
+2012, 1, 44, 79, 34
+2012, 2, 69, 62, 33
+2012, 3, 67, 65, 10
+2012, 4, 70, 70, 49
+2012, 5, 50, 98, 61
+2012, 6, 92, 97, 64
+2012, 7, 91, 95, 51
+2012, 8, 107, 107, 26
+2012, 9, 64, 102, 22
+2012, 10, 75, 76, 31
+2012, 11, 66, 75, 6
+2012, 12, 33, 100, 36
diff --git a/examples/rainfall/doc/src/rainfall.qdoc b/examples/rainfall/doc/src/rainfall.qdoc
index b1a4d8e0..bfe7fc36 100644
--- a/examples/rainfall/doc/src/rainfall.qdoc
+++ b/examples/rainfall/doc/src/rainfall.qdoc
@@ -1,27 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
-** This file is part of the documentation of the QtDataVis3D module.
+** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:FDL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: http://www.gnu.org/copyleft/fdl.html.
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
diff --git a/examples/rainfall/main.cpp b/examples/rainfall/main.cpp
index 47acee0b..2b9b2861 100644
--- a/examples/rainfall/main.cpp
+++ b/examples/rainfall/main.cpp
@@ -1,327 +1,26 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
-** This file is part of the documentation of the Qt Toolkit.
+** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
-** of its contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
-#include "q3dbars.h"
-#include "qdataitem.h"
-
+#include "rainfallchart.h"
#include <QGuiApplication>
-#include <QFont>
-//#include <QDebug>
using namespace QtDataVis3D;
-class RainfallChart : public QObject
-{
-public:
- explicit RainfallChart(Q3DBars *rainfall);
- ~RainfallChart();
-
- void addDataSet();
- void start();
-
-private:
- Q3DBars *m_chart;
- int m_columnCount;
- int m_rowCount;
-};
-
-RainfallChart::RainfallChart(Q3DBars *rainfall)
- : m_chart(rainfall),
- m_columnCount(12),
- m_rowCount(13)
-{
- // Set up bar specifications; make the bars as wide as they are deep,
- // and add a small space between the bars
- m_chart->setBarSpecs(QSizeF(1.0f, 1.0f), QSizeF(0.2f, 0.2f), true);
-
- // Set up sample space; make it match actual data size
- m_chart->setupSampleSpace(m_columnCount, m_rowCount,
- QStringLiteral("year"), QStringLiteral("month"),
- QStringLiteral("rainfall (in mm)"));
-
- // Set bar type to cylinder
- m_chart->setBarType(Cylinders, false);
-
- // Set shadows to medium
- m_chart->setShadowQuality(ShadowMedium);
-
- // Set font
- m_chart->setFont(QFont("Century Gothic", 40));
-
- // Set selection mode to bar and column
- //m_chart->setSelectionMode(ModeBarAndColumn);
- m_chart->setSelectionMode(ModeZoomColumn);
-
- // Set theme
- m_chart->setTheme(ThemeBlueNcs);
-
- // Set preset camera position
- m_chart->setCameraPreset(PresetIsometricRightHigh);
-
- // Disable grid
- m_chart->setGridEnabled(false);
-
- // Set window title
- m_chart->setWindowTitle(QStringLiteral("Monthly rainfall in Northern Finland (2000-2012)"));
-}
-
-RainfallChart::~RainfallChart()
-{
- delete m_chart;
-}
-
-void RainfallChart::start()
-{
- addDataSet();
-}
-
-void RainfallChart::addDataSet()
-{
- // Fill in rainfall per month from 2000 to 2012 in Northern Finland (Sodankylä, Utsjoki, Kuusamo)
- QVector< QVector<QDataItem*> > data;
- QVector<QDataItem*> row;
- // TODO: Change this example to load data from file
- // 2000
- row.append(new QDataItem(72, "mm")); //January 2000
- row.append(new QDataItem(47, "mm")); //February 2000
- row.append(new QDataItem(37, "mm")); //March 2000
- row.append(new QDataItem(79, "mm")); //April 2000
- row.append(new QDataItem(42, "mm")); //May 2000
- row.append(new QDataItem(73, "mm")); //June 2000
- row.append(new QDataItem(94, "mm")); //July 2000
- row.append(new QDataItem(37, "mm")); //August 2000
- row.append(new QDataItem(17, "mm")); //September 2000
- row.append(new QDataItem(69, "mm")); //October 2000
- row.append(new QDataItem(42, "mm")); //November 2000
- row.append(new QDataItem(42, "mm")); //December 2000
- data.append(row);
- row.clear();
- // 2001
- row.append(new QDataItem(25, "mm")); //January 2001
- row.append(new QDataItem(47, "mm")); //February 2001
- row.append(new QDataItem(20, "mm")); //March 2001
- row.append(new QDataItem(70, "mm")); //April 2001
- row.append(new QDataItem(27, "mm")); //May 2001
- row.append(new QDataItem(40, "mm")); //June 2001
- row.append(new QDataItem(123, "mm")); //July 2001
- row.append(new QDataItem(39, "mm")); //August 2001
- row.append(new QDataItem(66, "mm")); //September 2001
- row.append(new QDataItem(55, "mm")); //October 2001
- row.append(new QDataItem(29, "mm")); //November 2001
- row.append(new QDataItem(12, "mm")); //December 2001
- data.append(row);
- row.clear();
- // 2002
- row.append(new QDataItem(24, "mm")); //January 2002
- row.append(new QDataItem(45, "mm")); //February 2002
- row.append(new QDataItem(27, "mm")); //March 2002
- row.append(new QDataItem(30, "mm")); //April 2002
- row.append(new QDataItem(16, "mm")); //May 2002
- row.append(new QDataItem(98, "mm")); //June 2002
- row.append(new QDataItem(122, "mm")); //July 2002
- row.append(new QDataItem(20, "mm")); //August 2002
- row.append(new QDataItem(50, "mm")); //September 2002
- row.append(new QDataItem(24, "mm")); //October 2002
- row.append(new QDataItem(22, "mm")); //November 2002
- row.append(new QDataItem(12, "mm")); //December 2002
- data.append(row);
- row.clear();
- // 2003
- row.append(new QDataItem(43, "mm")); //January 2003
- row.append(new QDataItem(17, "mm")); //February 2003
- row.append(new QDataItem(26, "mm")); //March 2003
- row.append(new QDataItem(22, "mm")); //April 2003
- row.append(new QDataItem(60, "mm")); //May 2003
- row.append(new QDataItem(14, "mm")); //June 2003
- row.append(new QDataItem(86, "mm")); //July 2003
- row.append(new QDataItem(77, "mm")); //August 2003
- row.append(new QDataItem(69, "mm")); //September 2003
- row.append(new QDataItem(49, "mm")); //October 2003
- row.append(new QDataItem(23, "mm")); //November 2003
- row.append(new QDataItem(44, "mm")); //December 2003
- data.append(row);
- row.clear();
- // 2004
- row.append(new QDataItem(15, "mm")); //January 2004
- row.append(new QDataItem(19, "mm")); //February 2004
- row.append(new QDataItem(10, "mm")); //March 2004
- row.append(new QDataItem(11, "mm")); //April 2004
- row.append(new QDataItem(41, "mm")); //May 2004
- row.append(new QDataItem(29, "mm")); //June 2004
- row.append(new QDataItem(49, "mm")); //July 2004
- row.append(new QDataItem(72, "mm")); //August 2004
- row.append(new QDataItem(50, "mm")); //September 2004
- row.append(new QDataItem(18, "mm")); //October 2004
- row.append(new QDataItem(19, "mm")); //November 2004
- row.append(new QDataItem(40, "mm")); //December 2004
- data.append(row);
- row.clear();
- // 2005
- row.append(new QDataItem(60, "mm")); //January 2005
- row.append(new QDataItem(24, "mm")); //February 2005
- row.append(new QDataItem(12, "mm")); //March 2005
- row.append(new QDataItem(50, "mm")); //April 2005
- row.append(new QDataItem(88, "mm")); //May 2005
- row.append(new QDataItem(32, "mm")); //June 2005
- row.append(new QDataItem(76, "mm")); //July 2005
- row.append(new QDataItem(55, "mm")); //August 2005
- row.append(new QDataItem(92, "mm")); //September 2005
- row.append(new QDataItem(35, "mm")); //October 2005
- row.append(new QDataItem(105, "mm")); //November 2005
- row.append(new QDataItem(59, "mm")); //December 2005
- data.append(row);
- row.clear();
- // 2006
- row.append(new QDataItem(27, "mm")); //January 2006
- row.append(new QDataItem(18, "mm")); //February 2006
- row.append(new QDataItem(17, "mm")); //March 2006
- row.append(new QDataItem(26, "mm")); //April 2006
- row.append(new QDataItem(24, "mm")); //May 2006
- row.append(new QDataItem(18, "mm")); //June 2006
- row.append(new QDataItem(35, "mm")); //July 2006
- row.append(new QDataItem(28, "mm")); //August 2006
- row.append(new QDataItem(80, "mm")); //September 2006
- row.append(new QDataItem(52, "mm")); //October 2006
- row.append(new QDataItem(43, "mm")); //November 2006
- row.append(new QDataItem(44, "mm")); //December 2006
- data.append(row);
- row.clear();
- // 2007
- row.append(new QDataItem(41, "mm")); //January 2007
- row.append(new QDataItem(21, "mm")); //February 2007
- row.append(new QDataItem(30, "mm")); //March 2007
- row.append(new QDataItem(20, "mm")); //April 2007
- row.append(new QDataItem(53, "mm")); //May 2007
- row.append(new QDataItem(29, "mm")); //June 2007
- row.append(new QDataItem(139, "mm")); //July 2007
- row.append(new QDataItem(52, "mm")); //August 2007
- row.append(new QDataItem(51, "mm")); //September 2007
- row.append(new QDataItem(24, "mm")); //October 2007
- row.append(new QDataItem(47, "mm")); //November 2007
- row.append(new QDataItem(33, "mm")); //December 2007
- data.append(row);
- row.clear();
- // 2008
- row.append(new QDataItem(67, "mm")); //January 2008
- row.append(new QDataItem(19, "mm")); //February 2008
- row.append(new QDataItem(30, "mm")); //March 2008
- row.append(new QDataItem(31, "mm")); //April 2008
- row.append(new QDataItem(29, "mm")); //May 2008
- row.append(new QDataItem(79, "mm")); //June 2008
- row.append(new QDataItem(75, "mm")); //July 2008
- row.append(new QDataItem(99, "mm")); //August 2008
- row.append(new QDataItem(34, "mm")); //September 2008
- row.append(new QDataItem(52, "mm")); //October 2008
- row.append(new QDataItem(60, "mm")); //November 2008
- row.append(new QDataItem(20, "mm")); //December 2008
- data.append(row);
- row.clear();
- // 2009
- row.append(new QDataItem(9, "mm")); //January 2009
- row.append(new QDataItem(22, "mm")); //February 2009
- row.append(new QDataItem(11, "mm")); //March 2009
- row.append(new QDataItem(10, "mm")); //April 2009
- row.append(new QDataItem(69, "mm")); //May 2009
- row.append(new QDataItem(30, "mm")); //June 2009
- row.append(new QDataItem(78, "mm")); //July 2009
- row.append(new QDataItem(93, "mm")); //August 2009
- row.append(new QDataItem(70, "mm")); //September 2009
- row.append(new QDataItem(32, "mm")); //October 2009
- row.append(new QDataItem(56, "mm")); //November 2009
- row.append(new QDataItem(23, "mm")); //December 2009
- data.append(row);
- row.clear();
- // 2010
- row.append(new QDataItem(12, "mm")); //January 2010
- row.append(new QDataItem(28, "mm")); //February 2010
- row.append(new QDataItem(55, "mm")); //March 2010
- row.append(new QDataItem(20, "mm")); //April 2010
- row.append(new QDataItem(65, "mm")); //May 2010
- row.append(new QDataItem(26, "mm")); //June 2010
- row.append(new QDataItem(134, "mm")); //July 2010
- row.append(new QDataItem(57, "mm")); //August 2010
- row.append(new QDataItem(51, "mm")); //September 2010
- row.append(new QDataItem(53, "mm")); //October 2010
- row.append(new QDataItem(8, "mm")); //November 2010
- row.append(new QDataItem(9, "mm")); //December 2010
- data.append(row);
- row.clear();
- // 2011
- row.append(new QDataItem(34, "mm")); //January 2011
- row.append(new QDataItem(20, "mm")); //February 2011
- row.append(new QDataItem(30, "mm")); //March 2011
- row.append(new QDataItem(31, "mm")); //April 2011
- row.append(new QDataItem(42, "mm")); //May 2011
- row.append(new QDataItem(78, "mm")); //June 2011
- row.append(new QDataItem(85, "mm")); //July 2011
- row.append(new QDataItem(33, "mm")); //August 2011
- row.append(new QDataItem(42, "mm")); //September 2011
- row.append(new QDataItem(87, "mm")); //October 2011
- row.append(new QDataItem(41, "mm")); //November 2011
- row.append(new QDataItem(72, "mm")); //December 2011
- data.append(row);
- row.clear();
- // 2012
- row.append(new QDataItem(32, "mm")); //January 2012
- row.append(new QDataItem(42, "mm")); //February 2012
- row.append(new QDataItem(30, "mm")); //March 2012
- row.append(new QDataItem(50, "mm")); //April 2012
- row.append(new QDataItem(30, "mm")); //May 2012
- row.append(new QDataItem(70, "mm")); //June 2012
- row.append(new QDataItem(52, "mm")); //July 2012
- row.append(new QDataItem(20, "mm")); //August 2012
- row.append(new QDataItem(99, "mm")); //September 2012
- row.append(new QDataItem(70, "mm")); //October 2012
- row.append(new QDataItem(69, "mm")); //November 2012
- row.append(new QDataItem(49, "mm")); //December 2012
- data.append(row);
- row.clear();
- // Set up row and column names
- QVector<QString> months;
- months << "January" << "February" << "March" << "April" << "May" << "June" << "July" << "August" << "September" << "October" << "November" << "December";
- QVector<QString> years;
- years << "2000" << "2001" << "2002" << "2003" << "2004" << "2005" << "2006" << "2007" << "2008" << "2009" << "2010" << "2011" << "2012";
-
- m_chart->addDataSet(data, years, months);
-}
-
int main(int argc, char **argv)
{
QGuiApplication app(argc, argv);
diff --git a/examples/rainfall/rainfall.pro b/examples/rainfall/rainfall.pro
index 381b3402..af7f963b 100644
--- a/examples/rainfall/rainfall.pro
+++ b/examples/rainfall/rainfall.pro
@@ -2,7 +2,22 @@
error( "Couldn't find the examples.pri file!" )
}
-SOURCES += main.cpp
-QT += datavis3d
+SOURCES += main.cpp \
+ rainfallchart.cpp \
+ variantdataset.cpp \
+ variantbardataproxy.cpp \
+ variantbardatamapping.cpp \
+
+HEADERS += \
+ rainfallchart.h \
+ variantdataset.h \
+ variantbardataproxy.h \
+ variantbardatamapping.h
INSTALLS += target
+
+RESOURCES += \
+ rainfall.qrc
+
+OTHER_FILES += data/raindata.txt
+
diff --git a/examples/rainfall/rainfall.qrc b/examples/rainfall/rainfall.qrc
new file mode 100644
index 00000000..53cd4915
--- /dev/null
+++ b/examples/rainfall/rainfall.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/">
+ <file>data/raindata.txt</file>
+ </qresource>
+</RCC>
diff --git a/examples/rainfall/rainfallchart.cpp b/examples/rainfall/rainfallchart.cpp
new file mode 100644
index 00000000..f7bcd82b
--- /dev/null
+++ b/examples/rainfall/rainfallchart.cpp
@@ -0,0 +1,159 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "rainfallchart.h"
+#include <QtDataVis3D/qcategoryaxis.h>
+#include <QtDataVis3D/qvalueaxis.h>
+#include <QGuiApplication>
+#include <QFont>
+#include <QDebug>
+#include <QTextStream>
+#include <QFile>
+
+#define CHANGE_CITY_WITH_TIMER
+
+using namespace QtDataVis3D;
+
+RainfallChart::RainfallChart(Q3DBars *rainfall)
+ : m_chart(rainfall),
+ m_city(2)
+{
+ // In data file the months are in numeric format, so create custom list
+ for (int i = 1; i <= 12; i++)
+ m_numericMonths << QString::number(i);
+
+ m_columnCount = m_numericMonths.size();
+
+ m_proxy = new VariantBarDataProxy;
+ m_proxy->setItemLabelFormat(QStringLiteral(" mm"));
+ m_chart->setDataProxy(m_proxy);
+
+ updateYearsList(2000, 2012);
+
+ // Set up bar specifications; make the bars as wide as they are deep,
+ // and add a small space between the bars
+ m_chart->setBarSpecs(QSizeF(1.0f, 1.0f), QSizeF(0.2f, 0.2f), true);
+
+ // Set axis labels and titles
+ QStringList months;
+ months << "January" << "February" << "March" << "April" << "May" << "June" << "July" << "August" << "September" << "October" << "November" << "December";
+ m_chart->rowAxis()->setTitle("Year");
+ m_chart->columnAxis()->setTitle("Month");
+ m_chart->valueAxis()->setTitle(QString("rainfall (in mm) in city %1").arg(m_city - 1));
+ m_chart->rowAxis()->setCategoryLabels(m_years);
+ m_chart->columnAxis()->setCategoryLabels(months);
+
+ // Set bar type to cylinder
+ m_chart->setBarType(QDataVis::Cylinders, false);
+
+ // Set shadows to medium
+ m_chart->setShadowQuality(QDataVis::ShadowMedium);
+
+ // Set font
+ m_chart->setFont(QFont("Century Gothic", 40));
+
+ // Set selection mode to bar and column
+ //m_chart->setSelectionMode(ModeItemAndColumn);
+ m_chart->setSelectionMode(QDataVis::ModeZoomColumn);
+
+ // Set theme
+ m_chart->setTheme(QDataVis::ThemeBlueNcs);
+
+ // Set preset camera position
+ m_chart->setCameraPreset(QDataVis::PresetIsometricRightHigh);
+
+ // Disable grid
+ m_chart->setGridVisible(false);
+
+ // Set window title
+ m_chart->setWindowTitle(QStringLiteral("Monthly rainfall in various cities"));
+}
+
+RainfallChart::~RainfallChart()
+{
+ delete m_mapping;
+ delete m_dataSet;
+ delete m_chart;
+}
+
+void RainfallChart::start()
+{
+ addDataSet();
+
+#ifdef CHANGE_CITY_WITH_TIMER
+ connect(&m_timer, &QTimer::timeout, this, &RainfallChart::timeout);
+ m_timer.start(3000);
+#endif
+}
+
+void RainfallChart::timeout()
+{
+ if (++m_city > 4)
+ m_city = 2;
+
+ m_proxy->mapping()->setValueIndex(m_city);
+ m_chart->valueAxis()->setTitle(QString("rainfall (in mm) in city %1").arg(m_city - 1));
+}
+
+void RainfallChart::updateYearsList(int start, int end)
+{
+ m_years.clear();
+ for (int i = start; i <= end; i++)
+ m_years << QString::number(i);
+
+ m_rowCount = m_years.size();
+
+ // Set up sample space; make it match actual resolved data size
+ m_chart->setupSampleSpace(m_rowCount, m_columnCount);
+}
+
+void RainfallChart::addDataSet()
+{
+ m_dataSet = new VariantDataSet;
+ VariantDataItemList *itemList = new VariantDataItemList;
+ QTextStream stream;
+ QFile dataFile(":/data/raindata.txt");
+ if (dataFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ stream.setDevice(&dataFile);
+ while (!stream.atEnd()) {
+ QString line = stream.readLine();
+ if (line.startsWith("#"))
+ continue;
+ QStringList strList = line.split(",", QString::SkipEmptyParts);
+ if (strList.size() < 5) {
+ qWarning() << "Invalid row read from data:" << line;
+ continue;
+ }
+ VariantDataItem *newItem = new VariantDataItem;
+ for (int i = 0; i < 2; i++)
+ newItem->append(strList.at(i).trimmed());
+ for (int i = 2; i < 5; i++)
+ newItem->append(strList.at(i).trimmed().toDouble());
+ itemList->append(newItem);
+ }
+ } else {
+ qWarning() << "Unable to open data file:" << dataFile.fileName();
+ }
+
+ m_dataSet->addItems(itemList);
+
+ m_proxy->setDataSet(m_dataSet);
+
+ m_mapping = new VariantBarDataMapping(0, 1, m_city, m_years, m_numericMonths);
+ m_proxy->setMapping(m_mapping);
+}
diff --git a/examples/rainfall/rainfallchart.h b/examples/rainfall/rainfallchart.h
new file mode 100644
index 00000000..585f2bd0
--- /dev/null
+++ b/examples/rainfall/rainfallchart.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef RAINFALLCHART_H
+#define RAINFALLCHART_H
+
+#include "variantbardataproxy.h"
+#include <QtDataVis3D/q3dbars.h>
+#include <QTimer>
+
+using namespace QtDataVis3D;
+
+class RainfallChart : public QObject
+{
+ Q_OBJECT
+public:
+ explicit RainfallChart(Q3DBars *rainfall);
+ ~RainfallChart();
+
+ void addDataSet();
+ void start();
+
+public slots:
+ void timeout();
+private:
+
+ void updateYearsList(int start, int end);
+ Q3DBars *m_chart;
+ int m_columnCount;
+ int m_rowCount;
+ QStringList m_years;
+ QStringList m_numericMonths;
+ QTimer m_timer;
+ VariantBarDataProxy *m_proxy;
+ int m_city;
+ VariantBarDataMapping *m_mapping;
+ VariantDataSet *m_dataSet;
+};
+
+
+#endif // RAINFALLCHART_H
diff --git a/examples/rainfall/variantbardatamapping.cpp b/examples/rainfall/variantbardatamapping.cpp
new file mode 100644
index 00000000..288a3b55
--- /dev/null
+++ b/examples/rainfall/variantbardatamapping.cpp
@@ -0,0 +1,133 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "variantbardatamapping.h"
+
+VariantBarDataMapping::VariantBarDataMapping()
+ : QObject(0),
+ m_rowIndex(0),
+ m_columnIndex(1),
+ m_valueIndex(2)
+{
+}
+
+VariantBarDataMapping::VariantBarDataMapping(const VariantBarDataMapping &other)
+ : QObject(0),
+ m_rowIndex(0),
+ m_columnIndex(1),
+ m_valueIndex(2)
+{
+ operator=(other);
+}
+
+VariantBarDataMapping::VariantBarDataMapping(int rowIndex, int columnIndex, int valueIndex,
+ const QStringList &rowCategories,
+ const QStringList &columnCategories)
+ : QObject(0),
+ m_rowIndex(0),
+ m_columnIndex(1),
+ m_valueIndex(2)
+{
+ m_rowIndex = rowIndex;
+ m_columnIndex = columnIndex;
+ m_valueIndex = valueIndex;
+ m_rowCategories = rowCategories;
+ m_columnCategories = columnCategories;
+}
+
+VariantBarDataMapping::~VariantBarDataMapping()
+{
+}
+
+VariantBarDataMapping &VariantBarDataMapping::operator=(const VariantBarDataMapping &other)
+{
+ m_rowIndex = other.m_rowIndex;
+ m_columnIndex = other.m_columnIndex;
+ m_valueIndex = other.m_valueIndex;
+ m_rowCategories = other.m_rowCategories;
+ m_columnCategories = other.m_columnCategories;
+
+ return *this;
+}
+
+void VariantBarDataMapping::setRowIndex(int index)
+{
+ m_rowIndex = index;
+ emit mappingChanged();
+}
+
+int VariantBarDataMapping::rowIndex() const
+{
+ return m_rowIndex;
+}
+
+void VariantBarDataMapping::setColumnIndex(int index)
+{
+ m_columnIndex = index;
+ emit mappingChanged();
+}
+
+int VariantBarDataMapping::columnIndex() const
+{
+ return m_columnIndex;
+}
+
+void VariantBarDataMapping::setValueIndex(int index)
+{
+ m_valueIndex = index;
+ emit mappingChanged();
+}
+
+int VariantBarDataMapping::valueIndex() const
+{
+ return m_valueIndex;
+}
+
+void VariantBarDataMapping::setRowCategories(const QStringList &categories)
+{
+ m_rowCategories = categories;
+ emit mappingChanged();
+}
+
+const QStringList &VariantBarDataMapping::rowCategories() const
+{
+ return m_rowCategories;
+}
+
+void VariantBarDataMapping::setColumnCategories(const QStringList &categories)
+{
+ m_columnCategories = categories;
+ emit mappingChanged();
+}
+
+const QStringList &VariantBarDataMapping::columnCategories() const
+{
+ return m_columnCategories;
+}
+
+void VariantBarDataMapping::remap(int rowIndex, int columnIndex, int valueIndex,
+ const QStringList &rowCategories,
+ const QStringList &columnCategories)
+{
+ m_rowIndex = rowIndex;
+ m_columnIndex = columnIndex;
+ m_valueIndex = valueIndex;
+ m_rowCategories = rowCategories;
+ m_columnCategories = columnCategories;
+ emit mappingChanged();
+}
diff --git a/examples/rainfall/variantbardatamapping.h b/examples/rainfall/variantbardatamapping.h
new file mode 100644
index 00000000..616ee563
--- /dev/null
+++ b/examples/rainfall/variantbardatamapping.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef VARIANTBARDATAMAPPING_H
+#define VARIANTBARDATAMAPPING_H
+
+#include "qdatavis3denums.h"
+#include <QStringList>
+
+using namespace QtDataVis3D;
+
+class VariantBarDataMapping : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(int rowIndex READ rowIndex WRITE setRowIndex)
+ Q_PROPERTY(int columnIndex READ columnIndex WRITE setColumnIndex)
+ Q_PROPERTY(int valueIndex READ valueIndex WRITE setValueIndex)
+ Q_PROPERTY(QStringList rowCategories READ rowCategories WRITE setRowCategories)
+ Q_PROPERTY(QStringList columnCategories READ columnCategories WRITE setColumnCategories)
+public:
+ explicit VariantBarDataMapping();
+ VariantBarDataMapping(const VariantBarDataMapping &other);
+ VariantBarDataMapping(int rowIndex, int columnIndex, int valueIndex,
+ const QStringList &rowCategories,
+ const QStringList &columnCategories);
+ virtual ~VariantBarDataMapping();
+
+ VariantBarDataMapping &operator=(const VariantBarDataMapping &other);
+
+ void setRowIndex(int index);
+ int rowIndex() const;
+ void setColumnIndex(int index);
+ int columnIndex() const;
+ void setValueIndex(int index);
+ int valueIndex() const;
+
+ void setRowCategories(const QStringList &categories);
+ const QStringList &rowCategories() const;
+ void setColumnCategories(const QStringList &categories);
+ const QStringList &columnCategories() const;
+
+ void remap(int rowIndex, int columnIndex, int valueIndex,
+ const QStringList &rowCategories,
+ const QStringList &columnCategories);
+signals:
+ void mappingChanged();
+
+private:
+ // Indexes of the mapped items in the VariantDataItem
+ int m_rowIndex;
+ int m_columnIndex;
+ int m_valueIndex;
+
+ // For row/column items, sort items into these categories. Other categories are ignored.
+ QStringList m_rowCategories;
+ QStringList m_columnCategories;
+};
+
+#endif
diff --git a/examples/rainfall/variantbardataproxy.cpp b/examples/rainfall/variantbardataproxy.cpp
new file mode 100644
index 00000000..79b5c67f
--- /dev/null
+++ b/examples/rainfall/variantbardataproxy.cpp
@@ -0,0 +1,128 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "variantbardataproxy.h"
+
+using namespace QtDataVis3D;
+
+VariantBarDataProxy::VariantBarDataProxy() :
+ QBarDataProxy()
+{
+}
+
+VariantBarDataProxy::VariantBarDataProxy(VariantDataSet *newSet,
+ VariantBarDataMapping *mapping) :
+ QBarDataProxy()
+{
+ setDataSet(newSet);
+ setMapping(mapping);
+}
+
+VariantBarDataProxy::~VariantBarDataProxy()
+{
+}
+
+void VariantBarDataProxy::setDataSet(VariantDataSet *newSet)
+{
+ if (!m_dataSet.isNull())
+ QObject::disconnect(m_dataSet.data(), 0, this, 0);
+
+ m_dataSet = newSet;
+
+ if (!m_dataSet.isNull()) {
+ QObject::connect(m_dataSet.data(), &VariantDataSet::itemsAdded, this, &VariantBarDataProxy::handleItemsAdded);
+ QObject::connect(m_dataSet.data(), &VariantDataSet::dataCleared, this, &VariantBarDataProxy::handleDataCleared);
+ }
+ resolveDataSet();
+}
+
+VariantDataSet *VariantBarDataProxy::dataSet()
+{
+ return m_dataSet.data();
+}
+
+void VariantBarDataProxy::setMapping(VariantBarDataMapping *mapping)
+{
+ if (!m_mapping.isNull())
+ QObject::disconnect(m_mapping.data(), &VariantBarDataMapping::mappingChanged, this, &VariantBarDataProxy::handleMappingChanged);
+
+ m_mapping = mapping;
+
+ if (!m_mapping.isNull())
+ QObject::connect(m_mapping.data(), &VariantBarDataMapping::mappingChanged, this, &VariantBarDataProxy::handleMappingChanged);
+
+ resolveDataSet();
+}
+
+VariantBarDataMapping *VariantBarDataProxy::mapping()
+{
+ return m_mapping.data();
+}
+
+void VariantBarDataProxy::handleItemsAdded(int index, int count)
+{
+ Q_UNUSED(index)
+ Q_UNUSED(count)
+
+ // Resolve new items
+ resolveDataSet(); // TODO Resolving entire dataset is inefficient
+}
+
+void VariantBarDataProxy::handleDataCleared()
+{
+ // Data cleared, reset array
+ resetArray(0);
+}
+
+void VariantBarDataProxy::handleMappingChanged()
+{
+ resolveDataSet();
+}
+
+// Resolve entire dataset into QBarDataArray.
+void VariantBarDataProxy::resolveDataSet()
+{
+ if (m_dataSet.isNull() || m_mapping.isNull() || !m_mapping->rowCategories().size() || !m_mapping->columnCategories().size()) {
+ resetArray(0);
+ return;
+ }
+ const VariantDataItemList &itemList = m_dataSet->itemList();
+
+ int rowIndex = m_mapping->rowIndex();
+ int columnIndex = m_mapping->columnIndex();
+ int valueIndex = m_mapping->valueIndex();
+ const QStringList &rowList = m_mapping->rowCategories();
+ const QStringList &columnList = m_mapping->columnCategories();
+
+ // Sort values into rows and columns
+ typedef QHash<QString, qreal> ColumnValueMap;
+ QHash <QString, ColumnValueMap> itemValueMap;
+ foreach (const VariantDataItem *item, itemList)
+ itemValueMap[item->at(rowIndex).toString()][item->at(columnIndex).toString()] = item->at(valueIndex).toReal();
+
+ // Create new data array from itemValueMap
+ QBarDataArray *newProxyArray = new QBarDataArray;
+ foreach (QString rowKey, rowList) {
+ QBarDataRow *newProxyRow = new QBarDataRow(columnList.size());
+ for (int i = 0; i < columnList.size(); i++)
+ (*newProxyRow)[i].setValue(itemValueMap[rowKey][columnList.at(i)]);
+ newProxyArray->append(newProxyRow);
+ }
+
+ resetArray(newProxyArray);
+}
diff --git a/examples/rainfall/variantbardataproxy.h b/examples/rainfall/variantbardataproxy.h
new file mode 100644
index 00000000..2c80c0b1
--- /dev/null
+++ b/examples/rainfall/variantbardataproxy.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef VARIANTBARDATAPROXY_H
+#define VARIANTBARDATAPROXY_H
+
+#include "qbardataproxy.h"
+#include "variantdataset.h"
+#include "variantbardatamapping.h"
+#include <QStringList>
+#include <QMap>
+#include <QPointer>
+
+using namespace QtDataVis3D;
+
+class VariantBarDataProxy : public QBarDataProxy
+{
+ Q_OBJECT
+
+public:
+ explicit VariantBarDataProxy();
+ explicit VariantBarDataProxy(VariantDataSet *newSet, VariantBarDataMapping *mapping);
+ virtual ~VariantBarDataProxy();
+
+ // Doesn't gain ownership of the dataset, but does connect to it to listen for data changes.
+ void setDataSet(VariantDataSet *newSet);
+ VariantDataSet *dataSet();
+
+ // Map key (row, column, value) to value index in data item (VariantItem).
+ // Doesn't gain ownership of mapping, but does connect to it to listen for mapping changes.
+ // Modifying mapping that is set to proxy will trigger dataset re-resolving.
+ void setMapping(VariantBarDataMapping *mapping);
+ VariantBarDataMapping *mapping();
+
+public slots:
+ void handleItemsAdded(int index, int count);
+ void handleDataCleared();
+ void handleMappingChanged();
+
+private:
+ void resolveDataSet();
+
+ QPointer<VariantDataSet> m_dataSet;
+ QPointer<VariantBarDataMapping> m_mapping;
+
+ Q_DISABLE_COPY(VariantBarDataProxy)
+
+ friend class VariantBarDataProxy;
+};
+
+#endif
diff --git a/examples/rainfall/variantdataset.cpp b/examples/rainfall/variantdataset.cpp
new file mode 100644
index 00000000..3fe4fa6b
--- /dev/null
+++ b/examples/rainfall/variantdataset.cpp
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "variantdataset.h"
+
+VariantDataSet::VariantDataSet()
+ : QObject(0)
+{
+}
+
+VariantDataSet::~VariantDataSet()
+{
+ clear();
+}
+
+void VariantDataSet::clear()
+{
+ foreach (VariantDataItem *item, m_variantData) {
+ item->clear();
+ delete item;
+ }
+ m_variantData.clear();
+ emit dataCleared();
+}
+
+int VariantDataSet::addItem(VariantDataItem *item)
+{
+ m_variantData.append(item);
+ int addIndex = m_variantData.size();
+
+ emit itemsAdded(addIndex, 1);
+ return addIndex;
+}
+
+int VariantDataSet::addItems(VariantDataItemList *itemList)
+{
+ int newCount = itemList->size();
+ int addIndex = m_variantData.size();
+ m_variantData.append(*itemList);
+ delete itemList;
+ emit itemsAdded(addIndex, newCount);
+ return addIndex;
+}
+
+const VariantDataItemList &VariantDataSet::itemList() const
+{
+ return m_variantData;
+}
diff --git a/examples/rainfall/variantdataset.h b/examples/rainfall/variantdataset.h
new file mode 100644
index 00000000..f3965978
--- /dev/null
+++ b/examples/rainfall/variantdataset.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef VARIANTDATASET_H
+#define VARIANTDATASET_H
+
+#include "qdatavis3denums.h"
+#include <QScopedPointer>
+#include <QVariantList>
+
+using namespace QtDataVis3D;
+
+typedef QVariantList VariantDataItem;
+typedef QList<VariantDataItem *> VariantDataItemList;
+
+class VariantDataSet : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit VariantDataSet();
+ ~VariantDataSet();
+
+ void clear();
+
+ int addItem(VariantDataItem *item);
+ int addItems(VariantDataItemList *itemList);
+
+ const VariantDataItemList &itemList() const;
+
+signals:
+ void itemsAdded(int index, int count);
+ void dataCleared();
+
+private:
+ VariantDataItemList m_variantData;
+
+ Q_DISABLE_COPY(VariantDataSet)
+};
+
+#endif
diff --git a/examples/scatterchart/doc/src/scatterchart.qdoc b/examples/scatterchart/doc/src/scatterchart.qdoc
new file mode 100644
index 00000000..6e8dcd03
--- /dev/null
+++ b/examples/scatterchart/doc/src/scatterchart.qdoc
@@ -0,0 +1,29 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+/*!
+ \example scatterchart
+ \title Scatter Chart Example
+
+ The scatterchart example shows how to make a simple 3D scatter chart using Q3DScatter and
+ combining the use of widgets for adjusting several adjustable qualities.
+
+ \image scatterchart-example.png
+
+ TODO
+*/
diff --git a/examples/scatterchart/main.cpp b/examples/scatterchart/main.cpp
new file mode 100644
index 00000000..ab6eb313
--- /dev/null
+++ b/examples/scatterchart/main.cpp
@@ -0,0 +1,198 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "scatterchart.h"
+
+#include <QApplication>
+#include <QWidget>
+#include <QHBoxLayout>
+#include <QVBoxLayout>
+#include <QPushButton>
+#include <QCheckBox>
+#include <QSlider>
+#include <QComboBox>
+#include <QFontComboBox>
+#include <QLabel>
+#include <QScreen>
+#include <QFontDatabase>
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+
+ QWidget *widget = new QWidget;
+ QHBoxLayout *hLayout = new QHBoxLayout(widget);
+ QVBoxLayout *vLayout = new QVBoxLayout();
+
+ Q3DScatter *chart = new Q3DScatter();
+ QSize screenSize = chart->screen()->size();
+
+ QWidget *container = QWidget::createWindowContainer(chart);
+ container->setMinimumSize(QSize(screenSize.width() / 2, screenSize.height() / 2));
+ container->setMaximumSize(screenSize);
+ container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ container->setFocusPolicy(Qt::StrongFocus);
+
+ widget->setWindowTitle(QStringLiteral("values of some things in something"));
+
+ hLayout->addWidget(container, 1);
+ hLayout->addLayout(vLayout);
+
+ QPushButton *themeButton = new QPushButton(widget);
+ themeButton->setText(QStringLiteral("Change theme"));
+
+ QPushButton *labelButton = new QPushButton(widget);
+ labelButton->setText(QStringLiteral("Change label style"));
+
+ QPushButton *styleButton = new QPushButton(widget);
+ styleButton->setText(QStringLiteral("Change item style"));
+
+ QPushButton *cameraButton = new QPushButton(widget);
+ cameraButton->setText(QStringLiteral("Change camera preset"));
+
+ QPushButton *clearButton = new QPushButton(widget);
+ clearButton->setText(QStringLiteral("Clear chart"));
+
+ QPushButton *addOneButton = new QPushButton(widget);
+ addOneButton->setText(QStringLiteral("Add item"));
+
+ QPushButton *addBunchButton = new QPushButton(widget);
+ addBunchButton->setText(QStringLiteral("Add bunch of items"));
+
+ QPushButton *insertOneButton = new QPushButton(widget);
+ insertOneButton->setText(QStringLiteral("Insert item"));
+
+ QPushButton *insertBunchButton = new QPushButton(widget);
+ insertBunchButton->setText(QStringLiteral("Insert bunch of items"));
+
+ QPushButton *changeOneButton = new QPushButton(widget);
+ changeOneButton->setText(QStringLiteral("Change item"));
+
+ QPushButton *changeBunchButton = new QPushButton(widget);
+ changeBunchButton->setText(QStringLiteral("Change bunch of items"));
+
+ QPushButton *removeOneButton = new QPushButton(widget);
+ removeOneButton->setText(QStringLiteral("Remove item"));
+
+ QPushButton *removeBunchButton = new QPushButton(widget);
+ removeBunchButton->setText(QStringLiteral("Remove bunch of items"));
+
+ QPushButton *startTimerButton = new QPushButton(widget);
+ startTimerButton->setText(QStringLiteral("Start/stop timer"));
+
+ QCheckBox *backgroundCheckBox = new QCheckBox(widget);
+ backgroundCheckBox->setText(QStringLiteral("Show background"));
+ backgroundCheckBox->setChecked(true);
+
+ QCheckBox *gridCheckBox = new QCheckBox(widget);
+ gridCheckBox->setText(QStringLiteral("Show grid"));
+ gridCheckBox->setChecked(true);
+
+ QComboBox *shadowQuality = new QComboBox(widget);
+ shadowQuality->addItem(QStringLiteral("None"));
+ shadowQuality->addItem(QStringLiteral("Low"));
+ shadowQuality->addItem(QStringLiteral("Medium"));
+ shadowQuality->addItem(QStringLiteral("High"));
+ shadowQuality->setCurrentIndex(1);
+
+ QFontComboBox *fontList = new QFontComboBox(widget);
+
+ QSlider *fontSizeSlider = new QSlider(Qt::Horizontal, widget);
+ fontSizeSlider->setTickInterval(1);
+ fontSizeSlider->setMinimum(1);
+ fontSizeSlider->setValue(30);
+ fontSizeSlider->setMaximum(200);
+
+ vLayout->addWidget(themeButton, 0, Qt::AlignTop);
+ vLayout->addWidget(labelButton, 0, Qt::AlignTop);
+ vLayout->addWidget(styleButton, 0, Qt::AlignTop);
+ vLayout->addWidget(cameraButton, 0, Qt::AlignTop);
+ vLayout->addWidget(clearButton, 0, Qt::AlignTop);
+ vLayout->addWidget(addOneButton, 0, Qt::AlignTop);
+ vLayout->addWidget(addBunchButton, 0, Qt::AlignTop);
+ vLayout->addWidget(insertOneButton, 0, Qt::AlignTop);
+ vLayout->addWidget(insertBunchButton, 0, Qt::AlignTop);
+ vLayout->addWidget(changeOneButton, 0, Qt::AlignTop);
+ vLayout->addWidget(changeBunchButton, 0, Qt::AlignTop);
+ vLayout->addWidget(removeOneButton, 0, Qt::AlignTop);
+ vLayout->addWidget(removeBunchButton, 0, Qt::AlignTop);
+ vLayout->addWidget(startTimerButton, 0, Qt::AlignTop);
+ vLayout->addWidget(backgroundCheckBox);
+ vLayout->addWidget(gridCheckBox);
+ vLayout->addWidget(new QLabel(QStringLiteral("Adjust shadow quality")));
+ vLayout->addWidget(shadowQuality);
+ vLayout->addWidget(new QLabel(QStringLiteral("Change font")));
+ vLayout->addWidget(fontList);
+ vLayout->addWidget(new QLabel(QStringLiteral("Adjust font size")));
+ vLayout->addWidget(fontSizeSlider, 1, Qt::AlignTop);
+
+ widget->show();
+
+ ScatterDataModifier *modifier = new ScatterDataModifier(chart);
+
+ QObject::connect(fontSizeSlider, &QSlider::valueChanged, modifier,
+ &ScatterDataModifier::changeFontSize);
+
+ QObject::connect(styleButton, &QPushButton::clicked, modifier,
+ &ScatterDataModifier::changeStyle);
+ QObject::connect(cameraButton, &QPushButton::clicked, modifier,
+ &ScatterDataModifier::changePresetCamera);
+ QObject::connect(clearButton, &QPushButton::clicked, modifier,
+ &ScatterDataModifier::clear);
+ QObject::connect(addOneButton, &QPushButton::clicked, modifier,
+ &ScatterDataModifier::addOne);
+ QObject::connect(addBunchButton, &QPushButton::clicked, modifier,
+ &ScatterDataModifier::addBunch);
+ QObject::connect(insertOneButton, &QPushButton::clicked, modifier,
+ &ScatterDataModifier::insertOne);
+ QObject::connect(insertBunchButton, &QPushButton::clicked, modifier,
+ &ScatterDataModifier::insertBunch);
+ QObject::connect(changeOneButton, &QPushButton::clicked, modifier,
+ &ScatterDataModifier::changeOne);
+ QObject::connect(changeBunchButton, &QPushButton::clicked, modifier,
+ &ScatterDataModifier::changeBunch);
+ QObject::connect(removeOneButton, &QPushButton::clicked, modifier,
+ &ScatterDataModifier::removeOne);
+ QObject::connect(removeBunchButton, &QPushButton::clicked, modifier,
+ &ScatterDataModifier::removeBunch);
+ QObject::connect(startTimerButton, &QPushButton::clicked, modifier,
+ &ScatterDataModifier::startStopTimer);
+ QObject::connect(themeButton, &QPushButton::clicked, modifier,
+ &ScatterDataModifier::changeTheme);
+ QObject::connect(labelButton, &QPushButton::clicked, modifier,
+ &ScatterDataModifier::changeTransparency);
+
+ QObject::connect(shadowQuality, SIGNAL(currentIndexChanged(int)), modifier,
+ SLOT(changeShadowQuality(int)));
+ QObject::connect(modifier, &ScatterDataModifier::shadowQualityChanged, shadowQuality,
+ &QComboBox::setCurrentIndex);
+ QObject::connect(chart, &Q3DScatter::shadowQualityChanged, modifier,
+ &ScatterDataModifier::shadowQualityUpdatedByVisual);
+
+ QObject::connect(fontList, &QFontComboBox::currentFontChanged, modifier,
+ &ScatterDataModifier::changeFont);
+
+ QObject::connect(backgroundCheckBox, &QCheckBox::stateChanged, modifier,
+ &ScatterDataModifier::setBackgroundEnabled);
+ QObject::connect(gridCheckBox, &QCheckBox::stateChanged, modifier,
+ &ScatterDataModifier::setGridEnabled);
+
+ modifier->start();
+
+ return app.exec();
+}
diff --git a/examples/scatterchart/scatterchart.cpp b/examples/scatterchart/scatterchart.cpp
new file mode 100644
index 00000000..ac8676b5
--- /dev/null
+++ b/examples/scatterchart/scatterchart.cpp
@@ -0,0 +1,325 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "scatterchart.h"
+#include <QtDataVis3D/qscatterdataproxy.h>
+#include <QtDataVis3D/qvalueaxis.h>
+#include <qmath.h>
+using namespace QtDataVis3D;
+
+//#define RANDOM_SCATTER
+
+const int numberOfItems = 10000;
+
+ScatterDataModifier::ScatterDataModifier(Q3DScatter *scatter)
+ : m_chart(scatter),
+ m_fontSize(30.0f)
+{
+ m_chart->setFontSize(m_fontSize);
+ m_chart->setObjectType(QDataVis::Spheres, true);
+ m_chart->setTheme(QDataVis::ThemeBrownSand);
+ m_chart->setShadowQuality(QDataVis::ShadowHigh);
+
+ QScatterDataProxy *proxy = new QScatterDataProxy;
+ m_chart->setDataProxy(proxy);
+
+ connect(&m_timer, &QTimer::timeout, this, &ScatterDataModifier::timeout);
+}
+
+ScatterDataModifier::~ScatterDataModifier()
+{
+ delete m_chart;
+}
+
+void ScatterDataModifier::start()
+{
+ addData();
+}
+
+void ScatterDataModifier::addData()
+{
+ // Add labels
+ m_chart->valueAxisX()->setTitle("Somethings");
+ m_chart->valueAxisY()->setTitle("Values");
+ m_chart->valueAxisZ()->setTitle("Others");
+ m_chart->valueAxisX()->setRange(-50.0, 50.0);
+ m_chart->valueAxisY()->setRange(-1.0, 1.0);
+ m_chart->valueAxisZ()->setRange(-50.0, 50.0);
+
+ QScatterDataArray *dataArray = new QScatterDataArray;
+ dataArray->resize(numberOfItems);
+ QScatterDataItem *ptrToDataArray = &dataArray->first();
+
+#if RANDOM_SCATTER
+ for (int i = 0; i < numberOfItems; i++) {
+ ptrToDataArray->setPosition(randVector());
+ ptrToDataArray++;
+ }
+#else
+ float limit = qSqrt(numberOfItems) / 2.0f;
+ for (float i = -limit; i < limit; i++) {
+ for (float j = -limit; j < limit; j++) {
+ ptrToDataArray->setPosition(QVector3D(i, qCos(qDegreesToRadians((i * j) / 7.5)), j));
+ ptrToDataArray++;
+ }
+ }
+#endif
+
+ static_cast<QScatterDataProxy *>(m_chart->dataProxy())->resetArray(dataArray);
+}
+
+void ScatterDataModifier::changeStyle()
+{
+ static int model = 0;
+ switch (model) {
+ case 0:
+ m_chart->setObjectType(QDataVis::Dots, false);
+ break;
+ case 1:
+ m_chart->setObjectType(QDataVis::Dots, true);
+ break;
+ case 2:
+ m_chart->setObjectType(QDataVis::Spheres, false);
+ break;
+ case 3:
+ m_chart->setObjectType(QDataVis::Spheres, true);
+ break;
+ }
+ model++;
+ if (model > 3)
+ model = 0;
+}
+
+void ScatterDataModifier::changePresetCamera()
+{
+ static int preset = QDataVis::PresetFrontLow;
+
+ m_chart->setCameraPreset((QDataVis::CameraPreset)preset);
+
+ if (++preset > QDataVis::PresetDirectlyAboveCCW45)
+ preset = QDataVis::PresetFrontLow;
+}
+
+void ScatterDataModifier::changeTheme()
+{
+ static int theme = QDataVis::ThemeSystem;
+
+ m_chart->setTheme((QDataVis::ColorTheme)theme);
+
+ if (++theme > QDataVis::ThemeLight)
+ theme = QDataVis::ThemeSystem;
+}
+
+void ScatterDataModifier::changeTransparency()
+{
+ static int transparency = QDataVis::TransparencyNone;
+
+ m_chart->setLabelTransparency((QDataVis::LabelTransparency)transparency);
+
+ if (++transparency > QDataVis::TransparencyNoBackground)
+ transparency = QDataVis::TransparencyNone;
+}
+
+void ScatterDataModifier::changeFont(const QFont &font)
+{
+ QFont newFont = font;
+ newFont.setPointSizeF(m_fontSize);
+ m_chart->setFont(newFont);
+}
+
+void ScatterDataModifier::changeFontSize(int fontsize)
+{
+ m_fontSize = fontsize;
+ m_chart->setFontSize((GLfloat)m_fontSize);
+}
+
+void ScatterDataModifier::shadowQualityUpdatedByVisual(QDataVis::ShadowQuality sq)
+{
+ int quality = 0;
+ switch (sq) {
+ case QDataVis::ShadowLow:
+ quality = 1;
+ break;
+ case QDataVis::ShadowMedium:
+ quality = 2;
+ break;
+ case QDataVis::ShadowHigh:
+ quality = 3;
+ break;
+ }
+
+ // Updates the UI component to show correct shadow quality
+ emit shadowQualityChanged(quality);
+}
+
+void ScatterDataModifier::clear()
+{
+ m_chart->dataProxy()->resetArray(0);
+ qDebug() << m_loopCounter << "Cleared array";
+}
+
+void ScatterDataModifier::addOne()
+{
+ QScatterDataItem item(randVector());
+ int addIndex = m_chart->dataProxy()->addItem(item);
+ qDebug() << m_loopCounter << "added one to index:" << addIndex << "array size:" << m_chart->dataProxy()->array()->size();
+}
+
+void ScatterDataModifier::addBunch()
+{
+ QScatterDataArray items(100);
+ for (int i = 0; i < items.size(); i++)
+ items[i].setPosition(randVector());
+ int addIndex = m_chart->dataProxy()->addItems(items);
+ qDebug() << m_loopCounter << "added bunch to index:" << addIndex << "array size:" << m_chart->dataProxy()->array()->size();
+}
+
+void ScatterDataModifier::insertOne()
+{
+ QScatterDataItem item(randVector());
+ m_chart->dataProxy()->insertItem(0, item);
+ qDebug() << m_loopCounter << "Inserted one, array size:" << m_chart->dataProxy()->array()->size();
+}
+
+void ScatterDataModifier::insertBunch()
+{
+ QScatterDataArray items(100);
+ for (int i = 0; i < items.size(); i++)
+ items[i].setPosition(randVector());
+ m_chart->dataProxy()->insertItems(0, items);
+ qDebug() << m_loopCounter << "Inserted bunch, array size:" << m_chart->dataProxy()->array()->size();
+}
+
+void ScatterDataModifier::changeOne()
+{
+ if (m_chart->dataProxy()->array()->size()) {
+ QScatterDataItem item(randVector());
+ m_chart->dataProxy()->setItem(0, item);
+ qDebug() << m_loopCounter << "Changed one, array size:" << m_chart->dataProxy()->array()->size();
+ }
+}
+
+void ScatterDataModifier::changeBunch()
+{
+ if (m_chart->dataProxy()->array()->size()) {
+ int amount = qMin(m_chart->dataProxy()->array()->size(), 100);
+ QScatterDataArray items(amount);
+ for (int i = 0; i < items.size(); i++)
+ items[i].setPosition(randVector());
+ m_chart->dataProxy()->setItems(0, items);
+ qDebug() << m_loopCounter << "Changed bunch, array size:" << m_chart->dataProxy()->array()->size();
+ }
+}
+
+void ScatterDataModifier::removeOne()
+{
+ m_chart->dataProxy()->removeItems(0, 1);
+ qDebug() << m_loopCounter << "Removed one, array size:" << m_chart->dataProxy()->array()->size();
+}
+
+void ScatterDataModifier::removeBunch()
+{
+ m_chart->dataProxy()->removeItems(0, 100);
+ qDebug() << m_loopCounter << "Removed bunch, array size:" << m_chart->dataProxy()->array()->size();
+}
+
+void ScatterDataModifier::timeout()
+{
+ int doWhat = rand() % 8;
+ if (!(rand() % 100))
+ doWhat = -1;
+
+ switch (doWhat) {
+ case 0:
+ addOne();
+ break;
+ case 1:
+ addBunch();
+ break;
+ case 2:
+ insertOne();
+ break;
+ case 3:
+ insertBunch();
+ break;
+ case 4:
+ changeOne();
+ break;
+ case 5:
+ changeBunch();
+ break;
+ case 6:
+ removeOne();
+ break;
+ case 7:
+ removeBunch();
+ break;
+ default:
+ clear();
+ break;
+ }
+
+ m_loopCounter++;
+}
+
+void ScatterDataModifier::startStopTimer()
+{
+ if (m_timer.isActive()) {
+ m_timer.stop();
+ } else {
+ clear();
+ m_loopCounter = 0;
+ m_timer.start(0);
+ }
+}
+
+void ScatterDataModifier::changeShadowQuality(int quality)
+{
+ QDataVis::ShadowQuality sq = QDataVis::ShadowNone;
+ switch (quality) {
+ case 1:
+ sq = QDataVis::ShadowLow;
+ break;
+ case 2:
+ sq = QDataVis::ShadowMedium;
+ break;
+ case 3:
+ sq = QDataVis::ShadowHigh;
+ break;
+ }
+ m_chart->setShadowQuality(sq);
+ emit shadowQualityChanged(quality);
+}
+
+void ScatterDataModifier::setBackgroundEnabled(int enabled)
+{
+ m_chart->setBackgroundVisible((bool)enabled);
+}
+
+void ScatterDataModifier::setGridEnabled(int enabled)
+{
+ m_chart->setGridVisible((bool)enabled);
+}
+
+QVector3D ScatterDataModifier::randVector()
+{
+ return QVector3D(
+ (float)(rand() % 100) / 2.0f - (float)(rand() % 100) / 2.0f,
+ (float)(rand() % 100) / 100.0f - (float)(rand() % 100) / 100.0f,
+ (float)(rand() % 100) / 2.0f - (float)(rand() % 100) / 2.0f);
+}
diff --git a/examples/scatterchart/scatterchart.h b/examples/scatterchart/scatterchart.h
new file mode 100644
index 00000000..8500ef29
--- /dev/null
+++ b/examples/scatterchart/scatterchart.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef SCATTERDATAMODIFIER_H
+#define SCATTERDATAMODIFIER_H
+
+#include <QtDataVis3D/q3dscatter.h>
+
+#include <QFont>
+#include <QDebug>
+#include <QTimer>
+
+using namespace QtDataVis3D;
+
+class ScatterDataModifier : public QObject
+{
+ Q_OBJECT
+public:
+ explicit ScatterDataModifier(Q3DScatter *scatter);
+ ~ScatterDataModifier();
+
+ void addData();
+ void changeStyle();
+ void changePresetCamera();
+ void changeTheme();
+ void changeTransparency();
+ void changeFont(const QFont &font);
+ void changeFontSize(int fontsize);
+ void setBackgroundEnabled(int enabled);
+ void setGridEnabled(int enabled);
+ void start();
+
+public slots:
+ void changeShadowQuality(int quality);
+ void shadowQualityUpdatedByVisual(QDataVis::ShadowQuality shadowQuality);
+ void clear();
+ void addOne();
+ void addBunch();
+ void insertOne();
+ void insertBunch();
+ void changeOne();
+ void changeBunch();
+ void removeOne();
+ void removeBunch();
+ void timeout();
+ void startStopTimer();
+
+signals:
+ void shadowQualityChanged(int quality);
+
+private:
+ QVector3D randVector();
+ Q3DScatter *m_chart;
+ int m_fontSize;
+ QTimer m_timer;
+ int m_loopCounter;
+};
+
+#endif
diff --git a/examples/scatterchart/scatterchart.pro b/examples/scatterchart/scatterchart.pro
new file mode 100644
index 00000000..5dee59fd
--- /dev/null
+++ b/examples/scatterchart/scatterchart.pro
@@ -0,0 +1,10 @@
+!include( ../examples.pri ) {
+ error( "Couldn't find the examples.pri file!" )
+}
+
+SOURCES += main.cpp scatterchart.cpp
+HEADERS += scatterchart.h
+
+QT += widgets
+
+INSTALLS += target
diff --git a/examples/spectrum/doc/src/spectrum.qdoc b/examples/spectrum/doc/src/spectrum.qdoc
index 87028e9c..612c31cd 100644
--- a/examples/spectrum/doc/src/spectrum.qdoc
+++ b/examples/spectrum/doc/src/spectrum.qdoc
@@ -1,27 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
-** This file is part of the documentation of the QtDataVis3D module.
+** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:FDL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: http://www.gnu.org/copyleft/fdl.html.
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
diff --git a/examples/spectrum/spectrum.pro b/examples/spectrum/spectrum.pro
index eb431bd8..9a8d45ae 100644
--- a/examples/spectrum/spectrum.pro
+++ b/examples/spectrum/spectrum.pro
@@ -1,7 +1,3 @@
-!include( ../examples.pri ) {
- error( "Couldn't find the examples.pri file!" )
-}
-
qtHaveModule(multimedia) {
include(spectrum.pri)
diff --git a/examples/spectrum/spectrumapp/engine.cpp b/examples/spectrum/spectrumapp/engine.cpp
index 7016af4a..c23a4f78 100644
--- a/examples/spectrum/spectrumapp/engine.cpp
+++ b/examples/spectrum/spectrumapp/engine.cpp
@@ -1,40 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
-** This file is part of the examples of the Qt Toolkit.
+** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
-** of its contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
diff --git a/examples/spectrum/spectrumapp/engine.h b/examples/spectrum/spectrumapp/engine.h
index 3d04e13b..cdd8373f 100644
--- a/examples/spectrum/spectrumapp/engine.h
+++ b/examples/spectrum/spectrumapp/engine.h
@@ -1,40 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
-** This file is part of the examples of QtDataVis3D.
+** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
-** of its contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
diff --git a/examples/spectrum/spectrumapp/frequencyspectrum.cpp b/examples/spectrum/spectrumapp/frequencyspectrum.cpp
index f4a4167b..013d0454 100644
--- a/examples/spectrum/spectrumapp/frequencyspectrum.cpp
+++ b/examples/spectrum/spectrumapp/frequencyspectrum.cpp
@@ -1,40 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
-** This file is part of the examples of the Qt Toolkit.
+** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
-** of its contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
diff --git a/examples/spectrum/spectrumapp/frequencyspectrum.h b/examples/spectrum/spectrumapp/frequencyspectrum.h
index e7ea2e53..fac9a1b7 100644
--- a/examples/spectrum/spectrumapp/frequencyspectrum.h
+++ b/examples/spectrum/spectrumapp/frequencyspectrum.h
@@ -1,40 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
-** This file is part of the examples of QtDataVis3D.
+** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
-** of its contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
diff --git a/examples/spectrum/spectrumapp/main.cpp b/examples/spectrum/spectrumapp/main.cpp
index 4296a347..d0333e75 100644
--- a/examples/spectrum/spectrumapp/main.cpp
+++ b/examples/spectrum/spectrumapp/main.cpp
@@ -1,47 +1,28 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
-** This file is part of the examples of the Qt Toolkit.
+** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
-** of its contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
-#include "q3dbars.h"
#include "engine.h"
#include "utils.h"
+#include <QtDataVis3D/q3dbars.h>
+#include <QtDataVis3D/qbardataproxy.h>
+#include <QtDataVis3D/qvalueaxis.h>
+
#include <QGuiApplication>
#include <QAudio>
#include <QTimer>
@@ -85,20 +66,21 @@ MainApp::MainApp(Q3DBars *window)
m_lowFreq(SpectrumLowFreq),
m_highFreq(SpectrumHighFreq)
{
- m_chart->setupSampleSpace(SpectrumNumBands, SpectrumNumBands * 2);
+ m_chart->setupSampleSpace(SpectrumNumBands * 2, SpectrumNumBands);
// Disable grid
- m_chart->setGridEnabled(false);
- // Disable auto-scaling of height by defining tick count and step, even though we don't draw grid
- // By setting count to 1 and step to the max we can get, we lock the scale of the bars.
- m_chart->setTickCount(1, 1.0f);
+ m_chart->setGridVisible(false);
+ // Disable auto-scaling of height by defining explicit range
+ // By setting count to 0 we avoid getting any grid
+ m_chart->valueAxis()->setSegmentCount(0);
+ m_chart->valueAxis()->setRange(0.0, 1.0);
// Disable shadows
- m_chart->setShadowQuality(ShadowNone);
+ m_chart->setShadowQuality(QDataVis::ShadowNone);
#if USE_CONES
// Set bar specifications; make them a bit wider than deep and make them be drawn 75%
// inside each other
m_chart->setBarSpecs(QSizeF(1.0f, 0.75f), QSizeF(0.2f, -0.75f));
// Set bar type, smooth cones
- m_chart->setBarType(Cones, true);
+ m_chart->setBarType(QDataVis::Cones, true);
// Adjust zoom manually; automatic zoom level calculation does not work well with negative
// spacings (in setBarSpecs)
m_chart->setCameraPosition(10.0f, 5.0f, 70);
@@ -106,18 +88,21 @@ MainApp::MainApp(Q3DBars *window)
// Set bar specifications; make them twice as wide as they're deep
m_chart->setBarSpecs(QSizeF(1.0f, 0.5f), QSizeF(0.0f, 0.0f));
// Set bar type, flat bars
- m_chart->setBarType(Bars, false);
+ m_chart->setBarType(QDataVis::Bars, false);
// Adjust camera position
m_chart->setCameraPosition(10.0f, 7.5f, 75);
#endif
// Set color scheme
m_chart->setBarColor(QColor(Qt::black), QColor(Qt::red), QColor(Qt::darkYellow));
// Disable selection
- m_chart->setSelectionMode(ModeNone);
+ m_chart->setSelectionMode(QDataVis::ModeNone);
QObject::connect(m_engine, &Engine::changedSpectrum, this, &MainApp::spectrumChanged);
QObject::connect(m_engine, &Engine::stateChanged, this, &MainApp::stateChanged);
m_restartTimer->setSingleShot(true);
QObject::connect(m_restartTimer, &QTimer::timeout, this, &MainApp::restart);
+
+ QBarDataProxy *proxy = new QBarDataProxy;
+ m_chart->setDataProxy(proxy);
}
MainApp::~MainApp()
@@ -141,22 +126,20 @@ void MainApp::spectrumChanged(qint64 position, qint64 length, const FrequencySpe
Q_UNUSED(position);
Q_UNUSED(length);
//qDebug() << "updating bar values" << position << length;
- QVector<float> data;
+ QBarDataRow *data = new QBarDataRow(SpectrumNumBands);
for (int bar = 0; bar < SpectrumNumBands; bar++) {
// init data set
- data.append(0.0f);
+ (*data)[bar].setValue(qreal(0.0));
}
FrequencySpectrum::const_iterator i = spectrum.begin();
const FrequencySpectrum::const_iterator end = spectrum.end();
for ( ; i != end; ++i) {
const FrequencySpectrum::Element e = *i;
if (e.frequency >= m_lowFreq && e.frequency < m_highFreq) {
- data.replace(barIndex(e.frequency)
- , qMax(data.at(barIndex(e.frequency)), (float)e.amplitude));
+ (*data)[barIndex(e.frequency)].setValue(qMax(data->at(barIndex(e.frequency)).value(), qreal(e.amplitude)));
}
}
- if (data.size() > 0)
- m_chart->addDataRow(data);
+ static_cast<QBarDataProxy *>(m_chart->dataProxy())->insertRow(0, data);
}
void MainApp::stateChanged(QAudio::Mode mode, QAudio::State state)
diff --git a/examples/spectrum/spectrumapp/spectrum.h b/examples/spectrum/spectrumapp/spectrum.h
index 244a5892..015989d5 100644
--- a/examples/spectrum/spectrumapp/spectrum.h
+++ b/examples/spectrum/spectrumapp/spectrum.h
@@ -1,49 +1,27 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
-** This file is part of the examples of QtDataVis3D.
+** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
-** of its contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
#ifndef SPECTRUM_H
#define SPECTRUM_H
-#include <qglobal.h>
#include "utils.h"
#include "fftreal_wrapper.h" // For FFTLengthPowerOfTwo
+#include <qglobal.h>
//-----------------------------------------------------------------------------
// Constants
diff --git a/examples/spectrum/spectrumapp/spectrumanalyser.cpp b/examples/spectrum/spectrumapp/spectrumanalyser.cpp
index 518bb6da..4cebfde9 100644
--- a/examples/spectrum/spectrumapp/spectrumanalyser.cpp
+++ b/examples/spectrum/spectrumapp/spectrumanalyser.cpp
@@ -1,40 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
-** This file is part of the examples of the Qt Toolkit.
+** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
-** of its contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
diff --git a/examples/spectrum/spectrumapp/spectrumanalyser.h b/examples/spectrum/spectrumapp/spectrumanalyser.h
index 50d4fb66..6d9291ef 100644
--- a/examples/spectrum/spectrumapp/spectrumanalyser.h
+++ b/examples/spectrum/spectrumapp/spectrumanalyser.h
@@ -1,40 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
-** This file is part of the examples of QtDataVis3D.
+** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
-** of its contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
diff --git a/examples/spectrum/spectrumapp/spectrumapp.pro b/examples/spectrum/spectrumapp/spectrumapp.pro
index f73336a1..c2455f78 100644
--- a/examples/spectrum/spectrumapp/spectrumapp.pro
+++ b/examples/spectrum/spectrumapp/spectrumapp.pro
@@ -1,4 +1,10 @@
-include(../spectrum.pri)
+!include( ../../examples.pri ) {
+ error( "Couldn't find the examples.pri file!" )
+}
+
+!include( ../spectrum.pri ) {
+ error( "Couldn't find the spectrum.pri file!" )
+}
static: error(This application cannot be statically linked to the fftreal library)
@@ -6,7 +12,7 @@ TEMPLATE = app
TARGET = spectrum
-QT += multimedia datavis3d
+QT += multimedia
SOURCES += main.cpp \
engine.cpp \
diff --git a/examples/spectrum/spectrumapp/utils.cpp b/examples/spectrum/spectrumapp/utils.cpp
index 723dd6f6..bad6cc48 100644
--- a/examples/spectrum/spectrumapp/utils.cpp
+++ b/examples/spectrum/spectrumapp/utils.cpp
@@ -1,40 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
-** This file is part of the examples of the Qt Toolkit.
+** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
-** of its contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
diff --git a/examples/spectrum/spectrumapp/utils.h b/examples/spectrum/spectrumapp/utils.h
index 62215db5..f0ae5633 100644
--- a/examples/spectrum/spectrumapp/utils.h
+++ b/examples/spectrum/spectrumapp/utils.h
@@ -1,40 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
-** This file is part of the examples of QtDataVis3D.
+** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
-** of its contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
diff --git a/examples/spectrum/spectrumapp/wavfile.cpp b/examples/spectrum/spectrumapp/wavfile.cpp
index 0fe8833d..24482507 100644
--- a/examples/spectrum/spectrumapp/wavfile.cpp
+++ b/examples/spectrum/spectrumapp/wavfile.cpp
@@ -1,40 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
-** This file is part of the examples of QtDataVis3D.
+** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
-** of its contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
diff --git a/examples/spectrum/spectrumapp/wavfile.h b/examples/spectrum/spectrumapp/wavfile.h
index a9bca7e1..e408911b 100644
--- a/examples/spectrum/spectrumapp/wavfile.h
+++ b/examples/spectrum/spectrumapp/wavfile.h
@@ -1,40 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
-** This file is part of the examples of QtDataVis3D.
+** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
-** of its contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
diff --git a/examples/surfacechart/chartmodifier.cpp b/examples/surfacechart/chartmodifier.cpp
new file mode 100644
index 00000000..b685a680
--- /dev/null
+++ b/examples/surfacechart/chartmodifier.cpp
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "chartmodifier.h"
+
+#include <qmath.h>
+
+#include <QDebug>
+
+QT_DATAVIS3D_USE_NAMESPACE
+
+ChartModifier::ChartModifier(Q3DSurface *chart)
+ : m_chart(chart),
+ m_xCount(10),
+ m_zCount(10)
+{
+}
+
+ChartModifier::~ChartModifier()
+{
+ delete m_chart;
+}
+
+void ChartModifier::toggleSmooth(bool enabled)
+{
+ qDebug() << "ChartModifier::toggleSmooth " << enabled;
+ m_chart->setSmoothSurface(enabled);
+}
+
+void ChartModifier::toggleSurfaceGrid(bool enable)
+{
+ qDebug() << "ChartModifier::toggleSurfaceGrid" << enable;
+ m_chart->setSurfaceGrid(enable);
+}
+
+void ChartModifier::toggleSqrtSin(bool enable)
+{
+ qreal biggest = -9999.0;
+ qreal smallest = 9999.0;
+ QList<qreal> series;
+
+ if (enable) {
+ qDebug() << "Create Sqrt&Sin surface, (" << m_xCount << ", " << m_zCount << ")";
+
+ qreal stepZ = 16.0 / qreal(m_zCount);
+ qreal stepX = 16.0 / qreal(m_xCount);
+
+ for (qreal i = -8.0 + stepZ / 2.0 ; i < 8.0 ; i += stepZ) {
+ for (qreal j = -8.0 + stepX / 2.0; j < 8.0; j += stepX) {
+ qreal R = qSqrt(i*i + j*j) + 0.01;
+ qreal y = (sin(R)/R + 0.24) * 1.61;
+ series << y;
+ if (y > biggest) biggest = y;
+ if (y < smallest) smallest = y;
+ }
+ }
+
+ m_chart->setSegmentCount(4, 0.5f);
+ m_chart->appendSeries(series, m_xCount, m_zCount);
+
+ qDebug() << "biggest = " << biggest << ", smallest = " << smallest;
+ } else {
+ qDebug() << "Remove surface";
+ }
+}
+
+void ChartModifier::togglePlane(bool enable)
+{
+ qDebug() << "ChartModifier::togglePlane " << enable;
+ if (enable) {
+ QList<qreal> series;
+
+ qreal y = 2.0 / qreal(m_zCount - 1);
+ for (int i = 0; i < m_zCount; i++) {
+ for (int j = 0; j < m_xCount; j++) {
+ series << i * y;
+ }
+ }
+
+ m_chart->setSegmentCount(4, 0.5f);
+ m_chart->appendSeries(series, m_xCount, m_zCount);
+ }
+}
+
+void ChartModifier::toggleGridSliderLock(bool enable)
+{
+ m_gridSlidersLocked = enable;
+ if (m_gridSlidersLocked) {
+ m_gridSliderZ->setEnabled(false);
+ m_gridSliderZ->setValue(m_gridSliderX->value());
+ } else {
+ m_gridSliderZ->setEnabled(true);
+ }
+}
+
+void ChartModifier::adjustXCount(int count)
+{
+ m_xCount = count;
+ if (m_gridSlidersLocked)
+ m_gridSliderZ->setValue(count);
+
+ qDebug() << "X count = " << count;
+}
+
+void ChartModifier::adjustZCount(int count)
+{
+ m_zCount = count;
+
+ qDebug() << "Z count = " << count;
+}
+
diff --git a/examples/surfacechart/chartmodifier.h b/examples/surfacechart/chartmodifier.h
new file mode 100644
index 00000000..3ab2d179
--- /dev/null
+++ b/examples/surfacechart/chartmodifier.h
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef CHARTMODIFIER_H
+#define CHARTMODIFIER_H
+
+#include <QtDataVis3D/Q3DSurface>
+#include <QSlider>
+
+using namespace QtDataVis3D;
+
+class ChartModifier : public QObject
+{
+ Q_OBJECT
+public:
+ explicit ChartModifier(Q3DSurface *chart);
+ ~ChartModifier();
+
+ void toggleSmooth(bool enabled);
+ void toggleSurfaceGrid(bool enable);
+ void toggleSqrtSin(bool enable);
+ void togglePlane(bool enable);
+ void toggleGridSliderLock(bool enable);
+ void setGridSliderX(QSlider *slider) { m_gridSliderX = slider; }
+ void setGridSliderZ(QSlider *slider) { m_gridSliderZ = slider; }
+ void adjustXCount(int count);
+ void adjustZCount(int count);
+
+private:
+ Q3DSurface *m_chart;
+ QSlider *m_gridSliderX;
+ QSlider *m_gridSliderZ;
+ bool m_gridSlidersLocked;
+ int m_xCount;
+ int m_zCount;
+};
+
+#endif // CHARTMODIFIER_H
diff --git a/examples/surfacechart/main.cpp b/examples/surfacechart/main.cpp
new file mode 100644
index 00000000..1297d92b
--- /dev/null
+++ b/examples/surfacechart/main.cpp
@@ -0,0 +1,171 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "chartmodifier.h"
+
+#include <QApplication>
+#include <QApplication>
+#include <QWidget>
+#include <QHBoxLayout>
+#include <QVBoxLayout>
+#include <QPushButton>
+#include <QCheckBox>
+#include <QSlider>
+#include <QLabel>
+#include <QScreen>
+#include <QPainter>
+#include <QDebug>
+
+using namespace QtDataVis3D;
+
+int main(int argc, char *argv[])
+{
+ QApplication app(argc, argv);
+
+ QWidget *widget = new QWidget;
+ QHBoxLayout *hLayout = new QHBoxLayout(widget);
+ QVBoxLayout *vLayout = new QVBoxLayout();
+ vLayout->setAlignment(Qt::AlignTop);
+
+ Q3DSurface *surfaceChart = new Q3DSurface();
+ QSize screenSize = surfaceChart->screen()->size();
+
+ QWidget *container = QWidget::createWindowContainer(surfaceChart);
+ container->setMinimumSize(QSize(screenSize.width() / 2, screenSize.height() / 2));
+ container->setMaximumSize(screenSize);
+ container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ container->setFocusPolicy(Qt::StrongFocus);
+
+ widget->setWindowTitle(QStringLiteral("Surface tester"));
+
+ hLayout->addWidget(container, 1);
+ hLayout->addLayout(vLayout);
+
+ QCheckBox *smoothCB = new QCheckBox(widget);
+ smoothCB->setText(QStringLiteral("Smooth "));
+ smoothCB->setChecked(surfaceChart->smoothSurface());
+
+ QCheckBox *surfaceGridCB = new QCheckBox(widget);
+ surfaceGridCB->setText(QStringLiteral("Surface Grid"));
+ surfaceGridCB->setChecked(true);
+
+ QCheckBox *sqrtSinCB = new QCheckBox(widget);
+ sqrtSinCB->setText(QStringLiteral("Sqrt & Sin"));
+ sqrtSinCB->setChecked(false);
+
+ QCheckBox *planeCB = new QCheckBox(widget);
+ planeCB->setText(QStringLiteral("Plane"));
+ planeCB->setChecked(false);
+
+ QCheckBox *gridSlidersLockCB = new QCheckBox(widget);
+ gridSlidersLockCB->setText(QStringLiteral("Lock"));
+ gridSlidersLockCB->setChecked(false);
+
+ QSlider *gridSliderX = new QSlider(Qt::Horizontal, widget);
+ gridSliderX->setTickInterval(1);
+ gridSliderX->setMinimum(2);
+ gridSliderX->setValue(10);
+ gridSliderX->setMaximum(200);
+ gridSliderX->setEnabled(true);
+ QSlider *gridSliderZ = new QSlider(Qt::Horizontal, widget);
+ gridSliderZ->setTickInterval(1);
+ gridSliderZ->setMinimum(2);
+ gridSliderZ->setValue(10);
+ gridSliderZ->setMaximum(200);
+ gridSliderZ->setEnabled(true);
+
+ QLinearGradient gr(0, 0, 100, 1);
+ gr.setColorAt(0.0, Qt::green);
+ gr.setColorAt(0.5, Qt::yellow);
+ gr.setColorAt(1.0, Qt::red);
+ QPixmap pm(100, 24);
+ QPainter pmp(&pm);
+ pmp.setBrush(QBrush(gr));
+ pmp.setPen(Qt::NoPen);
+ pmp.drawRect(0, 0, 100, 24);
+ //pm.save("C:\\Users\\misalmel\\Work\\test.png", "png");
+ QPushButton *color = new QPushButton();
+ color->setIcon(QIcon(pm));
+ color->setIconSize(QSize(100, 24));
+ color->setFlat(true);
+
+ // Add controls to the layout
+ vLayout->addWidget(smoothCB);
+ vLayout->addWidget(surfaceGridCB);
+ vLayout->addWidget(new QLabel(QStringLiteral("Select surface sample")));
+ vLayout->addWidget(sqrtSinCB);
+ vLayout->addWidget(planeCB);
+ vLayout->addWidget(new QLabel(QStringLiteral("Adjust sample count")));
+ vLayout->addWidget(gridSlidersLockCB);
+ vLayout->addWidget(gridSliderX);
+ vLayout->addWidget(gridSliderZ);
+ vLayout->addWidget(color);
+
+ widget->show();
+
+ ChartModifier *modifier = new ChartModifier(surfaceChart);
+
+ // Connect controls to slots on modifier
+ QObject::connect(smoothCB, &QCheckBox::stateChanged,
+ modifier, &ChartModifier::toggleSmooth);
+ QObject::connect(surfaceGridCB, &QCheckBox::stateChanged,
+ modifier, &ChartModifier::toggleSurfaceGrid);
+ QObject::connect(sqrtSinCB, &QCheckBox::stateChanged,
+ modifier, &ChartModifier::toggleSqrtSin);
+ QObject::connect(planeCB, &QCheckBox::stateChanged,
+ modifier, &ChartModifier::togglePlane);
+ QObject::connect(gridSlidersLockCB, &QCheckBox::stateChanged,
+ modifier, &ChartModifier::toggleGridSliderLock);
+ QObject::connect(gridSliderX, &QSlider::valueChanged,
+ modifier, &ChartModifier::adjustXCount);
+ QObject::connect(gridSliderZ, &QSlider::valueChanged,
+ modifier, &ChartModifier::adjustZCount);
+
+ modifier->setGridSliderZ(gridSliderZ);
+ modifier->setGridSliderX(gridSliderX);
+ modifier->toggleGridSliderLock(gridSlidersLockCB->checkState());
+
+// QList<qreal> lowList;
+// lowList << 15.0 << 35.0 << 55.0 << 75.0 << 80.0 << 75.0 << 55.0 << 35.0 << 15.0;
+// lowList << 65.0 << 105.0 << 135.0 << 155.0 << 190.0 << 155.0 << 135.0 << 105.0 << 65.0;
+// lowList << 105.0 << 170.0 << 215.0 << 240.0 << 245.0 << 240.0 << 215.0 << 170.0 << 105.0;
+// lowList << 65.0 << 105.0 << 135.0 << 155.0 << 190.0 << 155.0 << 135.0 << 105.0 << 65.0;
+// lowList << 15.0 << 35.0 << 55.0 << 75.0 << 80.0 << 75.0 << 55.0 << 35.0 << 16.1;
+
+// lowList << 15.0 << 65.0 << 105.0 << 65.0 << 15.0;
+// lowList << 35.0 << 105.0 << 170.0 << 105.0 << 35;
+// lowList << 55.0 << 135.0 << 215.0 << 135.0 << 55;
+// lowList << 75.0 << 155.0 << 240.0 << 155.0 << 75;
+// lowList << 80.0 << 190.0 << 245.0 << 190.0 << 80;
+// lowList << 75.0 << 155.0 << 240.0 << 155.0 << 75.0;
+// lowList << 55.0 << 135.0 << 215.0 << 135.0 << 55;
+// lowList << 35.0 << 105.0 << 170.0 << 105.0 << 35.0;
+// lowList << 15.0 << 65.0 << 105.0 << 65.0 << 16.1;
+
+// surfaceChart->appendSeries(lowList, 9, 5);
+
+// QList<qreal> topList;
+// topList << 2.1 << 2.2;
+// surfaceChart.appendSeries(topList);
+
+// surfaceChart.resize(screenSize.width() / 1.5, screenSize.height() / 1.5);
+// surfaceChart.setPosition(screenSize.width() / 6, screenSize.height() / 6);
+// surfaceChart.show();
+
+ return app.exec();
+}
diff --git a/examples/surfacechart/surfacechart.pro b/examples/surfacechart/surfacechart.pro
new file mode 100644
index 00000000..79fd967d
--- /dev/null
+++ b/examples/surfacechart/surfacechart.pro
@@ -0,0 +1,11 @@
+!include( ../examples.pri ) {
+ error( "Couldn't find the examples.pri file!" )
+}
+
+SOURCES += main.cpp \
+ chartmodifier.cpp
+
+INSTALLS += target
+
+HEADERS += \
+ chartmodifier.h
diff --git a/examples/widget/chart.cpp b/examples/widget/chart.cpp
index c57a6752..a8c6c14a 100644
--- a/examples/widget/chart.cpp
+++ b/examples/widget/chart.cpp
@@ -1,46 +1,28 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
-** This file is part of the documentation of QtDataVis3D module.
+** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
-** of its contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
#include "chart.h"
+#include <QtDataVis3D/qcategoryaxis.h>
+#include <QtDataVis3D/qvalueaxis.h>
+#include <QtDataVis3D/qbardataproxy.h>
+#include <QTime>
-using namespace QtDataVis3D;
+QT_DATAVIS3D_USE_NAMESPACE
const QString celsiusString = QString(QChar(0xB0)) + "C";
@@ -56,11 +38,25 @@ ChartModifier::ChartModifier(Q3DBars *barchart)
m_barSpacingX(0.1f),
m_barSpacingZ(0.1f),
m_fontSize(20),
- m_ticks(20),
- m_tickStep(1),
- m_minval(-15.2f)
+ m_segments(4),
+ m_subSegments(3),
+ m_minval(-20.0), // TODO Barchart Y-axis currently only properly supports zero-centered ranges
+ m_maxval(20.0)
{
// Don't set any styles or specifications, start from defaults
+ // Generate generic labels
+ for (int i = 0; i < 200; i++) {
+ if (i % 5)
+ m_genericRowLabels << QString();
+ else
+ m_genericRowLabels << QStringLiteral("Row %1").arg(i);
+ }
+ for (int i = 0; i < 200; i++) {
+ if (i % 5)
+ m_genericColumnLabels << QString();
+ else
+ m_genericColumnLabels << QStringLiteral("Column %1").arg(i);
+ }
}
ChartModifier::~ChartModifier()
@@ -81,16 +77,27 @@ void ChartModifier::restart(bool dynamicData)
if (m_static) {
start();
// Set selection mode to zoom row
- m_chart->setSelectionMode(ModeZoomRow);
+ m_chart->setSelectionMode(QDataVis::ModeZoomRow);
m_chart->setFont(QFont("Times Roman", 20));
- m_chart->setTickCount(m_ticks, m_tickStep, m_minval);
} else {
+ m_chart->dataProxy()->resetArray(0);
// Set up sample space
- m_chart->setupSampleSpace(m_columnCount, m_rowCount);
+ m_chart->setupSampleSpace(m_rowCount, m_columnCount);
// Set selection mode to full
- m_chart->setSelectionMode(ModeBarRowAndColumn);
- // Reset tick count to default
- m_chart->setTickCount(0, 0);
+ m_chart->setSelectionMode(QDataVis::ModeItemRowAndColumn);
+ m_chart->valueAxis()->setSegmentCount(m_segments * 2);
+ m_chart->valueAxis()->setSubSegmentCount(0);
+ m_chart->valueAxis()->setAutoAdjustRange(true);
+
+ m_chart->rowAxis()->setTitle("Generic Row");
+ m_chart->columnAxis()->setTitle("Generic Column");
+ m_chart->valueAxis()->setTitle("Generic Value");
+
+ if (m_chart->rowAxis()->labels().size() < m_rowCount)
+ m_chart->rowAxis()->setCategoryLabels(m_genericRowLabels.mid(0, m_rowCount));
+
+ if (m_chart->columnAxis()->labels().size() < m_rowCount)
+ m_chart->columnAxis()->setCategoryLabels(m_genericColumnLabels.mid(0, m_columnCount));
}
}
@@ -103,9 +110,9 @@ void ChartModifier::addDataSet()
m_chart->setWindowTitle(QStringLiteral("Average temperatures in Oulu, Finland (2006-2012)"));
// Set up row and column names
- QVector<QString> months;
+ QStringList months;
months << "January" << "February" << "March" << "April" << "May" << "June" << "July" << "August" << "September" << "October" << "November" << "December";
- QVector<QString> years;
+ QStringList years;
years << "2006" << "2007" << "2008" << "2009" << "2010" << "2011" << "2012";
// Set up data
@@ -117,46 +124,126 @@ void ChartModifier::addDataSet()
{-9.0f, -15.2f, -3.8f, 2.6f, 8.3f, 15.9f, 18.6f, 14.9f, 11.1f, 5.3f, 1.8f, -0.2f}, // 2011
{-8.7f, -11.3f, -2.3f, 0.4f, 7.5f, 12.2f, 16.4f, 14.1f, 9.2f, 3.1f, 0.3f, -12.1f}}; // 2012
- // Create data set
- QDataSet *dataSet = new QDataSet();
+ // Use default data proxy to feed data directly in expected format
+ QBarDataProxy *proxy = m_chart->dataProxy();
+ proxy->setItemLabelFormat(celsiusString);
// Add labels
- dataSet->setLabels("Year", "Month", "Average temperature (" + celsiusString + ")",
- years, months);
+ m_chart->rowAxis()->setTitle("Year");
+ m_chart->columnAxis()->setTitle("Month");
+ m_chart->valueAxis()->setTitle("Average temperature (" + celsiusString + ")");
+ m_chart->rowAxis()->setCategoryLabels(years);
+ m_chart->columnAxis()->setCategoryLabels(months);
+ m_chart->valueAxis()->setSegmentCount(m_segments);
+ m_chart->valueAxis()->setSubSegmentCount(m_subSegments);
+ m_chart->valueAxis()->setRange(m_minval, m_maxval);
// Create data rows
- QDataRow *dataRow;
+ QBarDataArray *dataSet = new QBarDataArray;
+ QBarDataRow *dataRow;
+
+ dataSet->reserve(years.size());
for (int year = 0; year < years.size(); year++) {
- dataRow = new QDataRow(years.at(year));
+ dataRow = new QBarDataRow(months.size());
// Create data items
for (int month = 0; month < months.size(); month++) {
// Add data to rows
- dataRow->addItem(new QDataItem(temp[year][month], celsiusString));
+ (*dataRow)[month].setValue(temp[year][month]);
}
// Add row to set
- dataSet->addRow(dataRow);
- // Get next pointer
- dataRow++;
+ dataSet->append(dataRow);
}
- // Set tick count (4 steps of 5 degrees, with absolute minimum of -16C, even though we don't have quite that low temperatures in the data)
- //m_chart->setTickCount(4, 5, -16.0f);
- // ..or 20 steps of 1 degree, with absolute minimum of -15.2C
- m_chart->setTickCount(m_ticks, m_tickStep, m_minval);
-
// Set up sample space based on prepared data
- m_chart->setupSampleSpace(months.size(), years.size());
+ m_chart->setupSampleSpace(years.size(), months.size());
+
+ // Add data to chart (chart assumes ownership)
+ proxy->resetArray(dataSet);
+}
+
+void ChartModifier::addRow()
+{
+ QBarDataRow *dataRow = new QBarDataRow(m_columnCount);
+ for (float i = 0; i < m_columnCount; i++) {
+ (*dataRow)[i].setValue(((i + 1) / (float)m_columnCount) * (float)(rand() % 100));
+ //(*dataRow)[i].setValue(i + m_chart->dataProxy()->rowCount());
+ }
+ m_chart->dataProxy()->insertRow(0, dataRow);
+}
+
+void ChartModifier::addRows()
+{
+ QTime timer;
+ timer.start();
+ QBarDataArray dataArray;
+ for (int i = 0; i < m_rowCount; i++) {
+ QBarDataRow *dataRow = new QBarDataRow(m_columnCount);
+ for (int j = 0; j < m_columnCount; j++)
+ (*dataRow)[j].setValue(qreal(j + i + m_chart->dataProxy()->rowCount()));
+ dataArray.append(dataRow);
+ }
+ m_chart->dataProxy()->insertRows(0, dataArray);
+ qDebug() << "Added" << m_rowCount << "rows, time:" << timer.elapsed();
+}
+
+void ChartModifier::changeItem()
+{
+ // TODO fix to use actual selected item, for now just assume some row/column are selected
+ int row = qMin(4, (m_chart->dataProxy()->rowCount() - 1));
+ if (row >= 0) {
+ int column = qMin(4, (m_chart->dataProxy()->rowAt(row)->size() - 1));
+ if (column >= 0) {
+ QBarDataItem item(qreal(rand() % 100));
+ m_chart->dataProxy()->setItem(row, column, item);
+ }
+ }
+}
+
+void ChartModifier::changeRow()
+{
+ // TODO fix to use actual selected item, for now just assume some is selected
+ int row = qMin(4, (m_chart->dataProxy()->rowCount() - 1));
+ if (row >= 0) {
+ QBarDataRow *newRow = new QBarDataRow(m_chart->dataProxy()->rowAt(row)->size());
+ for (int i = 0; i < newRow->size(); i++)
+ (*newRow)[i].setValue(qreal(rand() % 100));
+ m_chart->dataProxy()->setRow(row, newRow);
+ }
+}
+
+void ChartModifier::changeRows()
+{
+ // TODO fix to use actual selected item, for now just assume some is selected
+ int row = qMin(4, (m_chart->dataProxy()->rowCount() - 1));
+ if (row >= 0) {
+ int startRow = qMax(row - 2, 0);
+ QBarDataArray newArray;
+ for (int i = startRow; i <= row; i++ ) {
+ QBarDataRow *newRow = new QBarDataRow(m_chart->dataProxy()->rowAt(i)->size());
+ for (int j = 0; j < newRow->size(); j++)
+ (*newRow)[j].setValue(qreal(rand() % 100));
+ newArray.append(newRow);
+ }
+ m_chart->dataProxy()->setRows(startRow, newArray);
+ }
+}
- // Add data to chart
- m_chart->addDataSet(dataSet);
+void ChartModifier::removeRow()
+{
+ // TODO fix to use actual selected item, for now just assume some is selected
+ int row = qMin(4, (m_chart->dataProxy()->rowCount() - 1));
+ if (row >= 0)
+ m_chart->dataProxy()->removeRows(row, 1);
}
-void ChartModifier::addBars()
+void ChartModifier::removeRows()
{
- QVector<float> data;
- for (float i = 0; i < m_columnCount; i++)
- data.append(((i + 1) / (float)m_columnCount) * (float)(rand() % 100));
- m_chart->addDataRow(data);
+ // TODO fix to use actual selected item, for now just assume some is selected
+ int row = qMin(4, (m_chart->dataProxy()->rowCount() - 1));
+ if (row >= 0) {
+ int startRow = qMax(row - 2, 0);
+ m_chart->dataProxy()->removeRows(startRow, 3);
+ }
}
void ChartModifier::changeStyle()
@@ -164,34 +251,34 @@ void ChartModifier::changeStyle()
static int model = 0;
switch (model) {
case 0:
- m_chart->setBarType(Cylinders, false);
+ m_chart->setBarType(QDataVis::Cylinders, false);
break;
case 1:
- m_chart->setBarType(Cylinders, true);
+ m_chart->setBarType(QDataVis::Cylinders, true);
break;
case 2:
- m_chart->setBarType(Cones, false);
+ m_chart->setBarType(QDataVis::Cones, false);
break;
case 3:
- m_chart->setBarType(Cones, true);
+ m_chart->setBarType(QDataVis::Cones, true);
break;
case 4:
- m_chart->setBarType(Bars, false);
+ m_chart->setBarType(QDataVis::Bars, false);
break;
case 5:
- m_chart->setBarType(Bars, true);
+ m_chart->setBarType(QDataVis::Bars, true);
break;
case 6:
- m_chart->setBarType(Pyramids, false);
+ m_chart->setBarType(QDataVis::Pyramids, false);
break;
case 7:
- m_chart->setBarType(Pyramids, true);
+ m_chart->setBarType(QDataVis::Pyramids, true);
break;
case 8:
- m_chart->setBarType(BevelBars, false);
+ m_chart->setBarType(QDataVis::BevelBars, false);
break;
case 9:
- m_chart->setBarType(BevelBars, true);
+ m_chart->setBarType(QDataVis::BevelBars, true);
break;
}
model++;
@@ -201,42 +288,42 @@ void ChartModifier::changeStyle()
void ChartModifier::changePresetCamera()
{
- static int preset = PresetFrontLow;
+ static int preset = QDataVis::PresetFrontLow;
- m_chart->setCameraPreset((CameraPreset)preset);
+ m_chart->setCameraPreset((QDataVis::CameraPreset)preset);
- if (++preset > PresetDirectlyBelow)
- preset = PresetFrontLow;
+ if (++preset > QDataVis::PresetDirectlyBelow)
+ preset = QDataVis::PresetFrontLow;
}
void ChartModifier::changeTheme()
{
- static int theme = ThemeSystem;
+ static int theme = QDataVis::ThemeSystem;
- m_chart->setTheme((ColorTheme)theme);
+ m_chart->setTheme((QDataVis::ColorTheme)theme);
- if (++theme > ThemeLight)
- theme = ThemeSystem;
+ if (++theme > QDataVis::ThemeLight)
+ theme = QDataVis::ThemeSystem;
}
void ChartModifier::changeTransparency()
{
- static int transparency = TransparencyNone;
+ static int transparency = QDataVis::TransparencyNone;
- m_chart->setLabelTransparency((LabelTransparency)transparency);
+ m_chart->setLabelTransparency((QDataVis::LabelTransparency)transparency);
- if (++transparency > TransparencyNoBackground)
- transparency = TransparencyFromTheme;
+ if (++transparency > QDataVis::TransparencyNoBackground)
+ transparency = QDataVis::TransparencyFromTheme;
}
void ChartModifier::changeSelectionMode()
{
- static int selectionMode = ModeNone;
+ static int selectionMode = QDataVis::ModeNone;
- m_chart->setSelectionMode((SelectionMode)selectionMode);
+ m_chart->setSelectionMode((QDataVis::SelectionMode)selectionMode);
- if (++selectionMode > ModeZoomColumn)
- selectionMode = ModeNone;
+ if (++selectionMode > QDataVis::ModeZoomColumn)
+ selectionMode = QDataVis::ModeNone;
}
void ChartModifier::changeFont(const QFont &font)
@@ -253,31 +340,51 @@ void ChartModifier::changeFontSize(int fontsize)
m_chart->setFontSize((GLfloat)m_fontSize);
}
+void ChartModifier::shadowQualityUpdatedByVisual(QDataVis::ShadowQuality sq)
+{
+ int quality = 0;
+ switch (sq) {
+ case QDataVis::ShadowLow:
+ quality = 1;
+ break;
+ case QDataVis::ShadowMedium:
+ quality = 2;
+ break;
+ case QDataVis::ShadowHigh:
+ quality = 3;
+ break;
+ }
+
+ // Updates the UI component to show correct shadow quality
+ emit shadowQualityChanged(quality);
+}
+
void ChartModifier::changeShadowQuality(int quality)
{
- ShadowQuality sq = ShadowNone;
+ QDataVis::ShadowQuality sq = QDataVis::ShadowNone;
switch (quality) {
case 1:
- sq = ShadowLow;
+ sq = QDataVis::ShadowLow;
break;
case 2:
- sq = ShadowMedium;
+ sq = QDataVis::ShadowMedium;
break;
case 3:
- sq = ShadowHigh;
+ sq = QDataVis::ShadowHigh;
break;
}
m_chart->setShadowQuality(sq);
+ emit shadowQualityChanged(quality);
}
void ChartModifier::setBackgroundEnabled(int enabled)
{
- m_chart->setBackgroundEnabled((bool)enabled);
+ m_chart->setBackgroundVisible((bool)enabled);
}
void ChartModifier::setGridEnabled(int enabled)
{
- m_chart->setGridEnabled((bool)enabled);
+ m_chart->setGridVisible((bool)enabled);
}
void ChartModifier::rotateX(int rotation)
@@ -319,11 +426,15 @@ void ChartModifier::setSpacingSpecsZ(int spacing)
void ChartModifier::setSampleCountX(int samples)
{
m_columnCount = samples;
- m_chart->setupSampleSpace(m_columnCount, m_rowCount);
+ m_chart->setupSampleSpace(m_rowCount, m_columnCount);
+ if (m_chart->columnAxis()->labels().size() < m_columnCount)
+ m_chart->columnAxis()->setCategoryLabels(m_genericColumnLabels.mid(0, m_columnCount));
}
void ChartModifier::setSampleCountZ(int samples)
{
m_rowCount = samples;
- m_chart->setupSampleSpace(m_columnCount, m_rowCount);
+ m_chart->setupSampleSpace(m_rowCount, m_columnCount);
+ if (m_chart->rowAxis()->labels().size() < m_rowCount)
+ m_chart->rowAxis()->setCategoryLabels(m_genericRowLabels.mid(0, m_rowCount));
}
diff --git a/examples/widget/chart.h b/examples/widget/chart.h
index f4ef747b..67280e13 100644
--- a/examples/widget/chart.h
+++ b/examples/widget/chart.h
@@ -1,51 +1,29 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
-** This file is part of the documentation of QtDataVis3D module.
+** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
-** of its contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
#ifndef CHARTMODIFIER_H
#define CHARTMODIFIER_H
-#include "q3dbars.h"
-#include "qdataset.h"
+#include <QtDataVis3D/q3dbars.h>
#include <QFont>
#include <QDebug>
+#include <QStringList>
using namespace QtDataVis3D;
@@ -57,7 +35,13 @@ public:
~ChartModifier();
void addDataSet();
- void addBars();
+ void addRow();
+ void addRows();
+ void changeItem();
+ void changeRow();
+ void changeRows();
+ void removeRow();
+ void removeRows();
void changeStyle();
void changePresetCamera();
void changeTheme();
@@ -80,6 +64,10 @@ public:
public slots:
void changeShadowQuality(int quality);
+ void shadowQualityUpdatedByVisual(QDataVis::ShadowQuality shadowQuality);
+
+signals:
+ void shadowQualityChanged(int quality);
private:
Q3DBars *m_chart;
@@ -93,9 +81,12 @@ private:
float m_barSpacingX;
float m_barSpacingZ;
int m_fontSize;
- int m_ticks;
- float m_tickStep;
- float m_minval;
+ int m_segments;
+ int m_subSegments;
+ qreal m_minval;
+ qreal m_maxval;
+ QStringList m_genericRowLabels;
+ QStringList m_genericColumnLabels;
};
#endif
diff --git a/examples/widget/doc/src/widget.qdoc b/examples/widget/doc/src/widget.qdoc
index d8790a60..6645d356 100644
--- a/examples/widget/doc/src/widget.qdoc
+++ b/examples/widget/doc/src/widget.qdoc
@@ -1,27 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
-** This file is part of the documentation of the QtDataVis3D module.
+** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:FDL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: http://www.gnu.org/copyleft/fdl.html.
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
diff --git a/examples/widget/main.cpp b/examples/widget/main.cpp
index 1b33b177..47892484 100644
--- a/examples/widget/main.cpp
+++ b/examples/widget/main.cpp
@@ -1,40 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
-** This file is part of the documentation of QtDataVis3D module.
+** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
-** of its contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
@@ -75,9 +53,33 @@ int main(int argc, char **argv)
hLayout->addLayout(vLayout);
QPushButton *dataButton = new QPushButton(widget);
- dataButton->setText(QStringLiteral("Add a row of random data"));
+ dataButton->setText(QStringLiteral("Insert a row of data"));
dataButton->setEnabled(false);
+ QPushButton *multiDataButton = new QPushButton(widget);
+ multiDataButton->setText(QStringLiteral("Insert many rows of data"));
+ multiDataButton->setEnabled(false);
+
+ QPushButton *changeSingleDataButton = new QPushButton(widget);
+ changeSingleDataButton->setText(QStringLiteral("Change selected bar value"));
+ changeSingleDataButton->setEnabled(false);
+
+ QPushButton *changeRowButton = new QPushButton(widget);
+ changeRowButton->setText(QStringLiteral("Change selected row values"));
+ changeRowButton->setEnabled(false);
+
+ QPushButton *changeRowsButton = new QPushButton(widget);
+ changeRowsButton->setText(QStringLiteral("Change three rows from selected"));
+ changeRowsButton->setEnabled(false);
+
+ QPushButton *removeRowButton = new QPushButton(widget);
+ removeRowButton->setText(QStringLiteral("Remove selected row"));
+ removeRowButton->setEnabled(false);
+
+ QPushButton *removeRowsButton = new QPushButton(widget);
+ removeRowsButton->setText(QStringLiteral("remove three rows from selected"));
+ removeRowsButton->setEnabled(false);
+
QPushButton *themeButton = new QPushButton(widget);
themeButton->setText(QStringLiteral("Change theme"));
@@ -147,13 +149,13 @@ int main(int argc, char **argv)
sampleSliderX->setTickInterval(1);
sampleSliderX->setMinimum(2);
sampleSliderX->setValue(10);
- sampleSliderX->setMaximum(100);
+ sampleSliderX->setMaximum(200);
sampleSliderX->setEnabled(false);
QSlider *sampleSliderZ = new QSlider(Qt::Horizontal, widget);
sampleSliderZ->setTickInterval(1);
sampleSliderZ->setMinimum(2);
sampleSliderZ->setValue(10);
- sampleSliderZ->setMaximum(100);
+ sampleSliderZ->setMaximum(200);
sampleSliderZ->setEnabled(false);
QSlider *fontSizeSlider = new QSlider(Qt::Horizontal, widget);
@@ -185,6 +187,12 @@ int main(int argc, char **argv)
vLayout->addWidget(sampleSliderX, 0, Qt::AlignTop);
vLayout->addWidget(sampleSliderZ, 1, Qt::AlignTop);
vLayout->addWidget(dataButton, 0, Qt::AlignTop);
+ vLayout->addWidget(multiDataButton, 0, Qt::AlignTop);
+ vLayout->addWidget(changeSingleDataButton, 0, Qt::AlignTop);
+ vLayout->addWidget(changeRowButton, 0, Qt::AlignTop);
+ vLayout->addWidget(changeRowsButton, 0, Qt::AlignTop);
+ vLayout->addWidget(removeRowButton, 0, Qt::AlignTop);
+ vLayout->addWidget(removeRowsButton, 0, Qt::AlignTop);
vLayout->addWidget(themeButton, 0, Qt::AlignTop);
vLayout->addWidget(labelButton, 0, Qt::AlignTop);
vLayout->addWidget(styleButton, 0, Qt::AlignTop);
@@ -222,6 +230,10 @@ int main(int argc, char **argv)
QObject::connect(shadowQuality, SIGNAL(currentIndexChanged(int)), modifier,
SLOT(changeShadowQuality(int)));
+ QObject::connect(modifier, &ChartModifier::shadowQualityChanged, shadowQuality,
+ &QComboBox::setCurrentIndex);
+ QObject::connect(widgetchart, &Q3DBars::shadowQualityChanged, modifier,
+ &ChartModifier::shadowQualityUpdatedByVisual);
QObject::connect(fontSizeSlider, &QSlider::valueChanged, modifier,
&ChartModifier::changeFontSize);
@@ -232,7 +244,13 @@ int main(int argc, char **argv)
QObject::connect(themeButton, &QPushButton::clicked, modifier, &ChartModifier::changeTheme);
QObject::connect(labelButton, &QPushButton::clicked, modifier,
&ChartModifier::changeTransparency);
- QObject::connect(dataButton, &QPushButton::clicked, modifier, &ChartModifier::addBars);
+ QObject::connect(dataButton, &QPushButton::clicked, modifier, &ChartModifier::addRow);
+ QObject::connect(multiDataButton, &QPushButton::clicked, modifier, &ChartModifier::addRows);
+ QObject::connect(changeSingleDataButton, &QPushButton::clicked, modifier, &ChartModifier::changeItem);
+ QObject::connect(changeRowButton, &QPushButton::clicked, modifier, &ChartModifier::changeRow);
+ QObject::connect(changeRowsButton, &QPushButton::clicked, modifier, &ChartModifier::changeRows);
+ QObject::connect(removeRowButton, &QPushButton::clicked, modifier, &ChartModifier::removeRow);
+ QObject::connect(removeRowsButton, &QPushButton::clicked, modifier, &ChartModifier::removeRows);
QObject::connect(selectionButton, &QPushButton::clicked, modifier,
&ChartModifier::changeSelectionMode);
@@ -255,6 +273,18 @@ int main(int argc, char **argv)
QObject::connect(staticCheckBox, &QCheckBox::stateChanged, dataButton,
&QPushButton::setEnabled);
+ QObject::connect(staticCheckBox, &QCheckBox::stateChanged, multiDataButton,
+ &QPushButton::setEnabled);
+ QObject::connect(staticCheckBox, &QCheckBox::stateChanged, changeSingleDataButton,
+ &QPushButton::setEnabled);
+ QObject::connect(staticCheckBox, &QCheckBox::stateChanged, changeRowButton,
+ &QPushButton::setEnabled);
+ QObject::connect(staticCheckBox, &QCheckBox::stateChanged, changeRowsButton,
+ &QPushButton::setEnabled);
+ QObject::connect(staticCheckBox, &QCheckBox::stateChanged, removeRowButton,
+ &QPushButton::setEnabled);
+ QObject::connect(staticCheckBox, &QCheckBox::stateChanged, removeRowsButton,
+ &QPushButton::setEnabled);
QObject::connect(staticCheckBox, &QCheckBox::stateChanged, sampleSliderX,
&QSlider::setEnabled);
QObject::connect(staticCheckBox, &QCheckBox::stateChanged, sampleSliderZ,
diff --git a/examples/widget/widget.pro b/examples/widget/widget.pro
index 1d7e91be..2b4078a4 100644
--- a/examples/widget/widget.pro
+++ b/examples/widget/widget.pro
@@ -5,6 +5,6 @@
SOURCES += main.cpp chart.cpp
HEADERS += chart.h
-QT += datavis3d widgets
+QT += widgets
INSTALLS += target
diff --git a/src/datavis3d/Doxyfile b/src/datavis3d/Doxyfile
deleted file mode 100644
index e5d78895..00000000
--- a/src/datavis3d/Doxyfile
+++ /dev/null
@@ -1,1196 +0,0 @@
-# Doxyfile 1.4.5
-
-# This file describes the settings to be used by the documentation system
-# doxygen (www.doxygen.org) for a project
-#
-# All text after a hash (#) is considered a comment and will be ignored
-# The format is:
-# TAG = value [value, ...]
-# For lists items can also be appended using:
-# TAG += value [value, ...]
-# Values that contain spaces should be placed between quotes (" ")
-
-#---------------------------------------------------------------------------
-# Project related configuration options
-#---------------------------------------------------------------------------
-
-# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
-# by quotes) that should identify the project.
-
-PROJECT_NAME = QtDataVis3D
-
-# The PROJECT_NUMBER tag can be used to enter a project or revision number.
-# This could be handy for archiving the generated documentation or
-# if some version control system is used.
-
-PROJECT_NUMBER =
-
-# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
-# base path where the generated documentation will be put.
-# If a relative path is entered, it will be relative to the location
-# where doxygen was started. If left blank the current directory will be used.
-
-OUTPUT_DIRECTORY = internal-docs
-
-# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
-# 4096 sub-directories (in 2 levels) under the output directory of each output
-# format and will distribute the generated files over these directories.
-# Enabling this option can be useful when feeding doxygen a huge amount of
-# source files, where putting all generated files in the same directory would
-# otherwise cause performance problems for the file system.
-
-CREATE_SUBDIRS = NO
-
-# The OUTPUT_LANGUAGE tag is used to specify the language in which all
-# documentation generated by doxygen is written. Doxygen will use this
-# information to generate all constant output in the proper language.
-# The default language is English, other supported languages are:
-# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish,
-# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese,
-# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian,
-# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish,
-# Swedish, and Ukrainian.
-
-OUTPUT_LANGUAGE = English
-
-# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
-# include brief member descriptions after the members that are listed in
-# the file and class documentation (similar to JavaDoc).
-# Set to NO to disable this.
-
-BRIEF_MEMBER_DESC = YES
-
-# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
-# the brief description of a member or function before the detailed description.
-# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
-# brief descriptions will be completely suppressed.
-
-REPEAT_BRIEF = YES
-
-# This tag implements a quasi-intelligent brief description abbreviator
-# that is used to form the text in various listings. Each string
-# in this list, if found as the leading text of the brief description, will be
-# stripped from the text and the result after processing the whole list, is
-# used as the annotated text. Otherwise, the brief description is used as-is.
-# If left blank, the following values are used ("$name" is automatically
-# replaced with the name of the entity): "The $name class" "The $name widget"
-# "The $name file" "is" "provides" "specifies" "contains"
-# "represents" "a" "an" "the"
-
-ABBREVIATE_BRIEF =
-
-# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
-# Doxygen will generate a detailed section even if there is only a brief
-# description.
-
-ALWAYS_DETAILED_SEC = NO
-
-# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
-# inherited members of a class in the documentation of that class as if those
-# members were ordinary class members. Constructors, destructors and assignment
-# operators of the base classes will not be shown.
-
-INLINE_INHERITED_MEMB = NO
-
-# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
-# path before files name in the file list and in the header files. If set
-# to NO the shortest path that makes the file name unique will be used.
-
-FULL_PATH_NAMES = YES
-
-# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
-# can be used to strip a user-defined part of the path. Stripping is
-# only done if one of the specified strings matches the left-hand part of
-# the path. The tag can be used to show relative paths in the file list.
-# If left blank the directory from which doxygen is run is used as the
-# path to strip.
-
-STRIP_FROM_PATH =
-
-# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
-# the path mentioned in the documentation of a class, which tells
-# the reader which header file to include in order to use a class.
-# If left blank only the name of the header file containing the class
-# definition is used. Otherwise one should specify the include paths that
-# are normally passed to the compiler using the -I flag.
-
-STRIP_FROM_INC_PATH =
-
-# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
-# (but less readable) file names. This can be useful is your file systems
-# doesn't support long names like on DOS, Mac, or CD-ROM.
-
-SHORT_NAMES = NO
-
-# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
-# will interpret the first line (until the first dot) of a JavaDoc-style
-# comment as the brief description. If set to NO, the JavaDoc
-# comments will behave just like the Qt-style comments (thus requiring an
-# explicit @brief command for a brief description.
-
-JAVADOC_AUTOBRIEF = NO
-
-# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
-# treat a multi-line C++ special comment block (i.e. a block of //! or ///
-# comments) as a brief description. This used to be the default behaviour.
-# The new default is to treat a multi-line C++ comment block as a detailed
-# description. Set this tag to YES if you prefer the old behaviour instead.
-
-MULTILINE_CPP_IS_BRIEF = NO
-
-# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
-# member inherits the documentation from any documented member that it
-# re-implements.
-
-INHERIT_DOCS = YES
-
-# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
-# a new page for each member. If set to NO, the documentation of a member will
-# be part of the file/class/namespace that contains it.
-
-SEPARATE_MEMBER_PAGES = NO
-
-# The TAB_SIZE tag can be used to set the number of spaces in a tab.
-# Doxygen uses this value to replace tabs by spaces in code fragments.
-
-TAB_SIZE = 4
-
-# This tag can be used to specify a number of aliases that acts
-# as commands in the documentation. An alias has the form "name=value".
-# For example adding "sideeffect=\par Side Effects:\n" will allow you to
-# put the command \sideeffect (or @sideeffect) in the documentation, which
-# will result in a user-defined paragraph with heading "Side Effects:".
-# You can put \n's in the value part of an alias to insert newlines.
-
-ALIASES =
-
-# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
-# sources only. Doxygen will then generate output that is more tailored for C.
-# For instance, some of the names that are used will be different. The list
-# of all members will be omitted, etc.
-
-OPTIMIZE_OUTPUT_FOR_C = NO
-
-# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
-# sources only. Doxygen will then generate output that is more tailored for Java.
-# For instance, namespaces will be presented as packages, qualified scopes
-# will look different, etc.
-
-OPTIMIZE_OUTPUT_JAVA = NO
-
-# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to
-# include (a tag file for) the STL sources as input, then you should
-# set this tag to YES in order to let doxygen match functions declarations and
-# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
-# func(std::string) {}). This also make the inheritance and collaboration
-# diagrams that involve STL classes more complete and accurate.
-
-BUILTIN_STL_SUPPORT = YES
-
-# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
-# tag is set to YES, then doxygen will reuse the documentation of the first
-# member in the group (if any) for the other members of the group. By default
-# all members of a group must be documented explicitly.
-
-DISTRIBUTE_GROUP_DOC = NO
-
-# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
-# the same type (for instance a group of public functions) to be put as a
-# subgroup of that type (e.g. under the Public Functions section). Set it to
-# NO to prevent subgrouping. Alternatively, this can be done per class using
-# the \nosubgrouping command.
-
-SUBGROUPING = YES
-
-#---------------------------------------------------------------------------
-# Build related configuration options
-#---------------------------------------------------------------------------
-
-# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
-# documentation are documented, even if no documentation was available.
-# Private class members and static file members will be hidden unless
-# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
-
-EXTRACT_ALL = YES
-
-# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
-# will be included in the documentation.
-
-EXTRACT_PRIVATE = yes
-
-# If the EXTRACT_STATIC tag is set to YES all static members of a file
-# will be included in the documentation.
-
-EXTRACT_STATIC = YES
-
-# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
-# defined locally in source files will be included in the documentation.
-# If set to NO only classes defined in header files are included.
-
-EXTRACT_LOCAL_CLASSES = YES
-
-# This flag is only useful for Objective-C code. When set to YES local
-# methods, which are defined in the implementation section but not in
-# the interface are included in the documentation.
-# If set to NO (the default) only methods in the interface are included.
-
-EXTRACT_LOCAL_METHODS = NO
-
-# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
-# undocumented members of documented classes, files or namespaces.
-# If set to NO (the default) these members will be included in the
-# various overviews, but no documentation section is generated.
-# This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_MEMBERS = NO
-
-# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
-# undocumented classes that are normally visible in the class hierarchy.
-# If set to NO (the default) these classes will be included in the various
-# overviews. This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_CLASSES = NO
-
-# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
-# friend (class|struct|union) declarations.
-# If set to NO (the default) these declarations will be included in the
-# documentation.
-
-HIDE_FRIEND_COMPOUNDS = NO
-
-# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
-# documentation blocks found inside the body of a function.
-# If set to NO (the default) these blocks will be appended to the
-# function's detailed documentation block.
-
-HIDE_IN_BODY_DOCS = NO
-
-# The INTERNAL_DOCS tag determines if documentation
-# that is typed after a \internal command is included. If the tag is set
-# to NO (the default) then the documentation will be excluded.
-# Set it to YES to include the internal documentation.
-
-INTERNAL_DOCS = YES
-
-# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
-# file names in lower-case letters. If set to YES upper-case letters are also
-# allowed. This is useful if you have classes or files whose names only differ
-# in case and if your file system supports case sensitive file names. Windows
-# and Mac users are advised to set this option to NO.
-
-CASE_SENSE_NAMES = YES
-
-# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
-# will show members with their full class and namespace scopes in the
-# documentation. If set to YES the scope will be hidden.
-
-HIDE_SCOPE_NAMES = NO
-
-# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
-# will put a list of the files that are included by a file in the documentation
-# of that file.
-
-SHOW_INCLUDE_FILES = YES
-
-# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
-# is inserted in the documentation for inline members.
-
-INLINE_INFO = YES
-
-# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
-# will sort the (detailed) documentation of file and class members
-# alphabetically by member name. If set to NO the members will appear in
-# declaration order.
-
-SORT_MEMBER_DOCS = YES
-
-# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
-# brief documentation of file, namespace and class members alphabetically
-# by member name. If set to NO (the default) the members will appear in
-# declaration order.
-
-SORT_BRIEF_DOCS = YES
-
-# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
-# sorted by fully-qualified names, including namespaces. If set to
-# NO (the default), the class list will be sorted only by class name,
-# not including the namespace part.
-# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
-# Note: This option applies only to the class list, not to the
-# alphabetical list.
-
-SORT_BY_SCOPE_NAME = YES
-
-# The GENERATE_TODOLIST tag can be used to enable (YES) or
-# disable (NO) the todo list. This list is created by putting \todo
-# commands in the documentation.
-
-GENERATE_TODOLIST = YES
-
-# The GENERATE_TESTLIST tag can be used to enable (YES) or
-# disable (NO) the test list. This list is created by putting \test
-# commands in the documentation.
-
-GENERATE_TESTLIST = YES
-
-# The GENERATE_BUGLIST tag can be used to enable (YES) or
-# disable (NO) the bug list. This list is created by putting \bug
-# commands in the documentation.
-
-GENERATE_BUGLIST = YES
-
-# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
-# disable (NO) the deprecated list. This list is created by putting
-# \deprecated commands in the documentation.
-
-GENERATE_DEPRECATEDLIST= YES
-
-# The ENABLED_SECTIONS tag can be used to enable conditional
-# documentation sections, marked by \if sectionname ... \endif.
-
-ENABLED_SECTIONS =
-
-# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
-# the initial value of a variable or define consists of for it to appear in
-# the documentation. If the initializer consists of more lines than specified
-# here it will be hidden. Use a value of 0 to hide initializers completely.
-# The appearance of the initializer of individual variables and defines in the
-# documentation can be controlled using \showinitializer or \hideinitializer
-# command in the documentation regardless of this setting.
-
-MAX_INITIALIZER_LINES = 30
-
-# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
-# at the bottom of the documentation of classes and structs. If set to YES the
-# list will mention the files that were used to generate the documentation.
-
-SHOW_USED_FILES = YES
-
-# If the sources in your project are distributed over multiple directories
-# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
-# in the documentation. The default is YES.
-
-SHOW_DIRECTORIES = YES
-
-# The FILE_VERSION_FILTER tag can be used to specify a program or script that
-# doxygen should invoke to get the current version for each file (typically from the
-# version control system). Doxygen will invoke the program by executing (via
-# popen()) the command <command> <input-file>, where <command> is the value of
-# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
-# provided by doxygen. Whatever the program writes to standard output
-# is used as the file version. See the manual for examples.
-
-FILE_VERSION_FILTER =
-
-#---------------------------------------------------------------------------
-# configuration options related to warning and progress messages
-#---------------------------------------------------------------------------
-
-# The QUIET tag can be used to turn on/off the messages that are generated
-# by doxygen. Possible values are YES and NO. If left blank NO is used.
-
-# Having it set to not, output a lot of status messages to stdout, we still
-# get the warning into the log file
-QUIET = YES
-
-# The WARNINGS tag can be used to turn on/off the warning messages that are
-# generated by doxygen. Possible values are YES and NO. If left blank
-# NO is used.
-
-WARNINGS = YES
-
-# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
-# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
-# automatically be disabled.
-
-WARN_IF_UNDOCUMENTED = NO
-
-# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
-# potential errors in the documentation, such as not documenting some
-# parameters in a documented function, or documenting parameters that
-# don't exist or using markup commands wrongly.
-
-WARN_IF_DOC_ERROR = YES
-
-# This WARN_NO_PARAMDOC option can be abled to get warnings for
-# functions that are documented, but have no documentation for their parameters
-# or return value. If set to NO (the default) doxygen will only warn about
-# wrong or incomplete parameter documentation, but not about the absence of
-# documentation.
-
-WARN_NO_PARAMDOC = NO
-
-# The WARN_FORMAT tag determines the format of the warning messages that
-# doxygen can produce. The string should contain the $file, $line, and $text
-# tags, which will be replaced by the file and line number from which the
-# warning originated and the warning text. Optionally the format may contain
-# $version, which will be replaced by the version of the file (if it could
-# be obtained via FILE_VERSION_FILTER)
-
-WARN_FORMAT = "$file:$line: $text"
-
-# The WARN_LOGFILE tag can be used to specify a file to which warning
-# and error messages should be written. If left blank the output is written
-# to stderr.
-
-WARN_LOGFILE = internal-docs/doxygen.log
-
-#---------------------------------------------------------------------------
-# configuration options related to the input files
-#---------------------------------------------------------------------------
-
-# The INPUT tag can be used to specify the files and/or directories that contain
-# documented source files. You may enter file names like "myfile.cpp" or
-# directories like "/usr/src/myproject". Separate the files or directories
-# with spaces.
-
-INPUT = . ../../tests/auto/xmlpatternsxqts/ ../../tests/auto/xmlpatternsview
-
-# If the value of the INPUT tag contains directories, you can use the
-# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
-# and *.h) to filter out the source-files in the directories. If left
-# blank the following patterns are tested:
-
-FILE_PATTERNS = *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.dox *.gperf
-
-# The RECURSIVE tag can be used to turn specify whether or not subdirectories
-# should be searched for input files as well. Possible values are YES and NO.
-# If left blank NO is used.
-
-RECURSIVE = YES
-
-# The EXCLUDE tag can be used to specify files and/or directories that should
-# excluded from the INPUT source files. This way you can easily exclude a
-# subdirectory from a directory tree whose root is specified with the INPUT tag.
-
-EXCLUDE =
-
-# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
-# directories that are symbolic links (a Unix filesystem feature) are excluded
-# from the input.
-
-EXCLUDE_SYMLINKS = NO
-
-# If the value of the INPUT tag contains directories, you can use the
-# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
-# certain files from those directories. Note that the wildcards are matched
-# against the file with absolute path, so to exclude all test directories
-# for example use the pattern */test/*
-
-# The Qt API uses qdoc and Doxygen doesn't like its tags, so exclude the q* files.
-EXCLUDE_PATTERNS = *.moc *.moc.cpp moc_*.cpp ui_*.h
-
-# The EXAMPLE_PATH tag can be used to specify one or more files or
-# directories that contain example code fragments that are included (see
-# the \include command).
-
-EXAMPLE_PATH =
-
-# If the value of the EXAMPLE_PATH tag contains directories, you can use the
-# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
-# and *.h) to filter out the source-files in the directories. If left
-# blank all files are included.
-
-EXAMPLE_PATTERNS =
-
-# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
-# searched for input files to be used with the \include or \dontinclude
-# commands irrespective of the value of the RECURSIVE tag.
-# Possible values are YES and NO. If left blank NO is used.
-
-EXAMPLE_RECURSIVE = YES
-
-# The IMAGE_PATH tag can be used to specify one or more files or
-# directories that contain image that are included in the documentation (see
-# the \image command).
-
-IMAGE_PATH =
-
-# The INPUT_FILTER tag can be used to specify a program that doxygen should
-# invoke to filter for each input file. Doxygen will invoke the filter program
-# by executing (via popen()) the command <filter> <input-file>, where <filter>
-# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
-# input file. Doxygen will then use the output that the filter program writes
-# to standard output. If FILTER_PATTERNS is specified, this tag will be
-# ignored.
-
-INPUT_FILTER =
-
-# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
-# basis. Doxygen will compare the file name with each pattern and apply the
-# filter if there is a match. The filters are a list of the form:
-# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
-# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
-# is applied to all files.
-
-FILTER_PATTERNS =
-
-# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
-# INPUT_FILTER) will be used to filter the input files when producing source
-# files to browse (i.e. when SOURCE_BROWSER is set to YES).
-
-FILTER_SOURCE_FILES = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to source browsing
-#---------------------------------------------------------------------------
-
-# If the SOURCE_BROWSER tag is set to YES then a list of source files will
-# be generated. Documented entities will be cross-referenced with these sources.
-# Note: To get rid of all source code in the generated output, make sure also
-# VERBATIM_HEADERS is set to NO.
-
-SOURCE_BROWSER = YES
-
-# Setting the INLINE_SOURCES tag to YES will include the body
-# of functions and classes directly in the documentation.
-
-INLINE_SOURCES = NO
-
-# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
-# doxygen to hide any special comment blocks from generated source code
-# fragments. Normal C and C++ comments will always remain visible.
-
-STRIP_CODE_COMMENTS = YES
-
-# If the REFERENCED_BY_RELATION tag is set to YES (the default)
-# then for each documented function all documented
-# functions referencing it will be listed.
-
-REFERENCED_BY_RELATION = YES
-
-# If the REFERENCES_RELATION tag is set to YES (the default)
-# then for each documented function all documented entities
-# called/used by that function will be listed.
-
-REFERENCES_RELATION = YES
-
-# If the USE_HTAGS tag is set to YES then the references to source code
-# will point to the HTML generated by the htags(1) tool instead of doxygen
-# built-in source browser. The htags tool is part of GNU's global source
-# tagging system (see http://www.gnu.org/software/global/global.html). You
-# will need version 4.8.6 or higher.
-
-USE_HTAGS = NO
-
-# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
-# will generate a verbatim copy of the header file for each class for
-# which an include is specified. Set to NO to disable this.
-
-VERBATIM_HEADERS = YES
-
-#---------------------------------------------------------------------------
-# configuration options related to the alphabetical class index
-#---------------------------------------------------------------------------
-
-# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
-# of all compounds will be generated. Enable this if the project
-# contains a lot of classes, structs, unions or interfaces.
-
-ALPHABETICAL_INDEX = NO
-
-# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
-# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
-# in which this list will be split (can be a number in the range [1..20])
-
-COLS_IN_ALPHA_INDEX = 5
-
-# In case all classes in a project start with a common prefix, all
-# classes will be put under the same header in the alphabetical index.
-# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
-# should be ignored while generating the index headers.
-
-IGNORE_PREFIX =
-
-#---------------------------------------------------------------------------
-# configuration options related to the HTML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
-# generate HTML output.
-
-GENERATE_HTML = YES
-
-# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `html' will be used as the default path.
-
-HTML_OUTPUT =
-
-# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
-# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
-# doxygen will generate files with .html extension.
-
-HTML_FILE_EXTENSION = .html
-
-# The HTML_HEADER tag can be used to specify a personal HTML header for
-# each generated HTML page. If it is left blank doxygen will generate a
-# standard header.
-
-HTML_HEADER =
-
-# The HTML_FOOTER tag can be used to specify a personal HTML footer for
-# each generated HTML page. If it is left blank doxygen will generate a
-# standard footer.
-
-HTML_FOOTER =
-
-# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
-# style sheet that is used by each HTML page. It can be used to
-# fine-tune the look of the HTML output. If the tag is left blank doxygen
-# will generate a default style sheet. Note that doxygen will try to copy
-# the style sheet file to the HTML output directory, so don't put your own
-# stylesheet in the HTML output directory as well, or it will be erased!
-
-HTML_STYLESHEET =
-
-# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
-# files or namespaces will be aligned in HTML using tables. If set to
-# NO a bullet list will be used.
-
-HTML_ALIGN_MEMBERS = YES
-
-# If the GENERATE_HTMLHELP tag is set to YES, additional index files
-# will be generated that can be used as input for tools like the
-# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
-# of the generated HTML documentation.
-
-GENERATE_HTMLHELP = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
-# be used to specify the file name of the resulting .chm file. You
-# can add a path in front of the file if the result should not be
-# written to the html output directory.
-
-CHM_FILE =
-
-# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
-# be used to specify the location (absolute path including file name) of
-# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
-# the HTML help compiler on the generated index.hhp.
-
-HHC_LOCATION =
-
-# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
-# controls if a separate .chi index file is generated (YES) or that
-# it should be included in the master .chm file (NO).
-
-GENERATE_CHI = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
-# controls whether a binary table of contents is generated (YES) or a
-# normal table of contents (NO) in the .chm file.
-
-BINARY_TOC = NO
-
-# The TOC_EXPAND flag can be set to YES to add extra items for group members
-# to the contents of the HTML help documentation and to the tree view.
-
-TOC_EXPAND = NO
-
-# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
-# top of each HTML page. The value NO (the default) enables the index and
-# the value YES disables it.
-
-DISABLE_INDEX = NO
-
-# This tag can be used to set the number of enum values (range [1..20])
-# that doxygen will group on one line in the generated HTML documentation.
-
-ENUM_VALUES_PER_LINE = 4
-
-# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
-# generated containing a tree-like index structure (just like the one that
-# is generated for HTML Help). For this to work a browser that supports
-# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
-# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
-# probably better off using the HTML help feature.
-
-GENERATE_TREEVIEW = NO
-
-# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
-# used to set the initial width (in pixels) of the frame in which the tree
-# is shown.
-
-TREEVIEW_WIDTH = 250
-
-#---------------------------------------------------------------------------
-# configuration options related to the LaTeX output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
-# generate Latex output.
-
-GENERATE_LATEX = NO
-
-# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `latex' will be used as the default path.
-
-LATEX_OUTPUT = latex
-
-# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
-# invoked. If left blank `latex' will be used as the default command name.
-
-LATEX_CMD_NAME = latex
-
-# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
-# generate index for LaTeX. If left blank `makeindex' will be used as the
-# default command name.
-
-MAKEINDEX_CMD_NAME = makeindex
-
-# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
-# LaTeX documents. This may be useful for small projects and may help to
-# save some trees in general.
-
-COMPACT_LATEX = NO
-
-# The PAPER_TYPE tag can be used to set the paper type that is used
-# by the printer. Possible values are: a4, a4wide, letter, legal and
-# executive. If left blank a4wide will be used.
-
-PAPER_TYPE = a4wide
-
-# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
-# packages that should be included in the LaTeX output.
-
-EXTRA_PACKAGES =
-
-# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
-# the generated latex document. The header should contain everything until
-# the first chapter. If it is left blank doxygen will generate a
-# standard header. Notice: only use this tag if you know what you are doing!
-
-LATEX_HEADER =
-
-# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
-# is prepared for conversion to pdf (using ps2pdf). The pdf file will
-# contain links (just like the HTML output) instead of page references
-# This makes the output suitable for online browsing using a pdf viewer.
-
-PDF_HYPERLINKS = NO
-
-# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
-# plain latex in the generated Makefile. Set this option to YES to get a
-# higher quality PDF documentation.
-
-USE_PDFLATEX = NO
-
-# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
-# command to the generated LaTeX files. This will instruct LaTeX to keep
-# running if errors occur, instead of asking the user for help.
-# This option is also used when generating formulas in HTML.
-
-LATEX_BATCHMODE = NO
-
-# If LATEX_HIDE_INDICES is set to YES then doxygen will not
-# include the index chapters (such as File Index, Compound Index, etc.)
-# in the output.
-
-LATEX_HIDE_INDICES = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the RTF output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
-# The RTF output is optimized for Word 97 and may not look very pretty with
-# other RTF readers or editors.
-
-GENERATE_RTF = NO
-
-# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `rtf' will be used as the default path.
-
-RTF_OUTPUT = rtf
-
-# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
-# RTF documents. This may be useful for small projects and may help to
-# save some trees in general.
-
-COMPACT_RTF = NO
-
-# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
-# will contain hyperlink fields. The RTF file will
-# contain links (just like the HTML output) instead of page references.
-# This makes the output suitable for online browsing using WORD or other
-# programs which support those fields.
-# Note: wordpad (write) and others do not support links.
-
-RTF_HYPERLINKS = NO
-
-# Load stylesheet definitions from file. Syntax is similar to doxygen's
-# config file, i.e. a series of assignments. You only have to provide
-# replacements, missing definitions are set to their default value.
-
-RTF_STYLESHEET_FILE =
-
-# Set optional variables used in the generation of an rtf document.
-# Syntax is similar to doxygen's config file.
-
-RTF_EXTENSIONS_FILE =
-
-#---------------------------------------------------------------------------
-# configuration options related to the man page output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
-# generate man pages
-
-GENERATE_MAN = NO
-
-# The MAN_OUTPUT tag is used to specify where the man pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `man' will be used as the default path.
-
-MAN_OUTPUT = man
-
-# The MAN_EXTENSION tag determines the extension that is added to
-# the generated man pages (default is the subroutine's section .3)
-
-MAN_EXTENSION = .3
-
-# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
-# then it will generate one additional man file for each entity
-# documented in the real man page(s). These additional files
-# only source the real man page, but without them the man command
-# would be unable to find the correct page. The default is NO.
-
-MAN_LINKS = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the XML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_XML tag is set to YES Doxygen will
-# generate an XML file that captures the structure of
-# the code including all documentation.
-
-GENERATE_XML = NO
-
-# The XML_OUTPUT tag is used to specify where the XML pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `xml' will be used as the default path.
-
-XML_OUTPUT = xml
-
-# The XML_SCHEMA tag can be used to specify an XML schema,
-# which can be used by a validating XML parser to check the
-# syntax of the XML files.
-
-XML_SCHEMA =
-
-# The XML_DTD tag can be used to specify an XML DTD,
-# which can be used by a validating XML parser to check the
-# syntax of the XML files.
-
-XML_DTD =
-
-# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
-# dump the program listings (including syntax highlighting
-# and cross-referencing information) to the XML output. Note that
-# enabling this will significantly increase the size of the XML output.
-
-XML_PROGRAMLISTING = YES
-
-#---------------------------------------------------------------------------
-# configuration options for the AutoGen Definitions output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
-# generate an AutoGen Definitions (see autogen.sf.net) file
-# that captures the structure of the code including all
-# documentation. Note that this feature is still experimental
-# and incomplete at the moment.
-
-GENERATE_AUTOGEN_DEF = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the Perl module output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_PERLMOD tag is set to YES Doxygen will
-# generate a Perl module file that captures the structure of
-# the code including all documentation. Note that this
-# feature is still experimental and incomplete at the
-# moment.
-
-GENERATE_PERLMOD = NO
-
-# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
-# the necessary Makefile rules, Perl scripts and LaTeX code to be able
-# to generate PDF and DVI output from the Perl module output.
-
-PERLMOD_LATEX = NO
-
-# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
-# nicely formatted so it can be parsed by a human reader. This is useful
-# if you want to understand what is going on. On the other hand, if this
-# tag is set to NO the size of the Perl module output will be much smaller
-# and Perl will parse it just the same.
-
-PERLMOD_PRETTY = YES
-
-# The names of the make variables in the generated doxyrules.make file
-# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
-# This is useful so different doxyrules.make files included by the same
-# Makefile don't overwrite each other's variables.
-
-PERLMOD_MAKEVAR_PREFIX =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor
-#---------------------------------------------------------------------------
-
-# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
-# evaluate all C-preprocessor directives found in the sources and include
-# files.
-
-ENABLE_PREPROCESSING = YES
-
-# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
-# names in the source code. If set to NO (the default) only conditional
-# compilation will be performed. Macro expansion can be done in a controlled
-# way by setting EXPAND_ONLY_PREDEF to YES.
-
-MACRO_EXPANSION = YES
-
-# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
-# then the macro expansion is limited to the macros specified with the
-# PREDEFINED and EXPAND_AS_DEFINED tags.
-
-EXPAND_ONLY_PREDEF = YES
-
-# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
-# in the INCLUDE_PATH (see below) will be search if a #include is found.
-
-SEARCH_INCLUDES = YES
-
-# The INCLUDE_PATH tag can be used to specify one or more directories that
-# contain include files that are not input files but should be processed by
-# the preprocessor.
-
-INCLUDE_PATH =
-
-# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
-# patterns (like *.h and *.hpp) to filter out the header-files in the
-# directories. If left blank, the patterns specified with FILE_PATTERNS will
-# be used.
-
-INCLUDE_FILE_PATTERNS =
-
-# The PREDEFINED tag can be used to specify one or more macro names that
-# are defined before the preprocessor is started (similar to the -D option of
-# gcc). The argument of the tag is a list of macros of the form: name
-# or name=definition (no spaces). If the definition and the = are
-# omitted =1 is assumed. To prevent a macro definition from being
-# undefined via #undef or recursively expanded use the := operator
-# instead of the = operator.
-
-PREDEFINED = Q_SLOTS="slots" \
- Q_SIGNALS="signals"
-
-# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
-# this tag can be used to specify a list of macro names that should be expanded.
-# The macro definition that is found in the sources will be used.
-# Use the PREDEFINED tag if you want to use a different macro definition.
-
-EXPAND_AS_DEFINED =
-
-# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
-# doxygen's preprocessor will remove all function-like macros that are alone
-# on a line, have an all uppercase name, and do not end with a semicolon. Such
-# function macros are typically used for boiler-plate code, and will confuse
-# the parser if not removed.
-
-SKIP_FUNCTION_MACROS = YES
-
-#---------------------------------------------------------------------------
-# Configuration::additions related to external references
-#---------------------------------------------------------------------------
-
-# The TAGFILES option can be used to specify one or more tagfiles.
-# Optionally an initial location of the external documentation
-# can be added for each tagfile. The format of a tag file without
-# this location is as follows:
-# TAGFILES = file1 file2 ...
-# Adding location for the tag files is done as follows:
-# TAGFILES = file1=loc1 "file2 = loc2" ...
-# where "loc1" and "loc2" can be relative or absolute paths or
-# URLs. If a location is present for each tag, the installdox tool
-# does not have to be run to correct the links.
-# Note that each tag file must have a unique name
-# (where the name does NOT include the path)
-# If a tag file is not located in the directory in which doxygen
-# is run, you must also specify the path to the tagfile here.
-
-TAGFILES =
-
-# When a file name is specified after GENERATE_TAGFILE, doxygen will create
-# a tag file that is based on the input files it reads.
-
-GENERATE_TAGFILE =
-
-# If the ALLEXTERNALS tag is set to YES all external classes will be listed
-# in the class index. If set to NO only the inherited external classes
-# will be listed.
-
-ALLEXTERNALS = NO
-
-# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
-# in the modules index. If set to NO, only the current project's groups will
-# be listed.
-
-EXTERNAL_GROUPS = YES
-
-# The PERL_PATH should be the absolute path and name of the perl script
-# interpreter (i.e. the result of `which perl').
-
-PERL_PATH = /usr/bin/perl
-
-#---------------------------------------------------------------------------
-# Configuration options related to the dot tool
-#---------------------------------------------------------------------------
-
-# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
-# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
-# or super classes. Setting the tag to NO turns the diagrams off. Note that
-# this option is superseded by the HAVE_DOT option below. This is only a
-# fallback. It is recommended to install and use dot, since it yields more
-# powerful graphs.
-
-CLASS_DIAGRAMS = YES
-
-# If set to YES, the inheritance and collaboration graphs will hide
-# inheritance and usage relations if the target is undocumented
-# or is not a class.
-
-HIDE_UNDOC_RELATIONS = YES
-
-# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
-# available from the path. This tool is part of Graphviz, a graph visualization
-# toolkit from AT&T and Lucent Bell Labs. The other options in this section
-# have no effect if this option is set to NO (the default)
-
-HAVE_DOT = YES
-
-CALLER_GRAPH = NO
-
-# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for each documented class showing the direct and
-# indirect inheritance relations. Setting this tag to YES will force the
-# the CLASS_DIAGRAMS tag to NO.
-
-CLASS_GRAPH = YES
-
-# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for each documented class showing the direct and
-# indirect implementation dependencies (inheritance, containment, and
-# class references variables) of the class with other documented classes.
-
-COLLABORATION_GRAPH = YES
-
-# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for groups, showing the direct groups dependencies
-
-GROUP_GRAPHS = YES
-
-# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
-# collaboration diagrams in a style similar to the OMG's Unified Modeling
-# Language.
-
-UML_LOOK = NO
-
-# If set to YES, the inheritance and collaboration graphs will show the
-# relations between templates and their instances.
-
-TEMPLATE_RELATIONS = YES
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
-# tags are set to YES then doxygen will generate a graph for each documented
-# file showing the direct and indirect include dependencies of the file with
-# other documented files.
-
-INCLUDE_GRAPH = YES
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
-# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
-# documented header file showing the documented files that directly or
-# indirectly include this file.
-
-INCLUDED_BY_GRAPH = YES
-
-# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will
-# generate a call dependency graph for every global function or class method.
-# Note that enabling this option will significantly increase the time of a run.
-# So in most cases it will be better to enable call graphs for selected
-# functions only using the \callgraph command.
-
-CALL_GRAPH = NO
-
-# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
-# will graphical hierarchy of all classes instead of a textual one.
-
-GRAPHICAL_HIERARCHY = YES
-
-# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
-# then doxygen will show the dependencies a directory has on other directories
-# in a graphical way. The dependency relations are determined by the #include
-# relations between the files in the directories.
-
-DIRECTORY_GRAPH = YES
-
-# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
-# generated by dot. Possible values are png, jpg, or gif
-# If left blank png will be used.
-
-DOT_IMAGE_FORMAT = png
-
-# The tag DOT_PATH can be used to specify the path where the dot tool can be
-# found. If left blank, it is assumed the dot tool can be found in the path.
-
-DOT_PATH =
-
-# The DOTFILE_DIRS tag can be used to specify one or more directories that
-# contain dot files that are included in the documentation (see the
-# \dotfile command).
-
-DOTFILE_DIRS = schema/doc/
-
-# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
-# background. This is disabled by default, which results in a white background.
-# Warning: Depending on the platform used, enabling this option may lead to
-# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
-# read).
-
-DOT_TRANSPARENT = YES
-
-# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
-# files in one run (i.e. multiple -o and -T options on the command line). This
-# makes dot run faster, but since only newer versions of dot (>1.8.10)
-# support this, this feature is disabled by default.
-
-DOT_MULTI_TARGETS = YES
-
-# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
-# generate a legend page explaining the meaning of the various boxes and
-# arrows in the dot generated graphs.
-
-GENERATE_LEGEND = YES
-
-# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
-# remove the intermediate dot files that are used to generate
-# the various graphs.
-
-DOT_CLEANUP = YES
-
-#---------------------------------------------------------------------------
-# Configuration::additions related to the search engine
-#---------------------------------------------------------------------------
-
-# The SEARCHENGINE tag specifies whether or not a search engine should be
-# used. If set to NO the values of all tags below this one will be ignored.
-
-SEARCHENGINE = NO
diff --git a/src/datavis3d/Mainpage.dox b/src/datavis3d/Mainpage.dox
deleted file mode 100644
index 973bc46f..00000000
--- a/src/datavis3d/Mainpage.dox
+++ /dev/null
@@ -1,96 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtXmlPatterns module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** 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 Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-
-/**
- * @mainpage QtXmlPatterns -- an implementation of XML technologies
- *
- * - @ref Patternist_info
- * - @ref Patternist_writingDoxygen
- *
- * @section Patternist_info Overview
- *
- * This is the internal developer documentation for QtXmlPatterns. Please refer
- * to Qt Assistant for usage documentation.
- *
- * The documentation that you are reading right now, can be generated by
- * running <tt>doxygen</tt> in this directory without arguments. The generated
- * documentation can subsequently be browsed from
- * <tt>internal-docs/html/index.html</tt>.
- *
- * @subsection Patternist_writingDoxygen Doxygen Conventions
- *
- * Doxygen conventions, are as follows.
- *
- * - <tt>@@returns</tt> and <tt>@@param</tt> paragraphs are terminated with a period.
- * - When XPath or XQuery expressions/queries appears in the Doxygen comments, wrap them
- * in the @c tt HTML tag.
- * - Classes and free standing functions should have an <tt>@@author</tt> tag, specifying who
- * is the main author of it.
- * - No code examples should appear directly in the Doxygen comments, they should be included with
- * <tt>@@include</tt> or <tt>@@dontinclude</tt>.
- * - The following terms are marked with <tt>@@c</tt> or the @c tt HTML tag:
- * - @c NaN
- * - @c true and @c false, when referred to as boolean values
- * - All QNames and item types. For example, <tt>item\()</tt> and <tt>xs:string</tt>. Remember
- * to use the @c tt HTML tag in these cases in order to include non-trivial characters
- * such as paranteses
- * - @c null
- * - @c stderr, @c stdout, and @c stdin
- *
- *
- * The current Doxygen comments does in some cases not adhere to this, but the
- * idea is to harmonize in that direction over time.
- *
- * PatternistSDK, located in the test sources, is documented in the
- * PatternistSDK Doxygen module.
- *
- * @author Frans Englich <frans.englich@nokia.com>
- */
diff --git a/src/datavis3d/axis/axis.pri b/src/datavis3d/axis/axis.pri
new file mode 100644
index 00000000..7d5a1c6f
--- /dev/null
+++ b/src/datavis3d/axis/axis.pri
@@ -0,0 +1,12 @@
+HEADERS += \
+ $$PWD/qabstractaxis.h \
+ $$PWD/qabstractaxis_p.h \
+ $$PWD/qvalueaxis.h \
+ $$PWD/qvalueaxis_p.h \
+ $$PWD/qcategoryaxis.h \
+ $$PWD/qcategoryaxis_p.h
+
+SOURCES += \
+ $$PWD/qabstractaxis.cpp \
+ $$PWD/qvalueaxis.cpp \
+ $$PWD/qcategoryaxis.cpp
diff --git a/src/datavis3d/axis/qabstractaxis.cpp b/src/datavis3d/axis/qabstractaxis.cpp
new file mode 100644
index 00000000..71b9effd
--- /dev/null
+++ b/src/datavis3d/axis/qabstractaxis.cpp
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "qabstractaxis.h"
+#include "qabstractaxis_p.h"
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+QAbstractAxis::QAbstractAxis(QAbstractAxisPrivate *d) :
+ QObject(0),
+ d_ptr(d)
+{
+}
+
+QAbstractAxis::~QAbstractAxis()
+{
+}
+
+QString QAbstractAxis::title() const
+{
+ return d_ptr->m_title;
+}
+
+QStringList QAbstractAxis::labels() const
+{
+ return d_ptr->m_labels;
+}
+
+QAbstractAxis::AxisOrientation QAbstractAxis::orientation() const
+{
+ return d_ptr->m_orientation;
+}
+
+QAbstractAxis::AxisType QAbstractAxis::type() const
+{
+ return d_ptr->m_type;
+}
+
+void QAbstractAxis::setTitle(QString title)
+{
+ if (d_ptr->m_title != title) {
+ d_ptr->m_title = title;
+ emit titleChanged(title);
+ }
+}
+
+// QAbstractAxisPrivate
+
+QAbstractAxisPrivate::QAbstractAxisPrivate(QAbstractAxis *q, QAbstractAxis::AxisType type)
+ : QObject(0),
+ q_ptr(q),
+ m_orientation(QAbstractAxis::AxisOrientationNone),
+ m_type(type)
+{
+}
+
+QAbstractAxisPrivate::~QAbstractAxisPrivate()
+{
+}
+
+void QAbstractAxisPrivate::setOrientation(QAbstractAxis::AxisOrientation orientation)
+{
+ if (m_orientation == QAbstractAxis::AxisOrientationNone)
+ m_orientation = orientation;
+ else
+ Q_ASSERT("Attempted to reset axis orientation.");
+}
+
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/axis/qabstractaxis.h b/src/datavis3d/axis/qabstractaxis.h
new file mode 100644
index 00000000..4bc0ac16
--- /dev/null
+++ b/src/datavis3d/axis/qabstractaxis.h
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef QABSTRACTAXIS_H
+#define QABSTRACTAXIS_H
+
+#include <QtDataVis3D/qdatavis3denums.h>
+#include <QObject>
+#include <QScopedPointer>
+#include <QVector>
+#include <QStringList>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class QAbstractAxisPrivate;
+
+class QT_DATAVIS3D_EXPORT QAbstractAxis : public QObject
+{
+ Q_OBJECT
+ Q_ENUMS(AxisOrientation)
+ Q_ENUMS(AxisType)
+ Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged)
+ Q_PROPERTY(QStringList labels READ labels NOTIFY labelsChanged)
+ Q_PROPERTY(AxisOrientation orientation READ orientation)
+ Q_PROPERTY(AxisType type READ type)
+
+public:
+ enum AxisOrientation {
+ AxisOrientationNone = 0,
+ AxisOrientationX = 1,
+ AxisOrientationY = 2,
+ AxisOrientationZ = 4
+ };
+
+ enum AxisType {
+ AxisTypeNone = 0,
+ AxisTypeCategory = 1,
+ AxisTypeValue = 2
+ //AxisTypeLogValue = 6 // inherits valueaxis (4 + 2) // TODO
+ };
+
+protected:
+ explicit QAbstractAxis(QAbstractAxisPrivate *d);
+public:
+ virtual ~QAbstractAxis();
+
+ QString title() const;
+ QStringList labels() const;
+
+ AxisOrientation orientation() const;
+ AxisType type() const;
+
+public slots:
+ void setTitle(QString title);
+
+signals:
+ void titleChanged(QString newTitle);
+ void labelsChanged();
+
+protected:
+ QScopedPointer<QAbstractAxisPrivate> d_ptr;
+
+private:
+ Q_DISABLE_COPY(QAbstractAxis)
+
+ friend class Abstract3DController;
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif // QABSTRACTAXIS_H
diff --git a/src/datavis3d/axis/qabstractaxis_p.h b/src/datavis3d/axis/qabstractaxis_p.h
new file mode 100644
index 00000000..3866ee75
--- /dev/null
+++ b/src/datavis3d/axis/qabstractaxis_p.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#include "datavis3dglobal_p.h"
+#include "qabstractaxis.h"
+
+#ifndef QABSTRACTAXIS_P_H
+#define QABSTRACTAXIS_P_H
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class QAbstractAxisPrivate : public QObject
+{
+ Q_OBJECT
+public:
+ QAbstractAxisPrivate(QAbstractAxis *q, QAbstractAxis::AxisType type);
+ virtual ~QAbstractAxisPrivate();
+
+ void setOrientation(QAbstractAxis::AxisOrientation orientation);
+
+protected:
+ QAbstractAxis *q_ptr;
+
+ QString m_title;
+ QStringList m_labels;
+ QAbstractAxis::AxisOrientation m_orientation;
+ QAbstractAxis::AxisType m_type;
+
+ friend class QAbstractAxis;
+ friend class QValueAxis;
+ friend class QCategoryAxis;
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif // QABSTRACTAXIS_P_H
diff --git a/src/datavis3d/axis/qcategoryaxis.cpp b/src/datavis3d/axis/qcategoryaxis.cpp
new file mode 100644
index 00000000..c20eb80f
--- /dev/null
+++ b/src/datavis3d/axis/qcategoryaxis.cpp
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "qcategoryaxis.h"
+#include "qcategoryaxis_p.h"
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+QCategoryAxis::QCategoryAxis() :
+ QAbstractAxis(new QCategoryAxisPrivate(this))
+{
+}
+
+QCategoryAxis::~QCategoryAxis()
+{
+}
+
+QStringList QCategoryAxis::categoryLabels() const
+{
+ return labels();
+}
+
+void QCategoryAxis::setCategoryLabels(const QStringList &labels)
+{
+ if (d_ptr->m_labels != labels) {
+ d_ptr->m_labels = labels;
+ emit labelsChanged();
+ }
+}
+
+QCategoryAxisPrivate *QCategoryAxis::dptr()
+{
+ return static_cast<QCategoryAxisPrivate *>(d_ptr.data());
+}
+
+QCategoryAxisPrivate::QCategoryAxisPrivate(QCategoryAxis *q)
+ : QAbstractAxisPrivate(q, QAbstractAxis::AxisTypeCategory)
+{
+}
+
+QCategoryAxisPrivate::~QCategoryAxisPrivate()
+{
+}
+
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/axis/qcategoryaxis.h b/src/datavis3d/axis/qcategoryaxis.h
new file mode 100644
index 00000000..8d1e3f57
--- /dev/null
+++ b/src/datavis3d/axis/qcategoryaxis.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef QCATEGORYAXIS_H
+#define QCATEGORYAXIS_H
+
+#include <QtDataVis3D/qabstractaxis.h>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class QCategoryAxisPrivate;
+
+class QT_DATAVIS3D_EXPORT QCategoryAxis : public QAbstractAxis
+{
+ Q_OBJECT
+ // Note: categoryLabels actually reads/writes the labels property in abstract axis,
+ // which is read only there. Since subclass cannot have property with same name,
+ // this partially duplicate property is necessary.
+ Q_PROPERTY(QStringList categoryLabels READ categoryLabels WRITE setCategoryLabels)
+public:
+ explicit QCategoryAxis();
+ ~QCategoryAxis();
+
+ QStringList categoryLabels() const;
+
+public slots:
+ void setCategoryLabels(const QStringList &labels);
+
+protected:
+ QCategoryAxisPrivate *dptr();
+
+private:
+
+ Q_DISABLE_COPY(QCategoryAxis)
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif // QCATEGORYAXIS_H
diff --git a/src/datavis3d/axis/qcategoryaxis_p.h b/src/datavis3d/axis/qcategoryaxis_p.h
new file mode 100644
index 00000000..3ca79c64
--- /dev/null
+++ b/src/datavis3d/axis/qcategoryaxis_p.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#include "qcategoryaxis.h"
+#include "qabstractaxis_p.h"
+#include "qbardataitem.h"
+
+#ifndef QCATEGORYAXIS_P_H
+#define QCATEGORYAXIS_P_H
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class QCategoryAxisPrivate : public QAbstractAxisPrivate
+{
+ Q_OBJECT
+
+public:
+ QCategoryAxisPrivate(QCategoryAxis *q);
+ virtual ~QCategoryAxisPrivate();
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif // QCATEGORYAXIS_P_H
diff --git a/src/datavis3d/axis/qvalueaxis.cpp b/src/datavis3d/axis/qvalueaxis.cpp
new file mode 100644
index 00000000..cee8a5c7
--- /dev/null
+++ b/src/datavis3d/axis/qvalueaxis.cpp
@@ -0,0 +1,235 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "qvalueaxis.h"
+#include "qvalueaxis_p.h"
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+QValueAxis::QValueAxis() :
+ QAbstractAxis(new QValueAxisPrivate(this))
+{
+}
+
+QValueAxis::~QValueAxis()
+{
+}
+
+void QValueAxis::setRange(qreal min, qreal max)
+{
+ dptr()->setRange(min, max);
+ setAutoAdjustRange(false);
+}
+
+void QValueAxis::setMin(qreal min)
+{
+ dptr()->setMin(min);
+ setAutoAdjustRange(false);
+}
+
+void QValueAxis::setMax(qreal max)
+{
+ dptr()->setMax(max);
+ setAutoAdjustRange(false);
+}
+
+qreal QValueAxis::min() const
+{
+ return dptrc()->m_min;
+}
+
+qreal QValueAxis::max() const
+{
+ return dptrc()->m_max;
+}
+
+void QValueAxis::setSegmentCount(int count)
+{
+ if (count <= 0) {
+ qWarning() << "Warning: Illegal segment count automatically adjusted to a legal one:"
+ << count << "-> 1";
+ count = 1;
+ }
+ if (dptr()->m_segmentCount != count){
+ dptr()->m_segmentCount = count;
+ dptr()->recreateLabels();
+ emit segmentCountChanged(count);
+ }
+}
+
+int QValueAxis::segmentCount() const
+{
+ return dptrc()->m_segmentCount;
+}
+
+void QValueAxis::setSubSegmentCount(int count)
+{
+ if (count <= 0) {
+ qWarning() << "Warning: Illegal subsegment count automatically adjusted to a legal one:"
+ << count << "-> 1";
+ count = 1;
+ }
+ if (dptr()->m_subSegmentCount != count) {
+ dptr()->m_subSegmentCount = count;
+ emit subSegmentCountChanged(count);
+ }
+}
+
+int QValueAxis::subSegmentCount() const
+{
+ return dptrc()->m_subSegmentCount;
+}
+
+void QValueAxis::setAutoAdjustRange(bool autoAdjust)
+{
+ if (dptr()->m_autoAdjust != autoAdjust) {
+ dptr()->m_autoAdjust = autoAdjust;
+ emit autoAdjustRangeChanged(autoAdjust);
+ }
+}
+
+bool QValueAxis::isAutoAdjustRange() const
+{
+ return dptrc()->m_autoAdjust;
+}
+
+void QValueAxis::setLabelFormat(const QString &format)
+{
+ if (dptr()->m_labelFormat != format) {
+ dptr()->m_labelFormat = format;
+ dptr()->recreateLabels();
+ emit labelFormatChanged(format);
+ }
+}
+
+QString QValueAxis::labelFormat() const
+{
+ return dptrc()->m_labelFormat;
+}
+
+QValueAxisPrivate *QValueAxis::dptr()
+{
+ return static_cast<QValueAxisPrivate *>(d_ptr.data());
+}
+
+const QValueAxisPrivate *QValueAxis::dptrc() const
+{
+ return static_cast<const QValueAxisPrivate *>(d_ptr.data());
+}
+
+QValueAxisPrivate::QValueAxisPrivate(QValueAxis *q)
+ : QAbstractAxisPrivate(q, QAbstractAxis::AxisTypeValue),
+ m_min(0.0),
+ m_max(10.0),
+ m_segmentCount(5),
+ m_subSegmentCount(1),
+ m_autoAdjust(true)
+{
+}
+
+QValueAxisPrivate::~QValueAxisPrivate()
+{
+}
+
+void QValueAxisPrivate::setRange(qreal min, qreal max)
+{
+ // If min >= max, we adjust ranges so that
+ // m_max becomes (min + 1.0)
+ // as axes need some kind of valid range.
+ // TODO: Make "reverse" axes work (i.e. min > max)
+ bool dirty = false;
+ if (m_min != min) {
+ m_min = min;
+ dirty = true;
+ }
+ if (m_max != max) {
+ if (min >= max) {
+ m_max = min + 1.0;
+ qWarning() << "Warning: Tried to set invalid range for value axis."
+ " Range automatically adjusted to a valid one:"
+ << min << "-" << max << "-->" << m_min << "-" << m_max;
+ } else {
+ m_max = max;
+ }
+ dirty = true;
+ }
+ if (dirty) {
+ recreateLabels();
+ emit qptr()->rangeChanged(min, max);
+ }
+}
+
+void QValueAxisPrivate::setMin(qreal min)
+{
+ if (m_min != min) {
+ if (min >= m_max) {
+ qreal oldMax = m_max;
+ m_max = min + 1.0;
+ qWarning() << "Warning: Tried to set minimum to equal or larger than maximum for"
+ " value axis. Maximum automatically adjusted to a valid one:"
+ << oldMax << "-->" << m_max;
+ }
+ m_min = min;
+ recreateLabels();
+ emit qptr()->rangeChanged(m_min, m_max);
+ }
+}
+
+void QValueAxisPrivate::setMax(qreal max)
+{
+ if (m_max != max) {
+ if (max <= m_min) {
+ qreal oldMin = m_min;
+ m_min = max - 1.0;
+ qWarning() << "Warning: Tried to set maximum to equal or smaller than minimum for"
+ " value axis. Minimum automatically adjusted to a valid one:"
+ << oldMin << "-->" << m_min;
+ }
+ m_max = max;
+ recreateLabels();
+ emit qptr()->rangeChanged(m_min, m_max);
+ }
+}
+
+void QValueAxisPrivate::recreateLabels()
+{
+ QStringList newLabels;
+ newLabels.reserve(m_segmentCount + 1);
+
+ // First label is at axis min, which is an extra segment
+ qreal segmentStep = (m_max - m_min) / m_segmentCount;
+
+ for (int i = 0; i < m_segmentCount; i++) {
+ // TODO Actually do proper formatting
+ newLabels.append(QString::number(m_min + (segmentStep * i)));
+ }
+ // Ensure max label doesn't suffer from any rounding errors
+ newLabels.append(QString::number(m_max));
+
+ if (m_labels != newLabels) {
+ m_labels = newLabels;
+ emit q_ptr->labelsChanged();
+ }
+}
+
+QValueAxis *QValueAxisPrivate::qptr()
+{
+ return static_cast<QValueAxis *>(q_ptr);
+}
+
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/axis/qvalueaxis.h b/src/datavis3d/axis/qvalueaxis.h
new file mode 100644
index 00000000..c9658f37
--- /dev/null
+++ b/src/datavis3d/axis/qvalueaxis.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef QVALUEAXIS_H
+#define QVALUEAXIS_H
+
+#include <QtDataVis3D/qabstractaxis.h>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class QValueAxisPrivate;
+
+class QT_DATAVIS3D_EXPORT QValueAxis : public QAbstractAxis
+{
+ Q_OBJECT
+ Q_PROPERTY(qreal min READ min WRITE setMin NOTIFY rangeChanged)
+ Q_PROPERTY(qreal max READ max WRITE setMax NOTIFY rangeChanged)
+ Q_PROPERTY(int segmentCount READ segmentCount WRITE setSegmentCount NOTIFY segmentCountChanged)
+ Q_PROPERTY(int subSegmentCount READ subSegmentCount WRITE setSubSegmentCount NOTIFY subSegmentCountChanged)
+ Q_PROPERTY(bool autoAdjustRange READ isAutoAdjustRange WRITE setAutoAdjustRange NOTIFY autoAdjustRangeChanged)
+ Q_PROPERTY(QString labelFormat READ labelFormat WRITE setLabelFormat NOTIFY labelFormatChanged)
+
+public:
+ explicit QValueAxis();
+ ~QValueAxis();
+
+ qreal min() const;
+ qreal max() const;
+ int segmentCount() const;
+ int subSegmentCount() const;
+ bool isAutoAdjustRange() const;
+ QString labelFormat() const;
+
+public slots:
+ void setRange(qreal min, qreal max);
+ void setMin(qreal min);
+ void setMax(qreal max);
+ void setSegmentCount(int count);
+ void setSubSegmentCount(int count);
+ void setAutoAdjustRange(bool autoAdjust);
+ void setLabelFormat(const QString &format);
+
+signals:
+ void rangeChanged(qreal min, qreal max);
+ void segmentCountChanged(int count);
+ void subSegmentCountChanged(int count);
+ void autoAdjustRangeChanged(bool autoAdjust);
+ void labelFormatChanged(QString format);
+
+protected:
+ QValueAxisPrivate *dptr();
+ const QValueAxisPrivate *dptrc() const;
+
+private:
+ Q_DISABLE_COPY(QValueAxis)
+ friend class Bars3dController;
+ friend class Scatter3DController;
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif // QVALUEAXIS_H
diff --git a/src/datavis3d/axis/qvalueaxis_p.h b/src/datavis3d/axis/qvalueaxis_p.h
new file mode 100644
index 00000000..f730d0c0
--- /dev/null
+++ b/src/datavis3d/axis/qvalueaxis_p.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#include "qvalueaxis.h"
+#include "qabstractaxis_p.h"
+
+#ifndef QVALUEAXIS_P_H
+#define QVALUEAXIS_P_H
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class QValueAxisPrivate : public QAbstractAxisPrivate
+{
+ Q_OBJECT
+
+public:
+ QValueAxisPrivate(QValueAxis *q);
+ virtual ~QValueAxisPrivate();
+
+ void setRange(qreal min, qreal max);
+ void setMin(qreal min);
+ void setMax (qreal max);
+
+protected:
+ void recreateLabels();
+
+ qreal m_min;
+ qreal m_max;
+ int m_segmentCount;
+ int m_subSegmentCount;
+ bool m_autoAdjust;
+ QString m_labelFormat;
+
+private:
+ QValueAxis *qptr();
+
+ friend class QValueAxis;
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif // QVALUEAXIS_P_H
diff --git a/src/datavis3d/common.pri b/src/datavis3d/common.pri
index 8532fc77..57948697 100644
--- a/src/datavis3d/common.pri
+++ b/src/datavis3d/common.pri
@@ -3,5 +3,6 @@
INCLUDEPATH += $$PWD/engine \
$$PWD/global \
- $$PWD/utils
-
+ $$PWD/utils \
+ $$PWD/axis \
+ $$PWD/data
diff --git a/src/datavis3d/data/abstractrenderitem.cpp b/src/datavis3d/data/abstractrenderitem.cpp
new file mode 100644
index 00000000..004fb598
--- /dev/null
+++ b/src/datavis3d/data/abstractrenderitem.cpp
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "abstractrenderitem_p.h"
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+AbstractRenderItem::AbstractRenderItem()
+ : m_labelItem(0),
+ m_selectionLabel(0)
+{
+}
+
+AbstractRenderItem::~AbstractRenderItem()
+{
+ delete m_labelItem;
+ delete m_selectionLabel;
+}
+
+LabelItem &AbstractRenderItem::labelItem()
+{
+ if (!m_labelItem)
+ m_labelItem = new LabelItem;
+ return *m_labelItem;
+}
+
+LabelItem &AbstractRenderItem::selectionLabel()
+{
+ if (!m_selectionLabel)
+ m_selectionLabel = new LabelItem;
+ return *m_selectionLabel;
+}
+
+QString &AbstractRenderItem::label()
+{
+ if (m_label.isNull())
+ formatLabel();
+ return m_label;
+}
+
+void AbstractRenderItem::setLabel(const QString &label)
+{
+ if (m_labelItem)
+ m_labelItem->clear();
+ if (m_selectionLabel)
+ m_selectionLabel->clear();
+ m_label = label;
+}
+
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/data/abstractrenderitem_p.h b/src/datavis3d/data/abstractrenderitem_p.h
new file mode 100644
index 00000000..4bf4df71
--- /dev/null
+++ b/src/datavis3d/data/abstractrenderitem_p.h
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef ABSTRACTRENDERITEM_P_H
+#define ABSTRACTRENDERITEM_P_H
+
+#include "datavis3dglobal_p.h"
+#include "labelitem_p.h"
+
+#include <QOpenGLFunctions>
+#include <QString>
+#include <QVector3D>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class AbstractRenderItem
+{
+public:
+ AbstractRenderItem();
+ virtual ~AbstractRenderItem();
+
+ // Position in 3D scene
+ inline void setTranslation(const QVector3D &translation) { m_translation = translation; }
+ inline const QVector3D &translation() const {return m_translation; }
+
+ // Label item for formatted label
+ LabelItem &labelItem();
+
+ // Selection label item (containing special selection texture, if mode is activated)
+ LabelItem &selectionLabel();
+
+ // Formatted label for item.
+ void setLabel(const QString &label);
+ QString &label(); // Formats label if not previously formatted
+
+protected:
+ virtual void formatLabel() = 0;
+
+ QString m_label;
+ QVector3D m_translation;
+ LabelItem *m_labelItem;
+ LabelItem *m_selectionLabel;
+
+ friend class QAbstractDataItem;
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/data/barrenderitem.cpp b/src/datavis3d/data/barrenderitem.cpp
new file mode 100644
index 00000000..db377aa3
--- /dev/null
+++ b/src/datavis3d/data/barrenderitem.cpp
@@ -0,0 +1,46 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "barrenderitem_p.h"
+#include "bars3drenderer_p.h"
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+BarRenderItem::BarRenderItem()
+ : AbstractRenderItem(),
+ m_renderer(0),
+ m_value(0)
+{
+}
+
+BarRenderItem::~BarRenderItem()
+{
+}
+
+void BarRenderItem::formatLabel()
+{
+ // Format the string on first access
+ QString numStr;
+ numStr.setNum(m_value);
+ // TODO actually format instead of just prepending the value
+ m_label.clear(); // Just in case
+ m_label.append(numStr);
+ m_label.append(m_renderer->itemLabelFormat()); // TODO format needs to be cached
+}
+
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/data/barrenderitem_p.h b/src/datavis3d/data/barrenderitem_p.h
new file mode 100644
index 00000000..babab795
--- /dev/null
+++ b/src/datavis3d/data/barrenderitem_p.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef BARRENDERITEM_P_H
+#define BARRENDERITEM_P_H
+
+#include "abstractrenderitem_p.h"
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class Bars3dRenderer;
+
+class BarRenderItem : public AbstractRenderItem
+{
+public:
+ BarRenderItem();
+ virtual ~BarRenderItem();
+
+ // Position relative to data window (for bar label generation)
+ inline void setPosition(const QPoint &pos) { m_position = pos; }
+ inline const QPoint &position() const { return m_position; }
+
+ // Actual cached data value of the bar (needed to trigger label reformats)
+ inline void setValue(qreal value);
+ inline qreal value() const { return m_value; }
+
+ // Normalized bar height
+ inline void setHeight(GLfloat height) { m_height = height; }
+ inline GLfloat height() const { return m_height; }
+
+ // TODO should be in abstract, but currently there is no abstract renderer
+ inline void setRenderer(Bars3dRenderer *renderer) { m_renderer = renderer; }
+
+protected:
+ virtual void formatLabel();
+
+ Bars3dRenderer *m_renderer;
+ qreal m_value;
+ QPoint m_position; // x = row, y = column
+ GLfloat m_height;
+
+ friend class QBarDataItem;
+};
+
+void BarRenderItem::setValue(qreal value)
+{
+ if (m_value != value) {
+ m_value = value;
+ if (!m_label.isNull())
+ setLabel(QString()); // Forces reformatting on next access
+ }
+}
+
+typedef QVector<BarRenderItem> BarRenderItemRow;
+typedef QVector<BarRenderItemRow> BarRenderItemArray;
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/data/data.pri b/src/datavis3d/data/data.pri
new file mode 100644
index 00000000..a3b28e6e
--- /dev/null
+++ b/src/datavis3d/data/data.pri
@@ -0,0 +1,52 @@
+HEADERS += \
+ $$PWD/labelitem_p.h \
+ $$PWD/qabstractdataproxy.h \
+ $$PWD/qabstractdataproxy_p.h \
+ $$PWD/qbardataproxy.h \
+ $$PWD/qbardataproxy_p.h \
+ $$PWD/abstractrenderitem_p.h \
+ $$PWD/barrenderitem_p.h \
+ $$PWD/qbardataitem.h \
+ $$PWD/qbardataitem_p.h \
+ $$PWD/qitemmodelbardatamapping.h \
+ $$PWD/qitemmodelbardatamapping_p.h \
+ $$PWD/qitemmodelbardataproxy_p.h \
+ $$PWD/qitemmodelbardataproxy.h \
+ $$PWD/maprenderitem_p.h \
+ $$PWD/qmapdataitem.h \
+ $$PWD/qmapdataitem_p.h \
+ $$PWD/qmapdataproxy.h \
+ $$PWD/qmapdataproxy_p.h \
+ $$PWD/scatterrenderitem_p.h \
+ $$PWD/qscatterdataitem.h \
+ $$PWD/qscatterdataitem_p.h \
+ $$PWD/qscatterdataproxy.h \
+ $$PWD/qscatterdataproxy_p.h \
+ $$PWD/qitemmodelmapdatamapping.h \
+ $$PWD/qitemmodelmapdatamapping_p.h \
+ $$PWD/qitemmodelmapdataproxy.h \
+ $$PWD/qitemmodelmapdataproxy_p.h \
+ $$PWD/qitemmodelscatterdatamapping.h \
+ $$PWD/qitemmodelscatterdatamapping_p.h \
+ $$PWD/qitemmodelscatterdataproxy.h \
+ $$PWD/qitemmodelscatterdataproxy_p.h
+
+SOURCES += \
+ $$PWD/labelitem.cpp \
+ $$PWD/qabstractdataproxy.cpp \
+ $$PWD/qbardataproxy.cpp \
+ $$PWD/abstractrenderitem.cpp \
+ $$PWD/barrenderitem.cpp \
+ $$PWD/qbardataitem.cpp \
+ $$PWD/qitemmodelbardatamapping.cpp \
+ $$PWD/qitemmodelbardataproxy.cpp \
+ $$PWD/maprenderitem.cpp \
+ $$PWD/qmapdataitem.cpp \
+ $$PWD/qmapdataproxy.cpp \
+ $$PWD/scatterrenderitem.cpp \
+ $$PWD/qscatterdataitem.cpp \
+ $$PWD/qscatterdataproxy.cpp \
+ $$PWD/qitemmodelmapdatamapping.cpp \
+ $$PWD/qitemmodelmapdataproxy.cpp \
+ $$PWD/qitemmodelscatterdatamapping.cpp \
+ $$PWD/qitemmodelscatterdataproxy.cpp
diff --git a/src/datavis3d/data/labelitem.cpp b/src/datavis3d/data/labelitem.cpp
new file mode 100644
index 00000000..1d1bf6f7
--- /dev/null
+++ b/src/datavis3d/data/labelitem.cpp
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "labelitem_p.h"
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+LabelItem::LabelItem()
+ : m_size(QSize(0, 0)),
+ m_textureId(0)
+{
+}
+
+LabelItem::~LabelItem()
+{
+ glDeleteTextures(1, &m_textureId);
+}
+
+void LabelItem::setSize(const QSize &size)
+{
+ m_size = size;
+}
+
+QSize LabelItem::size() const
+{
+ return m_size;
+}
+
+void LabelItem::setTextureId(GLuint textureId)
+{
+ glDeleteTextures(1, &m_textureId);
+ m_textureId = textureId;
+}
+
+GLuint LabelItem::textureId() const
+{
+ return m_textureId;
+}
+
+void LabelItem::clear()
+{
+ if (m_textureId) {
+ glDeleteTextures(1, &m_textureId);
+ m_textureId = 0;
+ }
+ m_size = QSize(0, 0);
+}
+
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/data/labelitem_p.h b/src/datavis3d/data/labelitem_p.h
new file mode 100644
index 00000000..84625002
--- /dev/null
+++ b/src/datavis3d/data/labelitem_p.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef LABELITEM_P_H
+#define LABELITEM_P_H
+
+#include "datavis3dglobal_p.h"
+#include <QOpenGLFunctions>
+#include <QSize>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class LabelItem
+{
+public:
+ explicit LabelItem();
+ ~LabelItem();
+
+ void setSize(const QSize &size);
+ QSize size() const;
+ void setTextureId(GLuint textureId);
+ GLuint textureId() const;
+ void clear();
+
+private:
+ Q_DISABLE_COPY(LabelItem);
+
+ QSize m_size;
+ GLuint m_textureId;
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/data/maprenderitem.cpp b/src/datavis3d/data/maprenderitem.cpp
new file mode 100644
index 00000000..c7165104
--- /dev/null
+++ b/src/datavis3d/data/maprenderitem.cpp
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "maprenderitem_p.h"
+#include "maps3drenderer_p.h" // TODO remove when maps refactored
+#include "maps3dcontroller_p.h" // TODO should be renderer
+#include "qmapdataproxy.h"
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+MapRenderItem::MapRenderItem()
+ : BarRenderItem()
+{
+}
+
+MapRenderItem::~MapRenderItem()
+{
+}
+
+void MapRenderItem::formatLabel()
+{
+ // TODO The label format specified in proxy should probably have additional custom formatting
+ // TODO specifiers in addition to standard printf specifiers for placement of item labels
+ // TODO and selection data (like row/column in bar selection)
+
+ // Format the string on first access
+ QString numStr;
+ numStr.setNum(m_value);
+ // TODO actually format instead of just prepending the value
+ m_label.clear(); // Just in case
+ m_label.append(m_itemLabel);
+ m_label.append(QStringLiteral(" "));
+ m_label.append(numStr);
+ m_label.append(m_renderer->dataProxy()->itemLabelFormat());
+}
+
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/data/maprenderitem_p.h b/src/datavis3d/data/maprenderitem_p.h
new file mode 100644
index 00000000..f1e7290e
--- /dev/null
+++ b/src/datavis3d/data/maprenderitem_p.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef MAPRENDERITEM_P_H
+#define MAPRENDERITEM_P_H
+
+#include "barrenderitem_p.h"
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class Maps3DRenderer;
+class Maps3DController; // TODO remove when maps refactored
+
+class MapRenderItem : public BarRenderItem
+{
+public:
+ MapRenderItem();
+ virtual ~MapRenderItem();
+
+ inline const QPointF &mapPosition() const { return m_mapPosition; }
+ inline void setMapPosition(const QPointF &pos) { m_mapPosition = pos; }
+
+ inline const QString &itemLabel() const { return m_itemLabel; }
+ inline void setItemLabel(const QString &label) { m_itemLabel = label; }
+
+ // TODO should be in abstract, but currently there is no abstract renderer
+ // TODO change when maps refactored
+ inline void setRenderer(Maps3DController *renderer) { m_renderer = renderer; }
+
+protected:
+ virtual void formatLabel();
+
+ Maps3DController *m_renderer;
+ QPointF m_mapPosition;
+ QString m_itemLabel; // from QMapDataItem::label() - unformatted item label
+
+ friend class QMapDataItem;
+};
+
+typedef QVector<MapRenderItem> MapRenderItemArray;
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/data/qabstractdataproxy.cpp b/src/datavis3d/data/qabstractdataproxy.cpp
new file mode 100644
index 00000000..11874edb
--- /dev/null
+++ b/src/datavis3d/data/qabstractdataproxy.cpp
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "qabstractdataproxy.h"
+#include "qabstractdataproxy_p.h"
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+QAbstractDataProxy::QAbstractDataProxy(QAbstractDataProxyPrivate *d) :
+ QObject(0),
+ d_ptr(d)
+{
+}
+
+QAbstractDataProxy::~QAbstractDataProxy()
+{
+}
+
+QAbstractDataProxy::DataType QAbstractDataProxy::type() const
+{
+ return d_ptr->m_type;
+}
+
+void QAbstractDataProxy::setItemLabelFormat(const QString &format)
+{
+ d_ptr->setItemLabelFormat(format);
+ emit itemLabelFormatChanged();
+}
+
+QString QAbstractDataProxy::itemLabelFormat() const
+{
+ return d_ptr->m_itemLabelFormat;
+}
+
+// QAbstractDataProxyPrivate
+
+QAbstractDataProxyPrivate::QAbstractDataProxyPrivate(QAbstractDataProxy *q, QAbstractDataProxy::DataType type)
+ : QObject(0),
+ q_ptr(q),
+ m_type(type)
+{
+}
+
+QAbstractDataProxyPrivate::~QAbstractDataProxyPrivate()
+{
+}
+
+void QAbstractDataProxyPrivate::setItemLabelFormat(const QString &format)
+{
+ m_itemLabelFormat = format;
+}
+
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/data/qabstractdataproxy.h b/src/datavis3d/data/qabstractdataproxy.h
new file mode 100644
index 00000000..0e717dbb
--- /dev/null
+++ b/src/datavis3d/data/qabstractdataproxy.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef QABSTRACTDATAPROXY_H
+#define QABSTRACTDATAPROXY_H
+
+#include <QtDataVis3D/qdatavis3denums.h>
+#include <QObject>
+#include <QScopedPointer>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class QAbstractDataProxyPrivate;
+
+class QT_DATAVIS3D_EXPORT QAbstractDataProxy : public QObject
+{
+ Q_OBJECT
+ Q_ENUMS(DataType)
+ Q_PROPERTY(DataType type READ type)
+
+public:
+ enum DataType {
+ DataTypeNone = 0,
+ DataTypeBar = 1,
+ DataTypeMap = 2,
+ DataTypeScatter = 4,
+ DataTypeSurface = 8
+ };
+
+protected:
+ explicit QAbstractDataProxy(QAbstractDataProxyPrivate *d);
+public:
+ virtual ~QAbstractDataProxy();
+
+ DataType type() const;
+
+ // Items use this string to format single item labels, unless custom proxy initializes
+ // item labels with something else.
+ void setItemLabelFormat(const QString &format);
+ QString itemLabelFormat() const;
+
+signals:
+ void itemLabelFormatChanged();
+
+protected:
+ QScopedPointer<QAbstractDataProxyPrivate> d_ptr;
+
+private:
+ Q_DISABLE_COPY(QAbstractDataProxy)
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif // QABSTRACTDATAPROXY_H
diff --git a/src/datavis3d/data/qabstractdataproxy_p.h b/src/datavis3d/data/qabstractdataproxy_p.h
new file mode 100644
index 00000000..eda13b86
--- /dev/null
+++ b/src/datavis3d/data/qabstractdataproxy_p.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#include "datavis3dglobal_p.h"
+#include "qabstractdataproxy.h"
+#include <QString>
+
+#ifndef QABSTRACTDATAPROXY_P_H
+#define QABSTRACTDATAPROXY_P_H
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class QAbstractDataProxyPrivate : public QObject
+{
+ Q_OBJECT
+public:
+ QAbstractDataProxyPrivate(QAbstractDataProxy *q, QAbstractDataProxy::DataType type);
+ virtual ~QAbstractDataProxyPrivate();
+
+ void setItemLabelFormat(const QString &format);
+
+protected:
+ QAbstractDataProxy *q_ptr;
+ QAbstractDataProxy::DataType m_type;
+ QString m_itemLabelFormat;
+
+private:
+ friend class QAbstractDataProxy;
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif // QABSTRACTDATAPROXY_P_H
diff --git a/src/datavis3d/data/qbardataitem.cpp b/src/datavis3d/data/qbardataitem.cpp
new file mode 100644
index 00000000..1e8f3d95
--- /dev/null
+++ b/src/datavis3d/data/qbardataitem.cpp
@@ -0,0 +1,99 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "qbardataitem_p.h"
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+/*!
+ * \class QBarDataItem
+ * \inmodule QtDataVis3D
+ * \brief The QBarDataItem class provides a container for resolved data to be added to bar graphs.
+ * \since 1.0.0
+ *
+ * A QBarDataItem holds data for a single rendered bar in a graph.
+ * Bar data proxies parse data into QBarDataItem instances for visualizing.
+ *
+ * \sa QBarDataProxy, {Qt Data Visualization 3D C++ Classes}
+ */
+
+/*!
+ * Constructs QBarDataItem.
+ */
+QBarDataItem::QBarDataItem()
+ : d_ptr(0), // private data doesn't exist by default (optimization)
+ m_value(0.0)
+{
+}
+
+QBarDataItem::QBarDataItem(qreal value)
+ : d_ptr(0),
+ m_value(value)
+{
+}
+
+QBarDataItem::QBarDataItem(const QBarDataItem &other)
+{
+ operator=(other);
+}
+
+/*!
+ * Destroys QBarDataItem.
+ */
+QBarDataItem::~QBarDataItem()
+{
+ delete d_ptr;
+}
+
+QBarDataItem &QBarDataItem::operator=(const QBarDataItem &other)
+{
+ m_value = other.m_value;
+ if (other.d_ptr)
+ createExtraData();
+ else
+ d_ptr = 0;
+ // TODO set extra data
+ return *this;
+}
+
+void QBarDataItem::setValue(qreal value)
+{
+ m_value = value;
+}
+
+qreal QBarDataItem::value() const
+{
+ return m_value;
+}
+
+void QBarDataItem::createExtraData()
+{
+ if (!d_ptr)
+ d_ptr = new QBarDataItemPrivate;
+}
+
+
+QBarDataItemPrivate::QBarDataItemPrivate()
+{
+}
+
+QBarDataItemPrivate::~QBarDataItemPrivate()
+{
+}
+
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/data/qbardataitem.h b/src/datavis3d/data/qbardataitem.h
new file mode 100644
index 00000000..d7062b66
--- /dev/null
+++ b/src/datavis3d/data/qbardataitem.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef QBARDATAITEM_H
+#define QBARDATAITEM_H
+
+#include <QtDataVis3D/qdatavis3denums.h>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class QBarDataItemPrivate;
+
+class QT_DATAVIS3D_EXPORT QBarDataItem
+{
+public:
+ QBarDataItem();
+ QBarDataItem(qreal value);
+ QBarDataItem(const QBarDataItem &other);
+ ~QBarDataItem();
+
+ QBarDataItem &operator=(const QBarDataItem &other);
+
+ void setValue(qreal value);
+ qreal value() const;
+
+ // TODO Set color, label format, ...?
+
+protected:
+ virtual void createExtraData();
+
+ QBarDataItemPrivate *d_ptr;
+
+private:
+ qreal m_value;
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/data/qbardataitem_p.h b/src/datavis3d/data/qbardataitem_p.h
new file mode 100644
index 00000000..e63ce787
--- /dev/null
+++ b/src/datavis3d/data/qbardataitem_p.h
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef QBARDATAITEM_P_H
+#define QBARDATAITEM_P_H
+
+#include "datavis3dglobal_p.h"
+#include "qbardataitem.h"
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class QBarDataItemPrivate
+{
+public:
+ QBarDataItemPrivate();
+ virtual ~QBarDataItemPrivate();
+
+ // TODO stores other data for bars besides value
+
+protected:
+ friend class QBarDataItem;
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/data/qbardataproxy.cpp b/src/datavis3d/data/qbardataproxy.cpp
new file mode 100644
index 00000000..589ed37a
--- /dev/null
+++ b/src/datavis3d/data/qbardataproxy.cpp
@@ -0,0 +1,262 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "qbardataproxy.h"
+#include "qbardataproxy_p.h"
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+QBarDataProxy::QBarDataProxy() :
+ QAbstractDataProxy(new QBarDataProxyPrivate(this))
+{
+}
+
+QBarDataProxy::QBarDataProxy(QBarDataProxyPrivate *d) :
+ QAbstractDataProxy(d)
+{
+}
+
+QBarDataProxy::~QBarDataProxy()
+{
+}
+
+void QBarDataProxy::resetArray(QBarDataArray *newArray)
+{
+ if (dptr()->resetArray(newArray))
+ emit arrayReset();
+}
+
+void QBarDataProxy::setRow(int rowIndex, QBarDataRow *row)
+{
+ dptr()->setRow(rowIndex, row);
+ emit rowsChanged(rowIndex, 1);
+}
+
+void QBarDataProxy::setRows(int rowIndex, const QBarDataArray &rows)
+{
+ dptr()->setRows(rowIndex, rows);
+ emit rowsChanged(rowIndex, rows.size());
+}
+
+void QBarDataProxy::setItem(int rowIndex, int columnIndex, const QBarDataItem &item)
+{
+ dptr()->setItem(rowIndex, columnIndex, item);
+ emit itemChanged(rowIndex, columnIndex);
+}
+
+int QBarDataProxy::addRow(QBarDataRow *row)
+{
+ int addIndex = dptr()->addRow(row);
+ emit rowsAdded(addIndex, 1);
+ return addIndex;
+}
+
+int QBarDataProxy::addRows(const QBarDataArray &rows)
+{
+ int addIndex = dptr()->addRows(rows);
+ emit rowsAdded(addIndex, rows.size());
+ return addIndex;
+}
+
+void QBarDataProxy::insertRow(int rowIndex, QBarDataRow *row)
+{
+ dptr()->insertRow(rowIndex, row);
+ emit rowsInserted(rowIndex, 1);
+}
+
+void QBarDataProxy::insertRows(int rowIndex, const QBarDataArray &rows)
+{
+ dptr()->insertRows(rowIndex, rows);
+ emit rowsInserted(rowIndex, rows.size());
+}
+
+void QBarDataProxy::removeRows(int rowIndex, int removeCount)
+{
+ if (rowIndex < rowCount()) {
+ dptr()->removeRows(rowIndex, removeCount);
+ emit rowsRemoved(rowIndex, removeCount);
+ }
+}
+
+int QBarDataProxy::rowCount() const
+{
+ return dptrc()->m_dataArray->size();
+}
+
+const QBarDataArray *QBarDataProxy::array() const
+{
+ return dptrc()->m_dataArray;
+}
+
+const QBarDataRow *QBarDataProxy::rowAt(int rowIndex) const
+{
+ const QBarDataArray &dataArray = *dptrc()->m_dataArray;
+ Q_ASSERT(rowIndex >= 0 && rowIndex < dataArray.size());
+ return dataArray[rowIndex];
+}
+
+const QBarDataItem *QBarDataProxy::itemAt(int rowIndex, int columnIndex) const
+{
+ const QBarDataArray &dataArray = *dptrc()->m_dataArray;
+ Q_ASSERT(rowIndex >= 0 && rowIndex < dataArray.size());
+ const QBarDataRow &dataRow = *dataArray[rowIndex];
+ Q_ASSERT(columnIndex >= 0 && columnIndex < dataRow.size());
+ return &dataRow.at(columnIndex);
+}
+
+QBarDataProxyPrivate *QBarDataProxy::dptr()
+{
+ return static_cast<QBarDataProxyPrivate *>(d_ptr.data());
+}
+
+const QBarDataProxyPrivate *QBarDataProxy::dptrc() const
+{
+ return static_cast<const QBarDataProxyPrivate *>(d_ptr.data());
+}
+
+// QBarDataProxyPrivate
+
+QBarDataProxyPrivate::QBarDataProxyPrivate(QBarDataProxy *q)
+ : QAbstractDataProxyPrivate(q, QAbstractDataProxy::DataTypeBar),
+ m_dataArray(new QBarDataArray)
+{
+}
+
+QBarDataProxyPrivate::~QBarDataProxyPrivate()
+{
+ clearArray();
+}
+
+bool QBarDataProxyPrivate::resetArray(QBarDataArray *newArray)
+{
+ if (!m_dataArray->size() && (!newArray || !newArray->size()))
+ return false;
+
+ clearArray();
+
+ if (newArray)
+ m_dataArray = newArray;
+ else
+ m_dataArray = new QBarDataArray;
+
+ return true;
+}
+
+void QBarDataProxyPrivate::setRow(int rowIndex, QBarDataRow *row)
+{
+ Q_ASSERT(rowIndex >= 0 && rowIndex < m_dataArray->size());
+ clearRow(rowIndex);
+ (*m_dataArray)[rowIndex] = row;
+}
+
+void QBarDataProxyPrivate::setRows(int rowIndex, const QBarDataArray &rows)
+{
+ QBarDataArray &dataArray = *m_dataArray;
+ Q_ASSERT(rowIndex >= 0 && (rowIndex + rows.size()) <= dataArray.size());
+ for (int i = 0; i < rows.size(); i++) {
+ clearRow(rowIndex);
+ dataArray[rowIndex] = rows.at(i);
+ rowIndex++;
+ }
+}
+
+void QBarDataProxyPrivate::setItem(int rowIndex, int columnIndex, const QBarDataItem &item)
+{
+ Q_ASSERT(rowIndex >= 0 && rowIndex < m_dataArray->size());
+ QBarDataRow &row = *(*m_dataArray)[rowIndex];
+ Q_ASSERT(columnIndex < row.size());
+ row[columnIndex] = item;
+}
+
+int QBarDataProxyPrivate::addRow(QBarDataRow *row)
+{
+ int currentSize = m_dataArray->size();
+ m_dataArray->append(row);
+ return currentSize;
+}
+
+int QBarDataProxyPrivate::addRows(const QBarDataArray &rows)
+{
+ int currentSize = m_dataArray->size();
+ for (int i = 0; i < rows.size(); i++)
+ m_dataArray->append(rows.at(i));
+ return currentSize;
+}
+
+void QBarDataProxyPrivate::insertRow(int rowIndex, QBarDataRow *row)
+{
+ Q_ASSERT(rowIndex >= 0 && rowIndex <= m_dataArray->size());
+ m_dataArray->insert(rowIndex, row);
+}
+
+void QBarDataProxyPrivate::insertRows(int rowIndex, const QBarDataArray &rows)
+{
+ Q_ASSERT(rowIndex >= 0 && rowIndex <= m_dataArray->size());
+ for (int i = 0; i < rows.size(); i++)
+ m_dataArray->insert(rowIndex++, rows.at(i));
+}
+
+void QBarDataProxyPrivate::removeRows(int rowIndex, int removeCount)
+{
+ Q_ASSERT(rowIndex >= 0);
+ int maxRemoveCount = m_dataArray->size() - rowIndex;
+ removeCount = qMin(removeCount, maxRemoveCount);
+ for (int i = 0; i < removeCount; i++) {
+ clearRow(rowIndex);
+ m_dataArray->removeAt(rowIndex);
+ }
+}
+
+void QBarDataProxyPrivate::clearRow(int rowIndex)
+{
+ if (m_dataArray->at(rowIndex)) {
+ delete m_dataArray->at(rowIndex);
+ (*m_dataArray)[rowIndex] = 0;
+ }
+}
+
+void QBarDataProxyPrivate::clearArray()
+{
+ for (int i = 0; i < m_dataArray->size(); i++)
+ clearRow(i);
+ m_dataArray->clear();
+ delete m_dataArray;
+}
+
+QPair<GLfloat, GLfloat> QBarDataProxyPrivate::limitValues(int startRow, int endRow, int startColumn, int endColumn)
+{
+ QPair<GLfloat, GLfloat> limits = qMakePair(0.0f, 0.0f);
+ endRow = qMin(endRow, m_dataArray->size() - 1);
+ for (int i = startRow; i <= endRow; i++) {
+ QBarDataRow *row = m_dataArray->at(i);
+ if (row) {
+ endColumn = qMin(endColumn, row->size() - 1);
+ for (int j = startColumn; j <= endColumn; j++) {
+ const QBarDataItem &item = m_dataArray->at(i)->at(j);
+ qreal itemValue = item.value();
+ if (limits.second < itemValue)
+ limits.second = itemValue;
+ if (limits.first > itemValue)
+ limits.first = itemValue;
+ }
+ }
+ }
+ return limits;
+}
+
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/data/qbardataproxy.h b/src/datavis3d/data/qbardataproxy.h
new file mode 100644
index 00000000..e28f8ff0
--- /dev/null
+++ b/src/datavis3d/data/qbardataproxy.h
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef QBARDATAPROXY_H
+#define QBARDATAPROXY_H
+
+#include <QtDataVis3D/qabstractdataproxy.h>
+#include <QtDataVis3D/qbardataitem.h>
+#include <QVector>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+typedef QVector<QBarDataItem> QBarDataRow;
+typedef QList<QBarDataRow *> QBarDataArray;
+
+class QBarDataProxyPrivate;
+
+class QT_DATAVIS3D_EXPORT QBarDataProxy : public QAbstractDataProxy
+{
+ Q_OBJECT
+
+public:
+ explicit QBarDataProxy();
+ explicit QBarDataProxy(QBarDataProxyPrivate *d);
+ virtual ~QBarDataProxy();
+
+ // BarDataProxy is optimized for adding, inserting, and removing rows of data.
+ // Adding a column essentially means modifying every row, which is comparatively very inefficient.
+ // Proxy is also optimized to use cases where the only defining characteristic of an individual
+ // bar is its value. Modifying other data that might be added in the future such as color of
+ // individual bar requires allocating additional data object for the bar.
+
+ // Row and item pointers are guaranteed to be valid only until next call that modifies data.
+ // Array pointer is guaranteed to be valid for lifetime of proxy.
+ int rowCount() const;
+ const QBarDataArray *array() const;
+ const QBarDataRow *rowAt(int rowIndex) const;
+ const QBarDataItem *itemAt(int rowIndex, int columnIndex) const;
+
+ // The data array is a list of vectors (rows) of QBarDataItem instances.
+ // Each row can contain different amount of items or even be null.
+
+ // QBarDataProxy takes ownership of all QBarDataRows passed to it, whether directly or
+ // in a QBarDataArray container.
+ // QBarDataRow pointers should not be used to modify data further after they have been passed to
+ // the proxy, as such modifications will not trigger proper signals.
+
+ // Clears the existing array and takes ownership of the new array.
+ // Passing null array clears all data.
+ void resetArray(QBarDataArray *newArray);
+
+ // Change existing rows
+ void setRow(int rowIndex, QBarDataRow *row);
+ void setRows(int rowIndex, const QBarDataArray &rows);
+
+ // Setting a column is comparatively inefficient as it changes all rows.
+ // Can resize rows that are shorter than columnIndex.
+ // TODO void setColumn(int columnIndex, const QBarDataRow &column);
+ // TODO void setColumns(int columnIndex, const QBarDataArray &columns);
+
+ // Change single item
+ void setItem(int rowIndex, int columnIndex, const QBarDataItem &item);
+ // Change block of items
+ // TODO setItems(int rowIndex, int columnIndex, QBarDataArray *items);
+
+ int addRow(QBarDataRow *row); // returns the index of added row
+ int addRows(const QBarDataArray &rows); // returns the index of first added row
+ // TODO int addColumn(const QBarDataRow &column); // returns the index of the added column
+ // TODO int addColumns(const QBarDataArray &columns); // returns the index of the first added column
+
+ // If rowIndex is equal to array size, rows are added to end of the array.
+ void insertRow(int rowIndex, QBarDataRow *row);
+ void insertRows(int rowIndex, const QBarDataArray &rows);
+ // TODO void insertColumn(int columnIndex, const QBarDataRow &column);
+ // TODO void insertColumns(int columnIndex, const QBarDataArray &columns);
+
+ // Attempting to remove rows past the end of the array does nothing.
+ void removeRows(int rowIndex, int removeCount);
+ // TODO void removeColumns(int columnIndex, int removeCount);
+
+signals:
+ void arrayReset();
+ void rowsAdded(int startIndex, int count);
+ void rowsChanged(int startIndex, int count);
+ // Index is the current array size if rows were removed from the end of the array
+ void rowsRemoved(int startIndex, int count);
+ void rowsInserted(int startIndex, int count);
+ // TODO void columnsChanged(int startIndex, int count);
+ // TODO void columnsAdded(int startIndex, int count);
+ // TODO void columnsRemoved(int startIndex, int count);
+ // TODO void columnsInserted(int startIndex, int count);
+ void itemChanged(int rowIndex, int columnIndex); // TODO remove once itemsChanged is added?
+ // TODO void itemsChanged(int rowIndex, int columnIndex, int rowCount, int columnCount);
+
+protected:
+ QBarDataProxyPrivate *dptr();
+ const QBarDataProxyPrivate *dptrc() const;
+
+private:
+ Q_DISABLE_COPY(QBarDataProxy)
+
+ friend class Bars3dController;
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif // QBARDATAPROXY_H
diff --git a/src/datavis3d/data/qbardataproxy_p.h b/src/datavis3d/data/qbardataproxy_p.h
new file mode 100644
index 00000000..fa6ccd0d
--- /dev/null
+++ b/src/datavis3d/data/qbardataproxy_p.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef QBARDATAPROXY_P_H
+#define QBARDATAPROXY_P_H
+
+#include "qbardataproxy.h"
+#include "qabstractdataproxy_p.h"
+#include "qbardataitem.h"
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class QBarDataProxyPrivate : public QAbstractDataProxyPrivate
+{
+ Q_OBJECT
+public:
+ QBarDataProxyPrivate(QBarDataProxy *q);
+ virtual ~QBarDataProxyPrivate();
+
+ bool resetArray(QBarDataArray *newArray);
+ void setRow(int rowIndex, QBarDataRow *row);
+ void setRows(int rowIndex, const QBarDataArray &rows);
+ void setItem(int rowIndex, int columnIndex, const QBarDataItem &item);
+ int addRow(QBarDataRow *row);
+ int addRows(const QBarDataArray &rows);
+ void insertRow(int rowIndex, QBarDataRow *row);
+ void insertRows(int rowIndex, const QBarDataArray &rows);
+ void removeRows(int rowIndex, int removeCount);
+
+ QPair<GLfloat, GLfloat> limitValues(int startRow, int startColumn, int rowCount, int columnCount);
+
+private:
+ void clearRow(int rowIndex);
+ void clearArray();
+
+ QBarDataArray *m_dataArray;
+
+private:
+ friend class QBarDataProxy;
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif // QBARDATAPROXY_P_H
diff --git a/src/datavis3d/data/qitemmodelbardatamapping.cpp b/src/datavis3d/data/qitemmodelbardatamapping.cpp
new file mode 100644
index 00000000..0aecb082
--- /dev/null
+++ b/src/datavis3d/data/qitemmodelbardatamapping.cpp
@@ -0,0 +1,156 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "qitemmodelbardatamapping_p.h"
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+QItemModelBarDataMapping::QItemModelBarDataMapping()
+ : QObject(0),
+ d_ptr(new QItemModelBarDataMappingPrivate(this))
+{
+}
+
+QItemModelBarDataMapping::QItemModelBarDataMapping(const QItemModelBarDataMapping &other)
+ : QObject(0),
+ d_ptr(new QItemModelBarDataMappingPrivate(this))
+{
+ operator=(other);
+}
+
+QItemModelBarDataMapping::QItemModelBarDataMapping(const QString &valueRole)
+ : QObject(0),
+ d_ptr(new QItemModelBarDataMappingPrivate(this))
+{
+ d_ptr->m_valueRole = valueRole;
+}
+
+QItemModelBarDataMapping::QItemModelBarDataMapping(const QString &rowRole,
+ const QString &columnRole,
+ const QString &valueRole,
+ const QStringList &rowCategories,
+ const QStringList &columnCategories)
+ : QObject(0),
+ d_ptr(new QItemModelBarDataMappingPrivate(this))
+{
+ d_ptr->m_rowRole = rowRole;
+ d_ptr->m_columnRole = columnRole;
+ d_ptr->m_valueRole = valueRole;
+ d_ptr->m_rowCategories = rowCategories;
+ d_ptr->m_columnCategories = columnCategories;
+}
+
+QItemModelBarDataMapping::~QItemModelBarDataMapping()
+{
+}
+
+QItemModelBarDataMapping &QItemModelBarDataMapping::operator=(const QItemModelBarDataMapping &other)
+{
+ d_ptr->m_rowRole = other.d_ptr->m_rowRole;
+ d_ptr->m_columnRole = other.d_ptr->m_columnRole;
+ d_ptr->m_valueRole = other.d_ptr->m_valueRole;
+ d_ptr->m_rowCategories = other.d_ptr->m_rowCategories;
+ d_ptr->m_columnCategories = other.d_ptr->m_columnCategories;
+
+ return *this;
+}
+
+void QItemModelBarDataMapping::setRowRole(const QString &role)
+{
+ d_ptr->m_rowRole = role;
+ emit mappingChanged();
+}
+
+QString QItemModelBarDataMapping::rowRole() const
+{
+ return d_ptr->m_rowRole;
+}
+
+void QItemModelBarDataMapping::setColumnRole(const QString &role)
+{
+ d_ptr->m_columnRole = role;
+ emit mappingChanged();
+}
+
+QString QItemModelBarDataMapping::columnRole() const
+{
+ return d_ptr->m_columnRole;
+}
+
+void QItemModelBarDataMapping::setValueRole(const QString &role)
+{
+ d_ptr->m_valueRole = role;
+ emit mappingChanged();
+}
+
+QString QItemModelBarDataMapping::valueRole() const
+{
+ return d_ptr->m_valueRole;
+}
+
+void QItemModelBarDataMapping::setRowCategories(const QStringList &categories)
+{
+ d_ptr->m_rowCategories = categories;
+ emit mappingChanged();
+}
+
+const QStringList &QItemModelBarDataMapping::rowCategories() const
+{
+ return d_ptr->m_rowCategories;
+}
+
+void QItemModelBarDataMapping::setColumnCategories(const QStringList &categories)
+{
+ d_ptr->m_columnCategories = categories;
+ emit mappingChanged();
+}
+
+const QStringList &QItemModelBarDataMapping::columnCategories() const
+{
+ return d_ptr->m_columnCategories;
+}
+
+void QItemModelBarDataMapping::remap(const QString &rowRole,
+ const QString &columnRole,
+ const QString &valueRole,
+ const QStringList &rowCategories,
+ const QStringList &columnCategories)
+{
+ d_ptr->m_rowRole = rowRole;
+ d_ptr->m_columnRole = columnRole;
+ d_ptr->m_valueRole = valueRole;
+ d_ptr->m_rowCategories = rowCategories;
+ d_ptr->m_columnCategories = columnCategories;
+
+ emit mappingChanged();
+}
+
+// QItemModelBarDataMappingPrivate
+
+QItemModelBarDataMappingPrivate::QItemModelBarDataMappingPrivate(QItemModelBarDataMapping *q)
+ : QObject(0),
+ q_ptr(q)
+{
+}
+
+QItemModelBarDataMappingPrivate::~QItemModelBarDataMappingPrivate()
+{
+}
+
+QT_DATAVIS3D_END_NAMESPACE
+
diff --git a/src/datavis3d/data/qitemmodelbardatamapping.h b/src/datavis3d/data/qitemmodelbardatamapping.h
new file mode 100644
index 00000000..d9f74152
--- /dev/null
+++ b/src/datavis3d/data/qitemmodelbardatamapping.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef QITEMMODELBARDATAMAPPING_H
+#define QITEMMODELBARDATAMAPPING_H
+
+#include <QtDataVis3D/qdatavis3denums.h>
+#include <QStringList>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class QItemModelBarDataMappingPrivate;
+
+class QT_DATAVIS3D_EXPORT QItemModelBarDataMapping : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QString rowRole READ rowRole WRITE setRowRole)
+ Q_PROPERTY(QString columnRole READ columnRole WRITE setColumnRole)
+ Q_PROPERTY(QString valueRole READ valueRole WRITE setValueRole)
+ Q_PROPERTY(QStringList rowCategories READ rowCategories WRITE setRowCategories)
+ Q_PROPERTY(QStringList columnCategories READ columnCategories WRITE setColumnCategories)
+public:
+ explicit QItemModelBarDataMapping();
+ QItemModelBarDataMapping(const QItemModelBarDataMapping &other);
+ QItemModelBarDataMapping(const QString &valueRole);
+ QItemModelBarDataMapping(const QString &rowRole, const QString &columnRole,
+ const QString &valueRole, const QStringList &rowCategories,
+ const QStringList &columnCategories);
+ virtual ~QItemModelBarDataMapping();
+
+ QItemModelBarDataMapping &operator=(const QItemModelBarDataMapping &other);
+
+ // If row categories or column categories is an empty list, use item models's rows and columns for rows and columns.
+ // If the categories are both defined, ignore item model's rows and columns and figure out the rows and columns from
+ // the values of the set roles for each item.
+
+ void setRowRole(const QString &role);
+ QString rowRole() const;
+ void setColumnRole(const QString &role);
+ QString columnRole() const;
+ void setValueRole(const QString &role);
+ QString valueRole() const;
+
+ void setRowCategories(const QStringList &categories);
+ const QStringList &rowCategories() const;
+ void setColumnCategories(const QStringList &categories);
+ const QStringList &columnCategories() const;
+
+ void remap(const QString &rowRole, const QString &columnRole,
+ const QString &valueRole, const QStringList &rowCategories,
+ const QStringList &columnCategories);
+signals:
+ void mappingChanged();
+
+private:
+ QScopedPointer<QItemModelBarDataMappingPrivate> d_ptr;
+};
+
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/data/qitemmodelbardatamapping_p.h b/src/datavis3d/data/qitemmodelbardatamapping_p.h
new file mode 100644
index 00000000..fa1728e0
--- /dev/null
+++ b/src/datavis3d/data/qitemmodelbardatamapping_p.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#include "qitemmodelbardatamapping.h"
+
+#ifndef QITEMMODELBARDATAMAPPING_P_H
+#define QITEMMODELBARDATAMAPPING_P_H
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class QItemModelBarDataMappingPrivate : public QObject
+{
+ Q_OBJECT
+public:
+ QItemModelBarDataMappingPrivate(QItemModelBarDataMapping *q);
+ virtual ~QItemModelBarDataMappingPrivate();
+
+private:
+ QString m_rowRole;
+ QString m_columnRole;
+ QString m_valueRole;
+
+ // For row/column items, sort items into these categories. Other categories are ignored.
+ QStringList m_rowCategories;
+ QStringList m_columnCategories;
+
+ QItemModelBarDataMapping *q_ptr;
+
+ friend class QItemModelBarDataMapping;
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/data/qitemmodelbardataproxy.cpp b/src/datavis3d/data/qitemmodelbardataproxy.cpp
new file mode 100644
index 00000000..4b3ed020
--- /dev/null
+++ b/src/datavis3d/data/qitemmodelbardataproxy.cpp
@@ -0,0 +1,290 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "qitemmodelbardataproxy_p.h"
+#include <QTimer>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+QItemModelBarDataProxy::QItemModelBarDataProxy() :
+ QBarDataProxy(new QItemModelBarDataProxyPrivate(this))
+{
+}
+
+QItemModelBarDataProxy::QItemModelBarDataProxy(QAbstractItemModel *itemModel,
+ QItemModelBarDataMapping *mapping) :
+ QBarDataProxy(new QItemModelBarDataProxyPrivate(this))
+{
+ dptr()->setItemModel(itemModel);
+ dptr()->setMapping(mapping);
+}
+
+QItemModelBarDataProxy::~QItemModelBarDataProxy()
+{
+}
+
+void QItemModelBarDataProxy::setItemModel(QAbstractItemModel *itemModel)
+{
+ dptr()->setItemModel(itemModel);
+}
+
+QAbstractItemModel *QItemModelBarDataProxy::itemModel()
+{
+ return dptr()->m_itemModel.data();
+}
+
+void QItemModelBarDataProxy::setMapping(QItemModelBarDataMapping *mapping)
+{
+ dptr()->setMapping(mapping);
+}
+
+QItemModelBarDataMapping *QItemModelBarDataProxy::mapping()
+{
+ return dptr()->m_mapping.data();
+}
+
+QItemModelBarDataProxyPrivate *QItemModelBarDataProxy::dptr()
+{
+ return static_cast<QItemModelBarDataProxyPrivate *>(d_ptr.data());
+}
+
+// QItemModelBarDataProxyPrivate
+
+QItemModelBarDataProxyPrivate::QItemModelBarDataProxyPrivate(QItemModelBarDataProxy *q)
+ : QBarDataProxyPrivate(q),
+ resolvePending(0)
+{
+ m_resolveTimer.setSingleShot(true);
+ QObject::connect(&m_resolveTimer, &QTimer::timeout, this, &QItemModelBarDataProxyPrivate::handlePendingResolve);
+}
+
+QItemModelBarDataProxyPrivate::~QItemModelBarDataProxyPrivate()
+{
+}
+
+void QItemModelBarDataProxyPrivate::setItemModel(QAbstractItemModel *itemModel)
+{
+ if (!m_itemModel.isNull())
+ QObject::disconnect(m_itemModel, 0, this, 0);
+
+ m_itemModel = itemModel;
+
+ if (!m_itemModel.isNull()) {
+ QObject::connect(m_itemModel, &QAbstractItemModel::columnsInserted, this, &QItemModelBarDataProxyPrivate::handleColumnsInserted);
+ QObject::connect(m_itemModel, &QAbstractItemModel::columnsMoved, this, &QItemModelBarDataProxyPrivate::handleColumnsMoved);
+ QObject::connect(m_itemModel, &QAbstractItemModel::columnsRemoved, this, &QItemModelBarDataProxyPrivate::handleColumnsRemoved);
+ QObject::connect(m_itemModel, &QAbstractItemModel::dataChanged, this, &QItemModelBarDataProxyPrivate::handleDataChanged);
+ QObject::connect(m_itemModel, &QAbstractItemModel::layoutChanged, this, &QItemModelBarDataProxyPrivate::handleLayoutChanged);
+ QObject::connect(m_itemModel, &QAbstractItemModel::modelReset, this, &QItemModelBarDataProxyPrivate::handleModelReset);
+ QObject::connect(m_itemModel, &QAbstractItemModel::rowsInserted, this, &QItemModelBarDataProxyPrivate::handleRowsInserted);
+ QObject::connect(m_itemModel, &QAbstractItemModel::rowsMoved, this, &QItemModelBarDataProxyPrivate::handleRowsMoved);
+ QObject::connect(m_itemModel, &QAbstractItemModel::rowsRemoved, this, &QItemModelBarDataProxyPrivate::handleRowsRemoved);
+ }
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0);
+}
+
+void QItemModelBarDataProxyPrivate::setMapping(QItemModelBarDataMapping *mapping)
+{
+ if (!m_mapping.isNull())
+ QObject::disconnect(m_mapping.data(), &QItemModelBarDataMapping::mappingChanged, this, &QItemModelBarDataProxyPrivate::handleMappingChanged);
+
+ m_mapping = mapping;
+
+ if (!m_mapping.isNull())
+ QObject::connect(m_mapping.data(), &QItemModelBarDataMapping::mappingChanged, this, &QItemModelBarDataProxyPrivate::handleMappingChanged);
+
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0);
+}
+
+void QItemModelBarDataProxyPrivate::handleColumnsInserted(const QModelIndex &parent, int start, int end)
+{
+ Q_UNUSED(parent)
+ Q_UNUSED(start)
+ Q_UNUSED(end)
+
+ // Resolve new items
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0); // TODO Resolving entire model is inefficient
+}
+
+void QItemModelBarDataProxyPrivate::handleColumnsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationColumn)
+{
+ Q_UNUSED(sourceParent)
+ Q_UNUSED(sourceStart)
+ Q_UNUSED(sourceEnd)
+ Q_UNUSED(destinationParent)
+ Q_UNUSED(destinationColumn)
+
+ // Resolve moved items
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0); // TODO Resolving entire model is inefficient
+}
+
+void QItemModelBarDataProxyPrivate::handleColumnsRemoved(const QModelIndex &parent, int start, int end)
+{
+ Q_UNUSED(parent)
+ Q_UNUSED(start)
+ Q_UNUSED(end)
+
+ // Remove old items
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0); // TODO Resolving entire model is inefficient
+}
+
+void QItemModelBarDataProxyPrivate::handleDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
+{
+ Q_UNUSED(topLeft)
+ Q_UNUSED(bottomRight)
+ Q_UNUSED(roles)
+
+ // Resolve changed items
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0); // TODO Resolving entire model is inefficient
+}
+
+void QItemModelBarDataProxyPrivate::handleLayoutChanged(const QList<QPersistentModelIndex> &parents, QAbstractItemModel::LayoutChangeHint hint)
+{
+ Q_UNUSED(parents)
+ Q_UNUSED(hint)
+
+ // Resolve moved items
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0); // TODO Resolving entire model is inefficient
+}
+
+void QItemModelBarDataProxyPrivate::handleModelReset()
+{
+ // Data cleared, reset array
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0); // TODO Resolving entire model is inefficient
+}
+
+void QItemModelBarDataProxyPrivate::handleRowsInserted(const QModelIndex &parent, int start, int end)
+{
+ Q_UNUSED(parent)
+ Q_UNUSED(start)
+ Q_UNUSED(end)
+
+ // Resolve new items
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0); // TODO Resolving entire model is inefficient
+}
+
+void QItemModelBarDataProxyPrivate::handleRowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow)
+{
+ Q_UNUSED(sourceParent)
+ Q_UNUSED(sourceStart)
+ Q_UNUSED(sourceEnd)
+ Q_UNUSED(destinationParent)
+ Q_UNUSED(destinationRow)
+
+ // Resolve moved items
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0); // TODO Resolving entire model is inefficient
+}
+
+void QItemModelBarDataProxyPrivate::handleRowsRemoved(const QModelIndex &parent, int start, int end)
+{
+ Q_UNUSED(parent)
+ Q_UNUSED(start)
+ Q_UNUSED(end)
+
+ // Resolve removed items
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0); // TODO Resolving entire model is inefficient
+}
+
+void QItemModelBarDataProxyPrivate::handleMappingChanged()
+{
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0);
+}
+
+void QItemModelBarDataProxyPrivate::handlePendingResolve()
+{
+ resolveModel();
+}
+
+// Resolve entire item model into QBarDataArray.
+void QItemModelBarDataProxyPrivate::resolveModel()
+{
+ if (m_itemModel.isNull() || m_mapping.isNull()) {
+ qptr()->resetArray(0);
+ return;
+ }
+
+ bool useModelRows(false);
+ if (!m_mapping->rowCategories().size() || !m_mapping->columnCategories().size()) {
+ useModelRows = true;
+ } else if (m_mapping->rowRole().isEmpty() || m_mapping->columnRole().isEmpty()) {
+ qptr()->resetArray(0);
+ return;
+ }
+
+ QBarDataArray *newProxyArray = new QBarDataArray;
+ QHash<int, QByteArray> roleHash = m_itemModel->roleNames();
+ // Default to display role if no mapping
+ int valueRole = roleHash.key(m_mapping->valueRole().toLatin1(), Qt::DisplayRole);
+ int rowCount = m_itemModel->rowCount();
+ int columnCount = m_itemModel->columnCount();
+
+ if (useModelRows) {
+ for (int i = 0; i < rowCount; i++) {
+ QBarDataRow *newProxyRow = new QBarDataRow(columnCount);
+ for (int j = 0; j < columnCount; j++)
+ (*newProxyRow)[j].setValue(m_itemModel->index(i, j).data(valueRole).toReal());
+ newProxyArray->append(newProxyRow);
+ }
+ } else {
+ int rowRole = roleHash.key(m_mapping->rowRole().toLatin1());
+ int columnRole = roleHash.key(m_mapping->columnRole().toLatin1());
+ const QStringList &rowList = m_mapping->rowCategories();
+ const QStringList &columnList = m_mapping->columnCategories();
+
+ // Sort values into rows and columns
+ typedef QHash<QString, qreal> ColumnValueMap;
+ QHash <QString, ColumnValueMap> itemValueMap;
+ for (int i = 0; i < rowCount; i++) {
+ for (int j = 0; j < columnCount; j++) {
+ QModelIndex index = m_itemModel->index(i, j);
+ itemValueMap[index.data(rowRole).toString()][index.data(columnRole).toString()]
+ = index.data(valueRole).toReal();
+ }
+ }
+
+ // Create new data array from itemValueMap
+ foreach (QString rowKey, rowList) {
+ QBarDataRow *newProxyRow = new QBarDataRow(columnList.size());
+ for (int i = 0; i < columnList.size(); i++)
+ (*newProxyRow)[i].setValue(itemValueMap[rowKey][columnList.at(i)]);
+ newProxyArray->append(newProxyRow);
+ }
+ }
+ qDebug() << __FUNCTION__ << "RowCount:" << newProxyArray->size() << "Column count:" << (newProxyArray->size() ? newProxyArray->at(0)->size() : 0);
+
+ qptr()->resetArray(newProxyArray);
+}
+
+QItemModelBarDataProxy *QItemModelBarDataProxyPrivate::qptr()
+{
+ return static_cast<QItemModelBarDataProxy *>(q_ptr);
+}
+
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/data/qitemmodelbardataproxy.h b/src/datavis3d/data/qitemmodelbardataproxy.h
new file mode 100644
index 00000000..1d60bed6
--- /dev/null
+++ b/src/datavis3d/data/qitemmodelbardataproxy.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef QITEMMODELBARDATAPROXY_H
+#define QITEMMODELBARDATAPROXY_H
+
+#include <QtDataVis3D/qbardataproxy.h>
+#include <QtDataVis3D/qitemmodelbardatamapping.h>
+#include <QAbstractItemModel>
+#include <QStringList>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class QItemModelBarDataProxyPrivate;
+
+class QT_DATAVIS3D_EXPORT QItemModelBarDataProxy : public QBarDataProxy
+{
+ Q_OBJECT
+
+public:
+ explicit QItemModelBarDataProxy();
+ explicit QItemModelBarDataProxy(QAbstractItemModel *itemModel, QItemModelBarDataMapping *mapping);
+ virtual ~QItemModelBarDataProxy();
+
+ // Doesn't gain ownership of the model, but does connect to it to listen for data changes.
+ void setItemModel(QAbstractItemModel *itemModel);
+ QAbstractItemModel *itemModel();
+
+ // Map bars role (row, column, value) to role in model.
+ // Doesn't gain ownership of mapping, but does connect to it to listen for mapping changes.
+ // Modifying mapping that is set to proxy will trigger dataset re-resolving.
+ void setMapping(QItemModelBarDataMapping *mapping);
+ QItemModelBarDataMapping *mapping();
+
+protected:
+ QItemModelBarDataProxyPrivate *dptr();
+
+private:
+ Q_DISABLE_COPY(QItemModelBarDataProxy)
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/data/qitemmodelbardataproxy_p.h b/src/datavis3d/data/qitemmodelbardataproxy_p.h
new file mode 100644
index 00000000..c69b1679
--- /dev/null
+++ b/src/datavis3d/data/qitemmodelbardataproxy_p.h
@@ -0,0 +1,77 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef QITEMMODELBARDATAPROXY_P_H
+#define QITEMMODELBARDATAPROXY_P_H
+
+#include "qitemmodelbardataproxy.h"
+#include "qbardataproxy_p.h"
+#include <QPointer>
+#include <QTimer>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class QItemModelBarDataProxyPrivate : public QBarDataProxyPrivate
+{
+ Q_OBJECT
+public:
+ QItemModelBarDataProxyPrivate(QItemModelBarDataProxy *q);
+ virtual ~QItemModelBarDataProxyPrivate();
+
+ void setItemModel(QAbstractItemModel *itemModel);
+ void setMapping(QItemModelBarDataMapping *mapping);
+
+public slots:
+ void handleColumnsInserted(const QModelIndex & parent, int start, int end);
+ void handleColumnsMoved(const QModelIndex & sourceParent, int sourceStart, int sourceEnd, const QModelIndex & destinationParent, int destinationColumn);
+ void handleColumnsRemoved(const QModelIndex & parent, int start, int end);
+ void handleDataChanged(const QModelIndex & topLeft, const QModelIndex & bottomRight, const QVector<int> & roles = QVector<int> ());
+ void handleLayoutChanged(const QList<QPersistentModelIndex> & parents = QList<QPersistentModelIndex> (), QAbstractItemModel::LayoutChangeHint hint = QAbstractItemModel::NoLayoutChangeHint);
+ void handleModelReset();
+ void handleRowsInserted(const QModelIndex & parent, int start, int end);
+ void handleRowsMoved(const QModelIndex & sourceParent, int sourceStart, int sourceEnd, const QModelIndex & destinationParent, int destinationRow);
+ void handleRowsRemoved(const QModelIndex & parent, int start, int end);
+
+ void handleMappingChanged();
+ void handlePendingResolve();
+
+private:
+ void resolveModel();
+ QItemModelBarDataProxy *qptr();
+
+ QPointer<QAbstractItemModel> m_itemModel; // Not owned
+ QPointer<QItemModelBarDataMapping> m_mapping; // Not owned
+ bool resolvePending;
+ QTimer m_resolveTimer;
+
+ friend class QItemModelBarDataProxy;
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/data/qitemmodelmapdatamapping.cpp b/src/datavis3d/data/qitemmodelmapdatamapping.cpp
new file mode 100644
index 00000000..a59be94b
--- /dev/null
+++ b/src/datavis3d/data/qitemmodelmapdatamapping.cpp
@@ -0,0 +1,130 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "qitemmodelmapdatamapping_p.h"
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+QItemModelMapDataMapping::QItemModelMapDataMapping()
+ : QObject(0),
+ d_ptr(new QItemModelMapDataMappingPrivate(this))
+{
+}
+
+QItemModelMapDataMapping::QItemModelMapDataMapping(const QItemModelMapDataMapping &other)
+ : QObject(0),
+ d_ptr(new QItemModelMapDataMappingPrivate(this))
+{
+ operator=(other);
+}
+
+QItemModelMapDataMapping::QItemModelMapDataMapping(const QString &labelRole, const QString &xPosRole,
+ const QString &yPosRole, const QString &valueRole)
+ : QObject(0),
+ d_ptr(new QItemModelMapDataMappingPrivate(this))
+{
+ d_ptr->m_labelRole = labelRole;
+ d_ptr->m_xPosRole = xPosRole;
+ d_ptr->m_yPosRole = yPosRole;
+ d_ptr->m_valueRole = valueRole;
+}
+
+QItemModelMapDataMapping::~QItemModelMapDataMapping()
+{
+}
+
+QItemModelMapDataMapping &QItemModelMapDataMapping::operator=(const QItemModelMapDataMapping &other)
+{
+ d_ptr->m_labelRole = other.d_ptr->m_labelRole;
+ d_ptr->m_xPosRole = other.d_ptr->m_xPosRole;
+ d_ptr->m_yPosRole = other.d_ptr->m_yPosRole;
+ d_ptr->m_valueRole = other.d_ptr->m_valueRole;
+
+ return *this;
+}
+
+void QItemModelMapDataMapping::setLabelRole(const QString &role)
+{
+ d_ptr->m_labelRole = role;
+ emit mappingChanged();
+}
+
+QString QItemModelMapDataMapping::labelRole() const
+{
+ return d_ptr->m_labelRole;
+}
+
+void QItemModelMapDataMapping::setXPosRole(const QString &role)
+{
+ d_ptr->m_xPosRole = role;
+ emit mappingChanged();
+}
+
+QString QItemModelMapDataMapping::xPosRole() const
+{
+ return d_ptr->m_xPosRole;
+}
+
+void QItemModelMapDataMapping::setYPosRole(const QString &role)
+{
+ d_ptr->m_yPosRole = role;
+ emit mappingChanged();
+}
+
+QString QItemModelMapDataMapping::yPosRole() const
+{
+ return d_ptr->m_yPosRole;
+}
+
+void QItemModelMapDataMapping::setValueRole(const QString &role)
+{
+ d_ptr->m_valueRole = role;
+ emit mappingChanged();
+}
+
+QString QItemModelMapDataMapping::valueRole() const
+{
+ return d_ptr->m_valueRole;
+}
+
+
+void QItemModelMapDataMapping::remap(const QString &labelRole, const QString &xPosRole,
+ const QString &yPosRole, const QString &valueRole)
+{
+ d_ptr->m_labelRole = labelRole;
+ d_ptr->m_xPosRole = xPosRole;
+ d_ptr->m_yPosRole = yPosRole;
+ d_ptr->m_valueRole = valueRole;
+
+ emit mappingChanged();
+}
+
+// QItemModelMapDataMappingPrivate
+
+QItemModelMapDataMappingPrivate::QItemModelMapDataMappingPrivate(QItemModelMapDataMapping *q)
+ : QObject(0),
+ q_ptr(q)
+{
+}
+
+QItemModelMapDataMappingPrivate::~QItemModelMapDataMappingPrivate()
+{
+}
+
+QT_DATAVIS3D_END_NAMESPACE
+
diff --git a/src/datavis3d/data/qitemmodelmapdatamapping.h b/src/datavis3d/data/qitemmodelmapdatamapping.h
new file mode 100644
index 00000000..79080a65
--- /dev/null
+++ b/src/datavis3d/data/qitemmodelmapdatamapping.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef QITEMMODELMAPDATAMAPPING_H
+#define QITEMMODELMAPDATAMAPPING_H
+
+#include <QtDataVis3D/qdatavis3denums.h>
+#include <QStringList>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class QItemModelMapDataMappingPrivate;
+
+class QT_DATAVIS3D_EXPORT QItemModelMapDataMapping : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QString labelRole READ labelRole WRITE setLabelRole)
+ Q_PROPERTY(QString xPosRole READ xPosRole WRITE setXPosRole)
+ Q_PROPERTY(QString yPosRole READ yPosRole WRITE setYPosRole)
+ Q_PROPERTY(QString valueRole READ valueRole WRITE setValueRole)
+public:
+ explicit QItemModelMapDataMapping();
+ QItemModelMapDataMapping(const QItemModelMapDataMapping &other);
+ QItemModelMapDataMapping(const QString &labelRole, const QString &xPosRole,
+ const QString &yPosRole, const QString &valueRole);
+ virtual ~QItemModelMapDataMapping();
+
+ QItemModelMapDataMapping &operator=(const QItemModelMapDataMapping &other);
+
+ void setLabelRole(const QString &role);
+ QString labelRole() const;
+ void setXPosRole(const QString &role);
+ QString xPosRole() const;
+ void setYPosRole(const QString &role);
+ QString yPosRole() const;
+ void setValueRole(const QString &role);
+ QString valueRole() const;
+
+ void remap(const QString &labelRole, const QString &xPosRole,
+ const QString &yPosRole, const QString &valueRole);
+signals:
+ void mappingChanged();
+
+private:
+ QScopedPointer<QItemModelMapDataMappingPrivate> d_ptr;
+};
+
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/data/qitemmodelmapdatamapping_p.h b/src/datavis3d/data/qitemmodelmapdatamapping_p.h
new file mode 100644
index 00000000..99618942
--- /dev/null
+++ b/src/datavis3d/data/qitemmodelmapdatamapping_p.h
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#include "qitemmodelmapdatamapping.h"
+
+#ifndef QITEMMODELMAPDATAMAPPING_P_H
+#define QITEMMODELMAPDATAMAPPING_P_H
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class QItemModelMapDataMappingPrivate : public QObject
+{
+ Q_OBJECT
+public:
+ QItemModelMapDataMappingPrivate(QItemModelMapDataMapping *q);
+ virtual ~QItemModelMapDataMappingPrivate();
+
+private:
+ QString m_labelRole;
+ QString m_xPosRole;
+ QString m_yPosRole;
+ QString m_valueRole;
+
+ QItemModelMapDataMapping *q_ptr;
+
+ friend class QItemModelMapDataMapping;
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/data/qitemmodelmapdataproxy.cpp b/src/datavis3d/data/qitemmodelmapdataproxy.cpp
new file mode 100644
index 00000000..b41384e9
--- /dev/null
+++ b/src/datavis3d/data/qitemmodelmapdataproxy.cpp
@@ -0,0 +1,275 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "qitemmodelmapdataproxy_p.h"
+#include <QTimer>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+QItemModelMapDataProxy::QItemModelMapDataProxy() :
+ QMapDataProxy(new QItemModelMapDataProxyPrivate(this))
+{
+}
+
+QItemModelMapDataProxy::QItemModelMapDataProxy(QAbstractItemModel *itemModel,
+ QItemModelMapDataMapping *mapping) :
+ QMapDataProxy(new QItemModelMapDataProxyPrivate(this))
+{
+ dptr()->setItemModel(itemModel);
+ dptr()->setMapping(mapping);
+}
+
+QItemModelMapDataProxy::~QItemModelMapDataProxy()
+{
+}
+
+void QItemModelMapDataProxy::setItemModel(QAbstractItemModel *itemModel)
+{
+ dptr()->setItemModel(itemModel);
+}
+
+QAbstractItemModel *QItemModelMapDataProxy::itemModel()
+{
+ return dptr()->m_itemModel.data();
+}
+
+void QItemModelMapDataProxy::setMapping(QItemModelMapDataMapping *mapping)
+{
+ dptr()->setMapping(mapping);
+}
+
+QItemModelMapDataMapping *QItemModelMapDataProxy::mapping()
+{
+ return dptr()->m_mapping.data();
+}
+
+QItemModelMapDataProxyPrivate *QItemModelMapDataProxy::dptr()
+{
+ return static_cast<QItemModelMapDataProxyPrivate *>(d_ptr.data());
+}
+
+// QItemModelMapDataProxyPrivate
+
+QItemModelMapDataProxyPrivate::QItemModelMapDataProxyPrivate(QItemModelMapDataProxy *q)
+ : QMapDataProxyPrivate(q),
+ resolvePending(0)
+{
+ m_resolveTimer.setSingleShot(true);
+ QObject::connect(&m_resolveTimer, &QTimer::timeout, this, &QItemModelMapDataProxyPrivate::handlePendingResolve);
+}
+
+QItemModelMapDataProxyPrivate::~QItemModelMapDataProxyPrivate()
+{
+}
+
+void QItemModelMapDataProxyPrivate::setItemModel(QAbstractItemModel *itemModel)
+{
+ if (!m_itemModel.isNull())
+ QObject::disconnect(m_itemModel, 0, this, 0);
+
+ m_itemModel = itemModel;
+
+ if (!m_itemModel.isNull()) {
+ QObject::connect(m_itemModel, &QAbstractItemModel::columnsInserted, this, &QItemModelMapDataProxyPrivate::handleColumnsInserted);
+ QObject::connect(m_itemModel, &QAbstractItemModel::columnsMoved, this, &QItemModelMapDataProxyPrivate::handleColumnsMoved);
+ QObject::connect(m_itemModel, &QAbstractItemModel::columnsRemoved, this, &QItemModelMapDataProxyPrivate::handleColumnsRemoved);
+ QObject::connect(m_itemModel, &QAbstractItemModel::dataChanged, this, &QItemModelMapDataProxyPrivate::handleDataChanged);
+ QObject::connect(m_itemModel, &QAbstractItemModel::layoutChanged, this, &QItemModelMapDataProxyPrivate::handleLayoutChanged);
+ QObject::connect(m_itemModel, &QAbstractItemModel::modelReset, this, &QItemModelMapDataProxyPrivate::handleModelReset);
+ QObject::connect(m_itemModel, &QAbstractItemModel::rowsInserted, this, &QItemModelMapDataProxyPrivate::handleRowsInserted);
+ QObject::connect(m_itemModel, &QAbstractItemModel::rowsMoved, this, &QItemModelMapDataProxyPrivate::handleRowsMoved);
+ QObject::connect(m_itemModel, &QAbstractItemModel::rowsRemoved, this, &QItemModelMapDataProxyPrivate::handleRowsRemoved);
+ }
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0);
+}
+
+void QItemModelMapDataProxyPrivate::setMapping(QItemModelMapDataMapping *mapping)
+{
+ if (!m_mapping.isNull())
+ QObject::disconnect(m_mapping.data(), &QItemModelMapDataMapping::mappingChanged, this, &QItemModelMapDataProxyPrivate::handleMappingChanged);
+
+ m_mapping = mapping;
+
+ if (!m_mapping.isNull())
+ QObject::connect(m_mapping.data(), &QItemModelMapDataMapping::mappingChanged, this, &QItemModelMapDataProxyPrivate::handleMappingChanged);
+
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0);
+}
+
+void QItemModelMapDataProxyPrivate::handleColumnsInserted(const QModelIndex &parent, int start, int end)
+{
+ Q_UNUSED(parent)
+ Q_UNUSED(start)
+ Q_UNUSED(end)
+
+ // Resolve new items
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0); // TODO Resolving entire model is inefficient
+}
+
+void QItemModelMapDataProxyPrivate::handleColumnsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationColumn)
+{
+ Q_UNUSED(sourceParent)
+ Q_UNUSED(sourceStart)
+ Q_UNUSED(sourceEnd)
+ Q_UNUSED(destinationParent)
+ Q_UNUSED(destinationColumn)
+
+ // Resolve moved items
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0); // TODO Resolving entire model is inefficient
+}
+
+void QItemModelMapDataProxyPrivate::handleColumnsRemoved(const QModelIndex &parent, int start, int end)
+{
+ Q_UNUSED(parent)
+ Q_UNUSED(start)
+ Q_UNUSED(end)
+
+ // Remove old items
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0); // TODO Resolving entire model is inefficient
+}
+
+void QItemModelMapDataProxyPrivate::handleDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles)
+{
+ Q_UNUSED(topLeft)
+ Q_UNUSED(bottomRight)
+ Q_UNUSED(roles)
+
+ // Resolve changed items
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0); // TODO Resolving entire model is inefficient
+}
+
+void QItemModelMapDataProxyPrivate::handleLayoutChanged(const QList<QPersistentModelIndex> &parents, QAbstractItemModel::LayoutChangeHint hint)
+{
+ Q_UNUSED(parents)
+ Q_UNUSED(hint)
+
+ // Resolve moved items
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0); // TODO Resolving entire model is inefficient
+}
+
+void QItemModelMapDataProxyPrivate::handleModelReset()
+{
+ // Data cleared, reset array
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0); // TODO Resolving entire model is inefficient
+}
+
+void QItemModelMapDataProxyPrivate::handleRowsInserted(const QModelIndex &parent, int start, int end)
+{
+ Q_UNUSED(parent)
+ Q_UNUSED(start)
+ Q_UNUSED(end)
+
+ // Resolve new items
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0); // TODO Resolving entire model is inefficient
+}
+
+void QItemModelMapDataProxyPrivate::handleRowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow)
+{
+ Q_UNUSED(sourceParent)
+ Q_UNUSED(sourceStart)
+ Q_UNUSED(sourceEnd)
+ Q_UNUSED(destinationParent)
+ Q_UNUSED(destinationRow)
+
+ // Resolve moved items
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0); // TODO Resolving entire model is inefficient
+}
+
+void QItemModelMapDataProxyPrivate::handleRowsRemoved(const QModelIndex &parent, int start, int end)
+{
+ Q_UNUSED(parent)
+ Q_UNUSED(start)
+ Q_UNUSED(end)
+
+ // Resolve removed items
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0); // TODO Resolving entire model is inefficient
+}
+
+void QItemModelMapDataProxyPrivate::handleMappingChanged()
+{
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0);
+}
+
+void QItemModelMapDataProxyPrivate::handlePendingResolve()
+{
+ resolveModel();
+}
+
+// Resolve entire item model into QMapDataArray.
+void QItemModelMapDataProxyPrivate::resolveModel()
+{
+ if (m_itemModel.isNull() || m_mapping.isNull()) {
+ qptr()->resetArray(0);
+ return;
+ }
+
+ static const int noRoleIndex = -1;
+
+ QHash<int, QByteArray> roleHash = m_itemModel->roleNames();
+ const int labelRole = roleHash.key(m_mapping->labelRole().toLatin1(), noRoleIndex);
+ const int xPosRole = roleHash.key(m_mapping->xPosRole().toLatin1(), noRoleIndex);
+ const int yPosRole = roleHash.key(m_mapping->yPosRole().toLatin1(), noRoleIndex);
+ // Default valueRole to display role if no mapping
+ const int valueRole = roleHash.key(m_mapping->valueRole().toLatin1(), Qt::DisplayRole);
+ const int columnCount = m_itemModel->columnCount();
+ const int rowCount = m_itemModel->rowCount();
+ const int totalCount = rowCount * columnCount;
+ int runningCount = 0;
+
+ // Parse data into newProxyArray
+ QMapDataArray *newProxyArray = new QMapDataArray(totalCount);
+ for (int i = 0; i < rowCount; i++) {
+ for (int j = 0; j < columnCount; j++) {
+ QModelIndex index = m_itemModel->index(i, j);
+ if (labelRole != noRoleIndex)
+ (*newProxyArray)[runningCount].setLabel(index.data(labelRole).toString());
+ qreal xPos(qreal(0.0));
+ qreal yPos(qreal(0.0));
+ if (xPosRole != noRoleIndex)
+ xPos = index.data(xPosRole).toReal();
+ if (yPosRole != noRoleIndex)
+ yPos = index.data(yPosRole).toReal();
+ (*newProxyArray)[runningCount].setMapPosition(QPointF(xPos, yPos));
+ (*newProxyArray)[runningCount].setValue(index.data(valueRole).toReal());
+ runningCount++;
+ }
+ }
+
+ qDebug() << __FUNCTION__ << "Total count:" << newProxyArray->size();
+
+ qptr()->resetArray(newProxyArray);
+}
+
+QItemModelMapDataProxy *QItemModelMapDataProxyPrivate::qptr()
+{
+ return static_cast<QItemModelMapDataProxy *>(q_ptr);
+}
+
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/data/qitemmodelmapdataproxy.h b/src/datavis3d/data/qitemmodelmapdataproxy.h
new file mode 100644
index 00000000..784ee162
--- /dev/null
+++ b/src/datavis3d/data/qitemmodelmapdataproxy.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef QITEMMODELMAPDATAPROXY_H
+#define QITEMMODELMAPDATAPROXY_H
+
+#include <QtDataVis3D/qmapdataproxy.h>
+#include <QtDataVis3D/qitemmodelmapdatamapping.h>
+#include <QAbstractItemModel>
+#include <QStringList>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class QItemModelMapDataProxyPrivate;
+
+class QT_DATAVIS3D_EXPORT QItemModelMapDataProxy : public QMapDataProxy
+{
+ Q_OBJECT
+
+public:
+ explicit QItemModelMapDataProxy();
+ explicit QItemModelMapDataProxy(QAbstractItemModel *itemModel, QItemModelMapDataMapping *mapping);
+ virtual ~QItemModelMapDataProxy();
+
+ // Doesn't gain ownership of the model, but does connect to it to listen for data changes.
+ void setItemModel(QAbstractItemModel *itemModel);
+ QAbstractItemModel *itemModel();
+
+ // Map maps role (label, xPos, yPos, value) to role in model
+ // Doesn't gain ownership of mapping, but does connect to it to listen for mapping changes.
+ // Modifying mapping that is set to proxy will trigger dataset re-resolving.
+ void setMapping(QItemModelMapDataMapping *mapping);
+ QItemModelMapDataMapping *mapping();
+
+protected:
+ QItemModelMapDataProxyPrivate *dptr();
+
+private:
+ Q_DISABLE_COPY(QItemModelMapDataProxy)
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/data/qitemmodelmapdataproxy_p.h b/src/datavis3d/data/qitemmodelmapdataproxy_p.h
new file mode 100644
index 00000000..64b16c7f
--- /dev/null
+++ b/src/datavis3d/data/qitemmodelmapdataproxy_p.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef QITEMMODELMAPDATAPROXY_P_H
+#define QITEMMODELMAPDATAPROXY_P_H
+
+#include "qitemmodelmapdataproxy.h"
+#include "qMapDataProxy_p.h"
+#include <QPointer>
+#include <QTimer>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class QItemModelMapDataProxyPrivate : public QMapDataProxyPrivate
+{
+ Q_OBJECT
+public:
+ QItemModelMapDataProxyPrivate(QItemModelMapDataProxy *q);
+ virtual ~QItemModelMapDataProxyPrivate();
+
+ void setItemModel(QAbstractItemModel *itemModel);
+ void setMapping(QItemModelMapDataMapping *mapping);
+
+public slots:
+ void handleColumnsInserted(const QModelIndex &parent, int start, int end);
+ void handleColumnsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd,
+ const QModelIndex &destinationParent, int destinationColumn);
+ void handleColumnsRemoved(const QModelIndex &parent, int start, int end);
+ void handleDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight,
+ const QVector<int> &roles = QVector<int> ());
+ void handleLayoutChanged(const QList<QPersistentModelIndex> &parents = QList<QPersistentModelIndex> (),
+ QAbstractItemModel::LayoutChangeHint hint = QAbstractItemModel::NoLayoutChangeHint);
+ void handleModelReset();
+ void handleRowsInserted(const QModelIndex &parent, int start, int end);
+ void handleRowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd,
+ const QModelIndex &destinationParent, int destinationRow);
+ void handleRowsRemoved(const QModelIndex &parent, int start, int end);
+
+ void handleMappingChanged();
+ void handlePendingResolve();
+
+private:
+ void resolveModel();
+ QItemModelMapDataProxy *qptr();
+
+ QPointer<QAbstractItemModel> m_itemModel; // Not owned
+ QPointer<QItemModelMapDataMapping> m_mapping; // Not owned
+ bool resolvePending;
+ QTimer m_resolveTimer;
+
+ friend class QItemModelMapDataProxy;
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/data/qitemmodelscatterdatamapping.cpp b/src/datavis3d/data/qitemmodelscatterdatamapping.cpp
new file mode 100644
index 00000000..0b430b79
--- /dev/null
+++ b/src/datavis3d/data/qitemmodelscatterdatamapping.cpp
@@ -0,0 +1,154 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "qitemmodelscatterdatamapping_p.h"
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+QItemModelScatterDataMapping::QItemModelScatterDataMapping()
+ : QObject(0),
+ d_ptr(new QItemModelScatterDataMappingPrivate(this))
+{
+}
+
+QItemModelScatterDataMapping::QItemModelScatterDataMapping(
+ const QItemModelScatterDataMapping &other)
+ : QObject(0),
+ d_ptr(new QItemModelScatterDataMappingPrivate(this))
+{
+ operator=(other);
+}
+
+QItemModelScatterDataMapping::QItemModelScatterDataMapping(const QString &labelRole,
+ const QString &xPosRole,
+ const QString &yPosRole,
+ const QString &zPosRole,
+ const QString &valueRole)
+ : QObject(0),
+ d_ptr(new QItemModelScatterDataMappingPrivate(this))
+{
+ Q_UNUSED(labelRole);
+ Q_UNUSED(valueRole);
+ //d_ptr->m_labelRole = labelRole;
+ d_ptr->m_xPosRole = xPosRole;
+ d_ptr->m_yPosRole = yPosRole;
+ d_ptr->m_zPosRole = zPosRole;
+ //d_ptr->m_valueRole = valueRole;
+}
+
+QItemModelScatterDataMapping::~QItemModelScatterDataMapping()
+{
+}
+
+QItemModelScatterDataMapping &QItemModelScatterDataMapping::operator=(
+ const QItemModelScatterDataMapping &other)
+{
+ //d_ptr->m_labelRole = other.d_ptr->m_labelRole;
+ d_ptr->m_xPosRole = other.d_ptr->m_xPosRole;
+ d_ptr->m_yPosRole = other.d_ptr->m_yPosRole;
+ d_ptr->m_zPosRole = other.d_ptr->m_zPosRole;
+ //d_ptr->m_valueRole = other.d_ptr->m_valueRole;
+
+ return *this;
+}
+
+//void QItemModelScatterDataMapping::setLabelRole(const QString &role)
+//{
+// d_ptr->m_labelRole = role;
+// emit mappingChanged();
+//}
+
+//QString QItemModelScatterDataMapping::labelRole() const
+//{
+// return d_ptr->m_labelRole;
+//}
+
+void QItemModelScatterDataMapping::setXPosRole(const QString &role)
+{
+ d_ptr->m_xPosRole = role;
+ emit mappingChanged();
+}
+
+QString QItemModelScatterDataMapping::xPosRole() const
+{
+ return d_ptr->m_xPosRole;
+}
+
+void QItemModelScatterDataMapping::setYPosRole(const QString &role)
+{
+ d_ptr->m_yPosRole = role;
+ emit mappingChanged();
+}
+
+QString QItemModelScatterDataMapping::yPosRole() const
+{
+ return d_ptr->m_yPosRole;
+}
+
+void QItemModelScatterDataMapping::setZPosRole(const QString &role)
+{
+ d_ptr->m_zPosRole = role;
+ emit mappingChanged();
+}
+
+QString QItemModelScatterDataMapping::zPosRole() const
+{
+ return d_ptr->m_zPosRole;
+}
+
+//void QItemModelScatterDataMapping::setValueRole(const QString &role)
+//{
+// d_ptr->m_valueRole = role;
+// emit mappingChanged();
+//}
+
+//QString QItemModelScatterDataMapping::valueRole() const
+//{
+// return d_ptr->m_valueRole;
+//}
+
+void QItemModelScatterDataMapping::remap(const QString &labelRole, const QString &xPosRole,
+ const QString &yPosRole, const QString &zPosRole,
+ const QString &valueRole)
+{
+ Q_UNUSED(labelRole);
+ Q_UNUSED(valueRole);
+ //d_ptr->m_labelRole = labelRole;
+ d_ptr->m_xPosRole = xPosRole;
+ d_ptr->m_yPosRole = yPosRole;
+ d_ptr->m_zPosRole = zPosRole;
+ //d_ptr->m_valueRole = valueRole;
+
+ emit mappingChanged();
+}
+
+// QItemModelScatterDataMappingPrivate
+
+QItemModelScatterDataMappingPrivate::QItemModelScatterDataMappingPrivate(
+ QItemModelScatterDataMapping *q)
+ : QObject(0),
+ q_ptr(q)
+{
+}
+
+QItemModelScatterDataMappingPrivate::~QItemModelScatterDataMappingPrivate()
+{
+}
+
+QT_DATAVIS3D_END_NAMESPACE
+
diff --git a/src/datavis3d/data/qitemmodelscatterdatamapping.h b/src/datavis3d/data/qitemmodelscatterdatamapping.h
new file mode 100644
index 00000000..f4a2cfe6
--- /dev/null
+++ b/src/datavis3d/data/qitemmodelscatterdatamapping.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef QITEMMODELSCATTERDATAMAPPING_H
+#define QITEMMODELSCATTERDATAMAPPING_H
+
+#include <QtDataVis3D/qdatavis3denums.h>
+#include <QObject>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class QItemModelScatterDataMappingPrivate;
+
+class QT_DATAVIS3D_EXPORT QItemModelScatterDataMapping : public QObject
+{
+ Q_OBJECT
+ //Q_PROPERTY(QString labelRole READ labelRole WRITE setLabelRole)
+ Q_PROPERTY(QString xPosRole READ xPosRole WRITE setXPosRole)
+ Q_PROPERTY(QString yPosRole READ yPosRole WRITE setYPosRole)
+ Q_PROPERTY(QString zPosRole READ zPosRole WRITE setZPosRole)
+ //Q_PROPERTY(QString valueRole READ valueRole WRITE setValueRole)
+public:
+ explicit QItemModelScatterDataMapping();
+ QItemModelScatterDataMapping(const QItemModelScatterDataMapping &other);
+ QItemModelScatterDataMapping(const QString &labelRole, const QString &xPosRole,
+ const QString &yPosRole, const QString &zPosRole,
+ const QString &valueRole);
+ virtual ~QItemModelScatterDataMapping();
+
+ QItemModelScatterDataMapping &operator=(const QItemModelScatterDataMapping &other);
+
+ //void setLabelRole(const QString &role);
+ //QString labelRole() const;
+ void setXPosRole(const QString &role);
+ QString xPosRole() const;
+ void setYPosRole(const QString &role);
+ QString yPosRole() const;
+ void setZPosRole(const QString &role);
+ QString zPosRole() const;
+ //void setValueRole(const QString &role);
+ //QString valueRole() const;
+
+ void remap(const QString &labelRole, const QString &xPosRole,
+ const QString &yPosRole, const QString &zPosRole, const QString &valueRole);
+signals:
+ void mappingChanged();
+
+private:
+ QScopedPointer<QItemModelScatterDataMappingPrivate> d_ptr;
+};
+
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/data/qitemmodelscatterdatamapping_p.h b/src/datavis3d/data/qitemmodelscatterdatamapping_p.h
new file mode 100644
index 00000000..90a826c0
--- /dev/null
+++ b/src/datavis3d/data/qitemmodelscatterdatamapping_p.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#include "qitemmodelscatterdatamapping.h"
+
+#ifndef QITEMMODELSCATTERDATAMAPPING_P_H
+#define QITEMMODELSCATTERDATAMAPPING_P_H
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class QItemModelScatterDataMappingPrivate : public QObject
+{
+ Q_OBJECT
+public:
+ QItemModelScatterDataMappingPrivate(QItemModelScatterDataMapping *q);
+ virtual ~QItemModelScatterDataMappingPrivate();
+
+private:
+ //QString m_labelRole;
+ QString m_xPosRole;
+ QString m_yPosRole;
+ QString m_zPosRole;
+ //QString m_valueRole;
+
+ QItemModelScatterDataMapping *q_ptr;
+
+ friend class QItemModelScatterDataMapping;
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/data/qitemmodelscatterdataproxy.cpp b/src/datavis3d/data/qitemmodelscatterdataproxy.cpp
new file mode 100644
index 00000000..c4f4f0a7
--- /dev/null
+++ b/src/datavis3d/data/qitemmodelscatterdataproxy.cpp
@@ -0,0 +1,305 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "qitemmodelscatterdataproxy_p.h"
+#include <QTimer>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+QItemModelScatterDataProxy::QItemModelScatterDataProxy() :
+ QScatterDataProxy(new QItemModelScatterDataProxyPrivate(this))
+{
+}
+
+QItemModelScatterDataProxy::QItemModelScatterDataProxy(QAbstractItemModel *itemModel,
+ QItemModelScatterDataMapping *mapping) :
+ QScatterDataProxy(new QItemModelScatterDataProxyPrivate(this))
+{
+ dptr()->setItemModel(itemModel);
+ dptr()->setMapping(mapping);
+}
+
+QItemModelScatterDataProxy::~QItemModelScatterDataProxy()
+{
+}
+
+void QItemModelScatterDataProxy::setItemModel(QAbstractItemModel *itemModel)
+{
+ dptr()->setItemModel(itemModel);
+}
+
+QAbstractItemModel *QItemModelScatterDataProxy::itemModel()
+{
+ return dptr()->m_itemModel.data();
+}
+
+void QItemModelScatterDataProxy::setMapping(QItemModelScatterDataMapping *mapping)
+{
+ dptr()->setMapping(mapping);
+}
+
+QItemModelScatterDataMapping *QItemModelScatterDataProxy::mapping()
+{
+ return dptr()->m_mapping.data();
+}
+
+QItemModelScatterDataProxyPrivate *QItemModelScatterDataProxy::dptr()
+{
+ return static_cast<QItemModelScatterDataProxyPrivate *>(d_ptr.data());
+}
+
+// QItemModelScatterDataProxyPrivate
+
+QItemModelScatterDataProxyPrivate::QItemModelScatterDataProxyPrivate(QItemModelScatterDataProxy *q)
+ : QScatterDataProxyPrivate(q),
+ resolvePending(0)
+{
+ m_resolveTimer.setSingleShot(true);
+ QObject::connect(&m_resolveTimer, &QTimer::timeout, this,
+ &QItemModelScatterDataProxyPrivate::handlePendingResolve);
+}
+
+QItemModelScatterDataProxyPrivate::~QItemModelScatterDataProxyPrivate()
+{
+}
+
+void QItemModelScatterDataProxyPrivate::setItemModel(QAbstractItemModel *itemModel)
+{
+ if (!m_itemModel.isNull())
+ QObject::disconnect(m_itemModel, 0, this, 0);
+
+ m_itemModel = itemModel;
+
+ if (!m_itemModel.isNull()) {
+ QObject::connect(m_itemModel, &QAbstractItemModel::columnsInserted, this,
+ &QItemModelScatterDataProxyPrivate::handleColumnsInserted);
+ QObject::connect(m_itemModel, &QAbstractItemModel::columnsMoved, this,
+ &QItemModelScatterDataProxyPrivate::handleColumnsMoved);
+ QObject::connect(m_itemModel, &QAbstractItemModel::columnsRemoved, this,
+ &QItemModelScatterDataProxyPrivate::handleColumnsRemoved);
+ QObject::connect(m_itemModel, &QAbstractItemModel::dataChanged, this,
+ &QItemModelScatterDataProxyPrivate::handleDataChanged);
+ QObject::connect(m_itemModel, &QAbstractItemModel::layoutChanged, this,
+ &QItemModelScatterDataProxyPrivate::handleLayoutChanged);
+ QObject::connect(m_itemModel, &QAbstractItemModel::modelReset, this,
+ &QItemModelScatterDataProxyPrivate::handleModelReset);
+ QObject::connect(m_itemModel, &QAbstractItemModel::rowsInserted, this,
+ &QItemModelScatterDataProxyPrivate::handleRowsInserted);
+ QObject::connect(m_itemModel, &QAbstractItemModel::rowsMoved, this,
+ &QItemModelScatterDataProxyPrivate::handleRowsMoved);
+ QObject::connect(m_itemModel, &QAbstractItemModel::rowsRemoved, this,
+ &QItemModelScatterDataProxyPrivate::handleRowsRemoved);
+ }
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0);
+}
+
+void QItemModelScatterDataProxyPrivate::setMapping(QItemModelScatterDataMapping *mapping)
+{
+ if (!m_mapping.isNull())
+ QObject::disconnect(m_mapping.data(), &QItemModelScatterDataMapping::mappingChanged, this,
+ &QItemModelScatterDataProxyPrivate::handleMappingChanged);
+
+ m_mapping = mapping;
+
+ if (!m_mapping.isNull())
+ QObject::connect(m_mapping.data(), &QItemModelScatterDataMapping::mappingChanged, this,
+ &QItemModelScatterDataProxyPrivate::handleMappingChanged);
+
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0);
+}
+
+void QItemModelScatterDataProxyPrivate::handleColumnsInserted(const QModelIndex &parent,
+ int start, int end)
+{
+ Q_UNUSED(parent)
+ Q_UNUSED(start)
+ Q_UNUSED(end)
+
+ // Resolve new items
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0); // TODO Resolving entire model is inefficient
+}
+
+void QItemModelScatterDataProxyPrivate::handleColumnsMoved(const QModelIndex &sourceParent,
+ int sourceStart, int sourceEnd,
+ const QModelIndex &destinationParent,
+ int destinationColumn)
+{
+ Q_UNUSED(sourceParent)
+ Q_UNUSED(sourceStart)
+ Q_UNUSED(sourceEnd)
+ Q_UNUSED(destinationParent)
+ Q_UNUSED(destinationColumn)
+
+ // Resolve moved items
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0); // TODO Resolving entire model is inefficient
+}
+
+void QItemModelScatterDataProxyPrivate::handleColumnsRemoved(const QModelIndex &parent,
+ int start, int end)
+{
+ Q_UNUSED(parent)
+ Q_UNUSED(start)
+ Q_UNUSED(end)
+
+ // Remove old items
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0); // TODO Resolving entire model is inefficient
+}
+
+void QItemModelScatterDataProxyPrivate::handleDataChanged(const QModelIndex &topLeft,
+ const QModelIndex &bottomRight,
+ const QVector<int> &roles)
+{
+ Q_UNUSED(topLeft)
+ Q_UNUSED(bottomRight)
+ Q_UNUSED(roles)
+
+ // Resolve changed items
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0); // TODO Resolving entire model is inefficient
+}
+
+void QItemModelScatterDataProxyPrivate::handleLayoutChanged(
+ const QList<QPersistentModelIndex> &parents,
+ QAbstractItemModel::LayoutChangeHint hint)
+{
+ Q_UNUSED(parents)
+ Q_UNUSED(hint)
+
+ // Resolve moved items
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0); // TODO Resolving entire model is inefficient
+}
+
+void QItemModelScatterDataProxyPrivate::handleModelReset()
+{
+ // Data cleared, reset array
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0); // TODO Resolving entire model is inefficient
+}
+
+void QItemModelScatterDataProxyPrivate::handleRowsInserted(const QModelIndex &parent,
+ int start, int end)
+{
+ Q_UNUSED(parent)
+ Q_UNUSED(start)
+ Q_UNUSED(end)
+
+ // Resolve new items
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0); // TODO Resolving entire model is inefficient
+}
+
+void QItemModelScatterDataProxyPrivate::handleRowsMoved(const QModelIndex &sourceParent,
+ int sourceStart, int sourceEnd,
+ const QModelIndex &destinationParent,
+ int destinationRow)
+{
+ Q_UNUSED(sourceParent)
+ Q_UNUSED(sourceStart)
+ Q_UNUSED(sourceEnd)
+ Q_UNUSED(destinationParent)
+ Q_UNUSED(destinationRow)
+
+ // Resolve moved items
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0); // TODO Resolving entire model is inefficient
+}
+
+void QItemModelScatterDataProxyPrivate::handleRowsRemoved(const QModelIndex &parent,
+ int start, int end)
+{
+ Q_UNUSED(parent)
+ Q_UNUSED(start)
+ Q_UNUSED(end)
+
+ // Resolve removed items
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0); // TODO Resolving entire model is inefficient
+}
+
+void QItemModelScatterDataProxyPrivate::handleMappingChanged()
+{
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0);
+}
+
+void QItemModelScatterDataProxyPrivate::handlePendingResolve()
+{
+ resolveModel();
+}
+
+// Resolve entire item model into QScatterDataArray.
+void QItemModelScatterDataProxyPrivate::resolveModel()
+{
+ if (m_itemModel.isNull() || m_mapping.isNull()) {
+ qptr()->resetArray(0);
+ return;
+ }
+
+ static const int noRoleIndex = -1;
+
+ QHash<int, QByteArray> roleHash = m_itemModel->roleNames();
+ //const int labelRole = roleHash.key(m_mapping->labelRole().toLatin1(), noRoleIndex);
+ const int xPosRole = roleHash.key(m_mapping->xPosRole().toLatin1(), noRoleIndex);
+ const int yPosRole = roleHash.key(m_mapping->yPosRole().toLatin1(), noRoleIndex);
+ const int zPosRole = roleHash.key(m_mapping->zPosRole().toLatin1(), noRoleIndex);
+ // Default valueRole to display role if no mapping
+ //const int valueRole = roleHash.key(m_mapping->valueRole().toLatin1(), Qt::DisplayRole);
+ const int columnCount = m_itemModel->columnCount();
+ const int rowCount = m_itemModel->rowCount();
+ const int totalCount = rowCount * columnCount;
+ int runningCount = 0;
+
+ // Parse data into newProxyArray
+ QScatterDataArray *newProxyArray = new QScatterDataArray(totalCount);
+ for (int i = 0; i < rowCount; i++) {
+ for (int j = 0; j < columnCount; j++) {
+ QModelIndex index = m_itemModel->index(i, j);
+ //if (labelRole != noRoleIndex)
+ // (*newProxyArray)[runningCount].setLabel(index.data(labelRole).toString());
+ float xPos(0.0f);
+ float yPos(0.0f);
+ float zPos(0.0f);
+ if (xPosRole != noRoleIndex)
+ xPos = index.data(xPosRole).toFloat();
+ if (yPosRole != noRoleIndex)
+ yPos = index.data(yPosRole).toFloat();
+ if (zPosRole != noRoleIndex)
+ zPos = index.data(zPosRole).toFloat();
+ (*newProxyArray)[runningCount].setPosition(QVector3D(xPos, yPos, zPos));
+ //(*newProxyArray)[runningCount].setValue(index.data(valueRole).toReal());
+ runningCount++;
+ }
+ }
+
+ qDebug() << __FUNCTION__ << "Total count:" << newProxyArray->size();
+
+ qptr()->resetArray(newProxyArray);
+}
+
+QItemModelScatterDataProxy *QItemModelScatterDataProxyPrivate::qptr()
+{
+ return static_cast<QItemModelScatterDataProxy *>(q_ptr);
+}
+
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/data/qitemmodelscatterdataproxy.h b/src/datavis3d/data/qitemmodelscatterdataproxy.h
new file mode 100644
index 00000000..f609e84b
--- /dev/null
+++ b/src/datavis3d/data/qitemmodelscatterdataproxy.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef QITEMMODELSCATTERDATAPROXY_H
+#define QITEMMODELSCATTERDATAPROXY_H
+
+#include <QtDataVis3D/qscatterdataproxy.h>
+#include <QtDataVis3D/qitemmodelscatterdatamapping.h>
+#include <QAbstractItemModel>
+#include <QStringList>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class QItemModelScatterDataProxyPrivate;
+
+class QT_DATAVIS3D_EXPORT QItemModelScatterDataProxy : public QScatterDataProxy
+{
+ Q_OBJECT
+
+public:
+ explicit QItemModelScatterDataProxy();
+ explicit QItemModelScatterDataProxy(QAbstractItemModel *itemModel,
+ QItemModelScatterDataMapping *mapping);
+ virtual ~QItemModelScatterDataProxy();
+
+ // Doesn't gain ownership of the model, but does connect to it to listen for data changes.
+ void setItemModel(QAbstractItemModel *itemModel);
+ QAbstractItemModel *itemModel();
+
+ // Map scatter role (xPos, yPos, zPos) to role in model
+ // Doesn't gain ownership of mapping, but does connect to it to listen for mapping changes.
+ // Modifying mapping that is set to proxy will trigger dataset re-resolving.
+ void setMapping(QItemModelScatterDataMapping *mapping);
+ QItemModelScatterDataMapping *mapping();
+
+protected:
+ QItemModelScatterDataProxyPrivate *dptr();
+
+private:
+ Q_DISABLE_COPY(QItemModelScatterDataProxy)
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/data/qitemmodelscatterdataproxy_p.h b/src/datavis3d/data/qitemmodelscatterdataproxy_p.h
new file mode 100644
index 00000000..aed3d974
--- /dev/null
+++ b/src/datavis3d/data/qitemmodelscatterdataproxy_p.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef QITEMMODELSCATTERDATAPROXY_P_H
+#define QITEMMODELSCATTERDATAPROXY_P_H
+
+#include "qitemmodelscatterdataproxy.h"
+#include "qscatterdataproxy_p.h"
+#include <QPointer>
+#include <QTimer>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class QItemModelScatterDataProxyPrivate : public QScatterDataProxyPrivate
+{
+ Q_OBJECT
+public:
+ QItemModelScatterDataProxyPrivate(QItemModelScatterDataProxy *q);
+ virtual ~QItemModelScatterDataProxyPrivate();
+
+ void setItemModel(QAbstractItemModel *itemModel);
+ void setMapping(QItemModelScatterDataMapping *mapping);
+
+public slots:
+ void handleColumnsInserted(const QModelIndex &parent, int start, int end);
+ void handleColumnsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd,
+ const QModelIndex &destinationParent, int destinationColumn);
+ void handleColumnsRemoved(const QModelIndex &parent, int start, int end);
+ void handleDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight,
+ const QVector<int> &roles = QVector<int> ());
+ void handleLayoutChanged(const QList<QPersistentModelIndex> &parents = QList<QPersistentModelIndex> (),
+ QAbstractItemModel::LayoutChangeHint hint = QAbstractItemModel::NoLayoutChangeHint);
+ void handleModelReset();
+ void handleRowsInserted(const QModelIndex &parent, int start, int end);
+ void handleRowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd,
+ const QModelIndex &destinationParent, int destinationRow);
+ void handleRowsRemoved(const QModelIndex &parent, int start, int end);
+
+ void handleMappingChanged();
+ void handlePendingResolve();
+
+private:
+ void resolveModel();
+ QItemModelScatterDataProxy *qptr();
+
+ QPointer<QAbstractItemModel> m_itemModel; // Not owned
+ QPointer<QItemModelScatterDataMapping> m_mapping; // Not owned
+ bool resolvePending;
+ QTimer m_resolveTimer;
+
+ friend class QItemModelScatterDataProxy;
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/data/qmapdataitem.cpp b/src/datavis3d/data/qmapdataitem.cpp
new file mode 100644
index 00000000..2fe9b6e8
--- /dev/null
+++ b/src/datavis3d/data/qmapdataitem.cpp
@@ -0,0 +1,100 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "qmapdataitem_p.h"
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+/*!
+ * \class QMapDataItem
+ * \inmodule QtDataVis3D
+ * \brief The QMapDataItem class provides a container for resolved data to be added to maps graphs.
+ * \since 1.0.0
+ *
+ * A QMapDataItem holds data for a single rendered bar in a maps graph.
+ * Maps data proxies parse data into QMapDataItem instances for visualizing.
+ *
+ * \sa QMapDataProxy, {Qt Data Visualization 3D C++ Classes}
+ */
+
+/*!
+ * Constructs QMapDataItem.
+ */
+QMapDataItem::QMapDataItem()
+ : QBarDataItem()
+{
+}
+
+QMapDataItem::QMapDataItem(const QMapDataItem &other)
+ : QBarDataItem(other)
+{
+ operator=(other);
+}
+
+/*!
+ * Destroys QMapDataItem.
+ */
+QMapDataItem::~QMapDataItem()
+{
+}
+
+QMapDataItem &QMapDataItem::operator=(const QMapDataItem &other)
+{
+ QBarDataItem::operator =(other);
+ m_mapPosition = other.m_mapPosition;
+ m_label = other.m_label;
+
+ return *this;
+}
+
+void QMapDataItem::setMapPosition(const QPointF &position)
+{
+ m_mapPosition = position;
+}
+
+QPointF QMapDataItem::mapPosition() const
+{
+ return m_mapPosition;
+}
+
+void QMapDataItem::setLabel(const QString &label)
+{
+ m_label = label;
+}
+
+QString QMapDataItem::label() const
+{
+ return m_label;
+}
+
+void QMapDataItem::createExtraData()
+{
+ if (!d_ptr)
+ d_ptr = new QMapDataItemPrivate;
+}
+
+QMapDataItemPrivate::QMapDataItemPrivate()
+ : QBarDataItemPrivate()
+{
+}
+
+QMapDataItemPrivate::~QMapDataItemPrivate()
+{
+}
+
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/data/qmapdataitem.h b/src/datavis3d/data/qmapdataitem.h
new file mode 100644
index 00000000..240b03dd
--- /dev/null
+++ b/src/datavis3d/data/qmapdataitem.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef QMAPDATAITEM_H
+#define QMAPDATAITEM_H
+
+#include <QtDataVis3D/qdatavis3denums.h>
+#include <QtDataVis3D/qbardataitem.h>
+#include <QPointF>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class QMapDataItemPrivate;
+
+class QT_DATAVIS3D_EXPORT QMapDataItem : public QBarDataItem
+{
+public:
+ QMapDataItem();
+ QMapDataItem(const QMapDataItem &other);
+ ~QMapDataItem();
+
+ QMapDataItem &operator=(const QMapDataItem &other);
+
+ void setMapPosition(const QPointF &position);
+ QPointF mapPosition() const;
+
+ void setLabel(const QString &label);
+ QString label() const;
+
+protected:
+ virtual void createExtraData();
+
+ QMapDataItemPrivate *d_ptr;
+
+private:
+ QPointF m_mapPosition;
+ QString m_label;
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/data/qmapdataitem_p.h b/src/datavis3d/data/qmapdataitem_p.h
new file mode 100644
index 00000000..2926e3ef
--- /dev/null
+++ b/src/datavis3d/data/qmapdataitem_p.h
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef QMAPDATAITEM_P_H
+#define QMAPDATAITEM_P_H
+
+#include "datavis3dglobal_p.h"
+#include "qmapdataitem.h"
+#include "qbardataitem_p.h"
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class QMapDataItemPrivate : public QBarDataItemPrivate
+{
+public:
+ QMapDataItemPrivate();
+ virtual ~QMapDataItemPrivate();
+
+ // TODO stores other data for map items besides position
+
+protected:
+ friend class QMapDataItem;
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/data/qmapdataproxy.cpp b/src/datavis3d/data/qmapdataproxy.cpp
new file mode 100644
index 00000000..a7a0e9d5
--- /dev/null
+++ b/src/datavis3d/data/qmapdataproxy.cpp
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "qmapdataproxy.h"
+#include "qmapdataproxy_p.h"
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+QMapDataProxy::QMapDataProxy() :
+ QAbstractDataProxy(new QMapDataProxyPrivate(this))
+{
+}
+
+QMapDataProxy::QMapDataProxy(QMapDataProxyPrivate *d) :
+ QAbstractDataProxy(d)
+{
+}
+
+QMapDataProxy::~QMapDataProxy()
+{
+}
+
+void QMapDataProxy::resetArray(QMapDataArray *newArray)
+{
+ if (dptr()->resetArray(newArray))
+ emit arrayReset();
+}
+
+
+int QMapDataProxy::itemCount() const
+{
+ return dptrc()->m_dataArray.size();
+}
+
+const QMapDataArray *QMapDataProxy::array() const
+{
+ return &dptrc()->m_dataArray;
+}
+
+const QMapDataItem *QMapDataProxy::itemAt(int index) const
+{
+ return &dptrc()->m_dataArray.at(index);
+}
+
+QMapDataProxyPrivate *QMapDataProxy::dptr()
+{
+ return static_cast<QMapDataProxyPrivate *>(d_ptr.data());
+}
+
+const QMapDataProxyPrivate *QMapDataProxy::dptrc() const
+{
+ return static_cast<const QMapDataProxyPrivate *>(d_ptr.data());
+}
+
+// QBarDataProxyPrivate
+
+QMapDataProxyPrivate::QMapDataProxyPrivate(QMapDataProxy *q)
+ : QAbstractDataProxyPrivate(q, QAbstractDataProxy::DataTypeMap)
+{
+}
+
+QMapDataProxyPrivate::~QMapDataProxyPrivate()
+{
+ m_dataArray.clear();
+}
+
+bool QMapDataProxyPrivate::resetArray(QMapDataArray *newArray)
+{
+ if (!m_dataArray.size() && (!newArray || !newArray->size()))
+ return false;
+
+ m_dataArray.clear();
+
+ if (newArray) {
+ m_dataArray = *newArray;
+ delete newArray;
+ }
+
+ return true;
+}
+
+QPair<GLfloat, GLfloat> QMapDataProxyPrivate::limitValues()
+{
+ QPair<GLfloat, GLfloat> limits = qMakePair(0.0f, 0.0f);
+ for (int i = 0; i < m_dataArray.size(); i++) {
+ const QMapDataItem &item = m_dataArray.at(i);
+ qreal itemValue = item.value();
+ if (limits.second < itemValue)
+ limits.second = itemValue;
+ if (limits.first > itemValue)
+ limits.first = itemValue;
+ }
+ return limits;
+}
+
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/data/qmapdataproxy.h b/src/datavis3d/data/qmapdataproxy.h
new file mode 100644
index 00000000..45bb95d5
--- /dev/null
+++ b/src/datavis3d/data/qmapdataproxy.h
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef QMAPDATAPROXY_H
+#define QMAPDATAPROXY_H
+
+#include <QtDataVis3D/qabstractdataproxy.h>
+#include <QtDataVis3D/qmapdataitem.h>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+typedef QVector<QMapDataItem> QMapDataArray;
+
+class QMapDataProxyPrivate;
+
+class QT_DATAVIS3D_EXPORT QMapDataProxy : public QAbstractDataProxy
+{
+ Q_OBJECT
+
+public:
+ explicit QMapDataProxy();
+ explicit QMapDataProxy(QMapDataProxyPrivate *d);
+ virtual ~QMapDataProxy();
+
+ // QMapDataProxy is also optimized to use cases where the only defining characteristics of an individual
+ // map item are it's value and position. Modifying other data such as color or mesh of individual bar
+ // requires allocating additional data object for the bar.
+
+ // Item pointers are guaranteed to be valid only until next call that modifies data.
+ // Array pointer is guaranteed to be valid for lifetime of proxy.
+ int itemCount() const;
+ const QMapDataArray *array() const;
+ const QMapDataItem *itemAt(int index) const; // Index needs to exist or this crashes
+
+ // TODO Should data manipulation/access methods be protected rather than public to enforce subclassing use of proxy?
+ // TODO Leaving them public gives user more options.
+
+ // QMapDataProxy takes ownership of all QMapDataArrays and QMapDataItems passed to it.
+
+ // Clears the existing array and sets it data to new array.
+ void resetArray(QMapDataArray *newArray);
+
+ // TODO void setItem(int index, QMapDataItem *item);
+ // TODO void setItems(int index, QMapDataArray *items);
+
+ // TODO int addItem(QMapDataItem *item); // returns the index of added item
+ // TODO int addItems(QMapDataArray *items); // returns the index of added item
+
+ // TODO void insertItem(int index, QMapDataItem *item);
+ // TODO void insertItems(int index, QMapDataArray *items);
+
+ // TODO void removeItems(int index, int removeCount);
+
+signals:
+ void arrayReset();
+ void itemsAdded(int startIndex, int count);
+ void itemsChanged(int startIndex, int count);
+ void itemsRemoved(int startIndex, int count); // Index may be over current array size if removed from end
+ void itemsInserted(int startIndex, int count);
+
+protected:
+ QMapDataProxyPrivate *dptr();
+ const QMapDataProxyPrivate *dptrc() const;
+
+private:
+ Q_DISABLE_COPY(QMapDataProxy)
+
+ friend class Maps3DController;
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/data/qmapdataproxy_p.h b/src/datavis3d/data/qmapdataproxy_p.h
new file mode 100644
index 00000000..bf3d1d2c
--- /dev/null
+++ b/src/datavis3d/data/qmapdataproxy_p.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef QMAPDATAPROXY_P_H
+#define QMAPDATAPROXY_P_H
+
+#include "qmapdataproxy.h"
+#include "qabstractdataproxy_p.h"
+#include "qmapdataitem.h"
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class QMapDataProxyPrivate : public QAbstractDataProxyPrivate
+{
+ Q_OBJECT
+public:
+ QMapDataProxyPrivate(QMapDataProxy *q);
+ virtual ~QMapDataProxyPrivate();
+
+ bool resetArray(QMapDataArray *newArray);
+
+ QPair<GLfloat, GLfloat> limitValues();
+
+private:
+ QMapDataArray m_dataArray;
+
+private:
+ friend class QMapDataProxy;
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif // QBARDATAPROXY_P_H
diff --git a/src/datavis3d/data/qscatterdataitem.cpp b/src/datavis3d/data/qscatterdataitem.cpp
new file mode 100644
index 00000000..e2580339
--- /dev/null
+++ b/src/datavis3d/data/qscatterdataitem.cpp
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "qscatterdataitem_p.h"
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+/*!
+ * \class QScatterDataItem
+ * \inmodule QtDataVis3D
+ * \brief The QScatterDataItem class provides a container for resolved data to be added to scatter
+ * graphs.
+ * \since 1.0.0
+ *
+ * A QScatterDataItem holds data for a single rendered item in a scatter graph.
+ * Scatter data proxies parse data into QScatterDataItem instances for visualizing.
+ *
+ * \sa QScatterDataProxy, {Qt Data Visualization 3D C++ Classes}
+ */
+
+/*!
+ * Constructs QScatterDataItem.
+ */
+QScatterDataItem::QScatterDataItem()
+ : d_ptr(0) // private data doesn't exist by default (optimization)
+
+{
+}
+
+QScatterDataItem::QScatterDataItem(const QVector3D &position)
+ : d_ptr(0),
+ m_position(position)
+{
+}
+
+QScatterDataItem::QScatterDataItem(const QScatterDataItem &other)
+{
+ operator=(other);
+}
+
+/*!
+ * Destroys QScatterDataItem.
+ */
+QScatterDataItem::~QScatterDataItem()
+{
+}
+
+QScatterDataItem &QScatterDataItem::operator=(const QScatterDataItem &other)
+{
+ m_position = other.m_position;
+ //m_size = other.m_size;
+
+ if (other.d_ptr)
+ createExtraData();
+ else
+ d_ptr = 0;
+ // TODO set extra data
+
+ return *this;
+}
+
+void QScatterDataItem::setPosition(const QVector3D &position)
+{
+ m_position = position;
+}
+
+const QVector3D &QScatterDataItem::position() const
+{
+ return m_position;
+}
+
+//void QScatterDataItem::setSize(qreal size)
+//{
+// m_size = size;
+//}
+
+//const qreal &QScatterDataItem::size() const
+//{
+// return m_size;
+//}
+
+void QScatterDataItem::createExtraData()
+{
+ if (!d_ptr)
+ d_ptr = new QScatterDataItemPrivate;
+}
+
+QScatterDataItemPrivate::QScatterDataItemPrivate()
+{
+}
+
+QScatterDataItemPrivate::~QScatterDataItemPrivate()
+{
+}
+
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/data/qscatterdataitem.h b/src/datavis3d/data/qscatterdataitem.h
new file mode 100644
index 00000000..82383ae6
--- /dev/null
+++ b/src/datavis3d/data/qscatterdataitem.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef QSCATTERDATAITEM_H
+#define QSCATTERDATAITEM_H
+
+#include <QtDataVis3D/qdatavis3denums.h>
+#include <QVector3D>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class QScatterDataItemPrivate;
+
+class QT_DATAVIS3D_EXPORT QScatterDataItem
+{
+public:
+ QScatterDataItem();
+ QScatterDataItem(const QVector3D &position);
+ QScatterDataItem(const QScatterDataItem &other);
+ ~QScatterDataItem();
+
+ QScatterDataItem &operator=(const QScatterDataItem &other);
+
+ void setPosition(const QVector3D &position);
+ const QVector3D &position() const;
+
+ //void setSize(qreal size);
+ //qreal size() const;
+
+protected:
+ virtual void createExtraData();
+
+ QScatterDataItemPrivate *d_ptr;
+
+private:
+ QVector3D m_position;
+ //qreal m_size;
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/data/qscatterdataitem_p.h b/src/datavis3d/data/qscatterdataitem_p.h
new file mode 100644
index 00000000..3718a185
--- /dev/null
+++ b/src/datavis3d/data/qscatterdataitem_p.h
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef QSCATTERDATAITEM_P_H
+#define QSCATTERDATAITEM_P_H
+
+#include "datavis3dglobal_p.h"
+#include "qscatterdataitem.h"
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class QScatterDataItemPrivate
+{
+public:
+ QScatterDataItemPrivate();
+ virtual ~QScatterDataItemPrivate();
+
+ // TODO stores other data for scatter items besides position
+
+protected:
+ friend class QScatterDataItem;
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/data/qscatterdataproxy.cpp b/src/datavis3d/data/qscatterdataproxy.cpp
new file mode 100644
index 00000000..d2f544ef
--- /dev/null
+++ b/src/datavis3d/data/qscatterdataproxy.cpp
@@ -0,0 +1,210 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "qscatterdataproxy.h"
+#include "qscatterdataproxy_p.h"
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+QScatterDataProxy::QScatterDataProxy() :
+ QAbstractDataProxy(new QScatterDataProxyPrivate(this))
+{
+}
+
+QScatterDataProxy::QScatterDataProxy(QScatterDataProxyPrivate *d) :
+ QAbstractDataProxy(d)
+{
+}
+
+QScatterDataProxy::~QScatterDataProxy()
+{
+}
+
+void QScatterDataProxy::resetArray(QScatterDataArray *newArray)
+{
+ if (dptr()->resetArray(newArray))
+ emit arrayReset();
+}
+
+void QScatterDataProxy::setItem(int index, const QScatterDataItem &item)
+{
+ dptr()->setItem(index, item);
+ emit itemsChanged(index, 1);
+}
+
+void QScatterDataProxy::setItems(int index, const QScatterDataArray &items)
+{
+ dptr()->setItems(index, items);
+ emit itemsChanged(index, items.size());
+}
+
+int QScatterDataProxy::addItem(const QScatterDataItem &item)
+{
+ int addIndex = dptr()->addItem(item);
+ emit itemsAdded(addIndex, 1);
+ return addIndex;
+}
+
+int QScatterDataProxy::addItems(const QScatterDataArray &items)
+{
+ int addIndex = dptr()->addItems(items);
+ emit itemsAdded(addIndex, items.size());
+ return addIndex;
+}
+
+void QScatterDataProxy::insertItem(int index, const QScatterDataItem &item)
+{
+ dptr()->insertItem(index, item);
+ emit itemsInserted(index, 1);
+}
+
+void QScatterDataProxy::insertItems(int index, const QScatterDataArray &items)
+{
+ dptr()->insertItems(index, items);
+ emit itemsInserted(index, items.size());
+}
+
+void QScatterDataProxy::removeItems(int index, int removeCount)
+{
+ dptr()->removeItems(index, removeCount);
+ emit itemsRemoved(index, removeCount);
+}
+
+int QScatterDataProxy::itemCount() const
+{
+ return dptrc()->m_dataArray->size();
+}
+
+const QScatterDataArray *QScatterDataProxy::array() const
+{
+ return dptrc()->m_dataArray;
+}
+
+const QScatterDataItem *QScatterDataProxy::itemAt(int index) const
+{
+ return &dptrc()->m_dataArray->at(index);
+}
+
+QScatterDataProxyPrivate *QScatterDataProxy::dptr()
+{
+ return static_cast<QScatterDataProxyPrivate *>(d_ptr.data());
+}
+
+const QScatterDataProxyPrivate *QScatterDataProxy::dptrc() const
+{
+ return static_cast<const QScatterDataProxyPrivate *>(d_ptr.data());
+}
+
+// QScatterDataProxyPrivate
+
+QScatterDataProxyPrivate::QScatterDataProxyPrivate(QScatterDataProxy *q)
+ : QAbstractDataProxyPrivate(q, QAbstractDataProxy::DataTypeScatter),
+ m_dataArray(new QScatterDataArray)
+{
+}
+
+QScatterDataProxyPrivate::~QScatterDataProxyPrivate()
+{
+ m_dataArray->clear();
+ delete m_dataArray;
+}
+
+bool QScatterDataProxyPrivate::resetArray(QScatterDataArray *newArray)
+{
+ if (!m_dataArray->size() && (!newArray || !newArray->size()))
+ return false;
+
+ m_dataArray->clear();
+ delete m_dataArray;
+
+ if (newArray)
+ m_dataArray = newArray;
+ else
+ m_dataArray = new QScatterDataArray;
+
+ return true;
+}
+
+void QScatterDataProxyPrivate::setItem(int index, const QScatterDataItem &item)
+{
+ Q_ASSERT(index >= 0 && index < m_dataArray->size());
+ (*m_dataArray)[index] = item;
+}
+
+void QScatterDataProxyPrivate::setItems(int index, const QScatterDataArray &items)
+{
+ Q_ASSERT(index >= 0 && (index + items.size()) <= m_dataArray->size());
+ for (int i = 0; i < items.size(); i++)
+ (*m_dataArray)[index++] = items[i];
+}
+
+int QScatterDataProxyPrivate::addItem(const QScatterDataItem &item)
+{
+ int currentSize = m_dataArray->size();
+ m_dataArray->append(item);
+ return currentSize;
+}
+
+int QScatterDataProxyPrivate::addItems(const QScatterDataArray &items)
+{
+ int currentSize = m_dataArray->size();
+ (*m_dataArray) += items;
+ return currentSize;
+}
+
+void QScatterDataProxyPrivate::insertItem(int index, const QScatterDataItem &item)
+{
+ Q_ASSERT(index >= 0 && index <= m_dataArray->size());
+ m_dataArray->insert(index, item);
+}
+
+void QScatterDataProxyPrivate::insertItems(int index, const QScatterDataArray &items)
+{
+ Q_ASSERT(index >= 0 && index <= m_dataArray->size());
+ for (int i = 0; i < items.size(); i++)
+ m_dataArray->insert(index++, items.at(i));
+}
+
+void QScatterDataProxyPrivate::removeItems(int index, int removeCount)
+{
+ Q_ASSERT(index >= 0);
+ int maxRemoveCount = m_dataArray->size() - index;
+ removeCount = qMin(removeCount, maxRemoveCount);
+ m_dataArray->remove(index, removeCount);
+}
+
+QVector3D QScatterDataProxyPrivate::limitValues()
+{
+ QVector3D limits;
+ for (int i = 0; i < m_dataArray->size(); i++) {
+ const QScatterDataItem &item = m_dataArray->at(i);
+ float xValue = qAbs(item.position().x());
+ if (limits.x() < xValue)
+ limits.setX(xValue);
+ float yValue = qAbs(item.position().y());
+ if (limits.y() < yValue)
+ limits.setY(yValue);
+ float zValue = qAbs(item.position().z());
+ if (limits.z() < zValue)
+ limits.setZ(zValue);
+ }
+ //qDebug() << __FUNCTION__ << limits << m_dataArray.size();
+ return limits;
+}
+
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/data/qscatterdataproxy.h b/src/datavis3d/data/qscatterdataproxy.h
new file mode 100644
index 00000000..9e139c00
--- /dev/null
+++ b/src/datavis3d/data/qscatterdataproxy.h
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef QSCATTERDATAPROXY_H
+#define QSCATTERDATAPROXY_H
+
+#include <QtDataVis3D/qabstractdataproxy.h>
+#include <QtDataVis3D/qscatterdataitem.h>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+typedef QVector<QScatterDataItem> QScatterDataArray;
+
+class QScatterDataProxyPrivate;
+
+class QT_DATAVIS3D_EXPORT QScatterDataProxy : public QAbstractDataProxy
+{
+ Q_OBJECT
+
+public:
+ explicit QScatterDataProxy();
+ explicit QScatterDataProxy(QScatterDataProxyPrivate *d);
+ virtual ~QScatterDataProxy();
+
+ // QScatterDataProxy is optimized to use cases where the only defining characteristics of an
+ // individual scatter item are it's position and size. Modifying other data that might be
+ // added in the future such as color requires allocating additional data object for the bar.
+
+ // Item pointers are guaranteed to be valid only until next call that modifies data.
+ // Array pointer is guaranteed to be valid for lifetime of proxy.
+ int itemCount() const;
+ const QScatterDataArray *array() const;
+ const QScatterDataItem *itemAt(int index) const;
+
+ // Clears the existing array and takes ownership of the new array.
+ // Passing null array clears all data.
+ void resetArray(QScatterDataArray *newArray);
+
+ // Change existing items
+ void setItem(int index, const QScatterDataItem &item);
+ void setItems(int index, const QScatterDataArray &items);
+
+ int addItem(const QScatterDataItem &item); // returns the index of added item
+ int addItems(const QScatterDataArray &items); // returns the index of first added item
+
+ // If index is equal to data array size, item(s) are added to the array.
+ void insertItem(int index, const QScatterDataItem &item);
+ void insertItems(int index, const QScatterDataArray &items);
+
+ // Attempting to remove items past the end of the array does nothing.
+ void removeItems(int index, int removeCount);
+
+signals:
+ void arrayReset();
+ void itemsAdded(int startIndex, int count);
+ void itemsChanged(int startIndex, int count);
+ void itemsRemoved(int startIndex, int count); // Index may be over current array size if removed from end
+ void itemsInserted(int startIndex, int count);
+
+protected:
+ QScatterDataProxyPrivate *dptr();
+ const QScatterDataProxyPrivate *dptrc() const;
+
+private:
+ Q_DISABLE_COPY(QScatterDataProxy)
+
+ friend class Scatter3DController;
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/data/qscatterdataproxy_p.h b/src/datavis3d/data/qscatterdataproxy_p.h
new file mode 100644
index 00000000..526845fd
--- /dev/null
+++ b/src/datavis3d/data/qscatterdataproxy_p.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef QSCATTERDATAPROXY_P_H
+#define QSCATTERDATAPROXY_P_H
+
+#include "qscatterdataproxy.h"
+#include "qabstractdataproxy_p.h"
+#include "qscatterdataitem.h"
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class QScatterDataProxyPrivate : public QAbstractDataProxyPrivate
+{
+ Q_OBJECT
+public:
+ QScatterDataProxyPrivate(QScatterDataProxy *q);
+ virtual ~QScatterDataProxyPrivate();
+
+ bool resetArray(QScatterDataArray *newArray);
+ void setItem(int index, const QScatterDataItem &item);
+ void setItems(int index, const QScatterDataArray &items);
+ int addItem(const QScatterDataItem &item);
+ int addItems(const QScatterDataArray &items);
+ void insertItem(int index, const QScatterDataItem &item);
+ void insertItems(int index, const QScatterDataArray &items);
+ void removeItems(int index, int removeCount);
+
+ QVector3D limitValues();
+
+private:
+ QScatterDataArray *m_dataArray;
+ QString m_itemLabelFormat;
+
+ friend class QScatterDataProxy;
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif // QBARDATAPROXY_P_H
diff --git a/src/datavis3d/data/scatterrenderitem.cpp b/src/datavis3d/data/scatterrenderitem.cpp
new file mode 100644
index 00000000..15281c0a
--- /dev/null
+++ b/src/datavis3d/data/scatterrenderitem.cpp
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "scatterrenderitem_p.h"
+#include "scatter3drenderer_p.h"
+#include "qscatterdataproxy.h"
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+ScatterRenderItem::ScatterRenderItem()
+ : BarRenderItem()
+{
+}
+
+ScatterRenderItem::~ScatterRenderItem()
+{
+}
+
+void ScatterRenderItem::formatLabel()
+{
+ // TODO The label format specified in proxy should probably have additional custom formatting
+ // TODO specifiers in addition to standard printf specifiers for placement of item labels
+ // TODO and selection data (like row/column in bar selection)
+
+ // Format the string on first access
+ QString numStr;
+ numStr.setNum(m_value);
+ // TODO actually format instead of just prepending the value
+ m_label.clear(); // Just in case
+ //m_label.append(m_itemLabel);
+ //m_label.append(QStringLiteral(" "));
+ m_label.append(numStr);
+ m_label.append(m_renderer->itemLabelFormat());
+}
+
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/data/scatterrenderitem_p.h b/src/datavis3d/data/scatterrenderitem_p.h
new file mode 100644
index 00000000..47cfeed2
--- /dev/null
+++ b/src/datavis3d/data/scatterrenderitem_p.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef SCATTERRENDERITEM_P_H
+#define SCATTERRENDERITEM_P_H
+
+#include "barrenderitem_p.h"
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class Scatter3DRenderer;
+
+class ScatterRenderItem : public BarRenderItem
+{
+public:
+ ScatterRenderItem();
+ virtual ~ScatterRenderItem();
+
+ inline const QVector3D &position() const { return m_position; }
+ inline void setPosition(const QVector3D &pos) { m_position = pos; }
+
+ //inline void setSize(qreal size);
+ //inline qreal size() const { return m_size; }
+
+ // TODO should be in abstract, but currently there is no abstract renderer
+ // TODO change when maps refactored
+ inline void setRenderer(Scatter3DRenderer *renderer) { m_renderer = renderer; }
+
+protected:
+ virtual void formatLabel();
+
+ Scatter3DRenderer *m_renderer;
+ QVector3D m_position;
+ //qreal m_size; // TODO in case we need a fourth variable that adjusts scatter item size
+
+ friend class QScatterDataItem;
+};
+
+typedef QVector<ScatterRenderItem> ScatterRenderItemArray;
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/datavis3d.pro b/src/datavis3d/datavis3d.pro
index 63091c55..fa548c22 100644
--- a/src/datavis3d/datavis3d.pro
+++ b/src/datavis3d/datavis3d.pro
@@ -1,7 +1,7 @@
TARGET = QtDataVis3D
QT = core gui opengl #qml
-DEFINES += QTENTERPRISE_DATAVIS3D_LIBRARY
+DEFINES += QT_DATAVIS3D_LIBRARY
QMAKE_DOCS = $$PWD/doc/qtdatavis3d.qdocconf
@@ -11,6 +11,8 @@ include($$PWD/common.pri)
include($$PWD/engine/engine.pri)
include($$PWD/global/global.pri)
include($$PWD/utils/utils.pri)
+include($$PWD/axis/axis.pri)
+include($$PWD/data/data.pri)
wince* {
# The Microsoft MIPS compiler crashes if /Og is specified.
diff --git a/src/datavis3d/doc/qtdatavis3d.qdocconf b/src/datavis3d/doc/qtdatavis3d.qdocconf
index c3fd9826..0e9f6d5b 100644
--- a/src/datavis3d/doc/qtdatavis3d.qdocconf
+++ b/src/datavis3d/doc/qtdatavis3d.qdocconf
@@ -15,7 +15,7 @@ sourcedirs += ..
depends += qtcore \
qtgui
-qhp.projects = QtDataVis3D
+qhp.projects = qtdatavis3d
qhp.qtdatavis3d.file = qtdatavis3d.qhp
qhp.qtdatavis3d.namespace = org.qt-project.qtdatavis3d.1.0.0
diff --git a/src/datavis3d/doc/snippets/doc_src_q3dbars_construction.cpp b/src/datavis3d/doc/snippets/doc_src_q3dbars_construction.cpp
index 0d94e0eb..09979d8c 100644
--- a/src/datavis3d/doc/snippets/doc_src_q3dbars_construction.cpp
+++ b/src/datavis3d/doc/snippets/doc_src_q3dbars_construction.cpp
@@ -1,40 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
-** This file is part of the documentation of the QtDataVis3D module.
+** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:BSD$
-** You may use this file under the terms of the BSD license as follows:
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
**
-** "Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions are
-** met:
-** * Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** * Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in
-** the documentation and/or other materials provided with the
-** distribution.
-** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
-** of its contributors may be used to endorse or promote products derived
-** from this software without specific prior written permission.
-**
-**
-** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
diff --git a/src/datavis3d/doc/snippets/doc_src_qtdatavis3d.cpp b/src/datavis3d/doc/snippets/doc_src_qtdatavis3d.cpp
index ac2f7f40..a3b3e8e8 100644
--- a/src/datavis3d/doc/snippets/doc_src_qtdatavis3d.cpp
+++ b/src/datavis3d/doc/snippets/doc_src_qtdatavis3d.cpp
@@ -1,41 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
diff --git a/src/datavis3d/doc/snippets/doc_src_qtdatavis3d.pro b/src/datavis3d/doc/snippets/doc_src_qtdatavis3d.pro
index 4b670157..ba0f320b 100644
--- a/src/datavis3d/doc/snippets/doc_src_qtdatavis3d.pro
+++ b/src/datavis3d/doc/snippets/doc_src_qtdatavis3d.pro
@@ -1,41 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
diff --git a/src/datavis3d/doc/src/qtdatavis3d-index.qdoc b/src/datavis3d/doc/src/qtdatavis3d-index.qdoc
index 0c9cf8cc..dae2a14d 100644
--- a/src/datavis3d/doc/src/qtdatavis3d-index.qdoc
+++ b/src/datavis3d/doc/src/qtdatavis3d-index.qdoc
@@ -1,27 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
-** This file is part of the documentation of the QtDataVis3D module.
+** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:FDL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: http://www.gnu.org/copyleft/fdl.html.
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
@@ -61,7 +52,10 @@
\li \l{Barchart Example}
\li \l{Mapdata Example}
\li \l{Qt Quick 2 Barchart Example}
+ \li \l{Qt Quick 2 Maps Example}
+ \li \l{Qt Quick 2 Scatter Example}
\li \l{Rainfall Example}
+ \li \l{Scatter Chart Example}
\li \l{Spectrum Example}
\li \l{Widget Example}
\endlist
diff --git a/src/datavis3d/doc/src/qtdatavis3d.qdoc b/src/datavis3d/doc/src/qtdatavis3d.qdoc
index 37e53161..c27fe0a3 100644
--- a/src/datavis3d/doc/src/qtdatavis3d.qdoc
+++ b/src/datavis3d/doc/src/qtdatavis3d.qdoc
@@ -1,27 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
-** This file is part of the documentation of the QtDataVis3D module.
+** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:FDL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: http://www.gnu.org/copyleft/fdl.html.
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
diff --git a/src/datavis3d/doc/src/qtdatavis3dlicense.qdoc b/src/datavis3d/doc/src/qtdatavis3dlicense.qdoc
index 9821b26f..610fb9b7 100644
--- a/src/datavis3d/doc/src/qtdatavis3dlicense.qdoc
+++ b/src/datavis3d/doc/src/qtdatavis3dlicense.qdoc
@@ -1,27 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
-** This file is part of the documentation of the Qt SVG module.
+** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:FDL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Free Documentation License Usage
-** Alternatively, this file may be used under the terms of the GNU Free
-** Documentation License version 1.3 as published by the Free Software
-** Foundation and appearing in the file included in the packaging of
-** this file. Please review the following information to ensure
-** the GNU Free Documentation License version 1.3 requirements
-** will be met: http://www.gnu.org/copyleft/fdl.html.
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
diff --git a/src/datavis3d/documentationGroups.dox b/src/datavis3d/documentationGroups.dox
deleted file mode 100644
index ed9c3f1c..00000000
--- a/src/datavis3d/documentationGroups.dox
+++ /dev/null
@@ -1,150 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtXmlPatterns module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** 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 Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-
-/**
- * @file
- * @short Contains Doxygen documentation for groups.
- */
-
-namespace QPatternist
-{
- /**
- * @short The abstract syntax tree nodes that implements the builtin
- * functions, such as @c fn:concat().
- *
- * @defgroup Patternist_functions Function Implementations
- * @author Frans Englich <frans.englich@nokia.com>
- */
-
- /**
- * @short The abstract syntax tree nodes that is generated for XPath,
- * XQuery, and XSL-T code.
- *
- * XPath's approach of compilation is traditional. An Abstract Syntax
- * Tree(AST) is built, where the Expression class is the abstract base
- * class for all kinds of implementations of expressions.
- *
- * What perhaps can be said to be characteristic for Patternist is that the
- * base class, Expression, performs a lot of work, and that sub-classes
- * declares what specific behaviors they need, which the Expression's
- * functions then bring into action.
- *
- * XPath expressions often have different amount of operands. For example,
- * the 'and' expression takes two, the context item(".") none, and the
- * if-expression three. To help expression implementations with that, there
- * exist the abstract EmptyContainer, SingleContainer, PairContainer,
- * TripleContainer, and UnlimitedContainer classes for avoiding duplicating
- * code.
- *
- * @defgroup Patternist_expressions Expressions
- * @author Frans Englich <frans.englich@nokia.com>
- */
-
- /**
- * @short Various classes that contains small utility functions.
- *
- * @defgroup Patternist Utility Classes
- * @author Frans Englich <frans.englich@nokia.com>
- */
-
- /**
- * @short Classes for the type system in the XQuery & XSL-T language.
- *
- * @defgroup Patternist_types Type system
- * @author Frans Englich <frans.englich@nokia.com>
- */
-
- /**
- * @defgroup Patternist_xdm XQuery/XPath Data Model
- * @author Frans Englich <frans.englich@nokia.com>
- */
-
- /**
- * @short Patternist's family of iterators in one of the most central parts
- * of Patternist's API, and are responsible for carrying, and typically
- * also creating, data.
- *
- * An iterator, which always is an Iterator sub-class, is similar to a
- * Java-style iterator. What signifies Patternist's iterators is that they
- * almost always contains business logic(which is the cause to their
- * efficiency).
- *
- * An example which illustrates this principle is the RangeIterator. When
- * the RangeExpression is told to create a sequence of integers between 1
- * and 1000, it doesn't enter a loop that allocates 1000 Integer instances,
- * but instead return an RangeIterator that incrementally creates the
- * numbers when asked to do so via its RangeIterator::next() function. If
- * it turns out that the expression that has the range expression as
- * operand only needs three items from it, that is what gets created, not
- * 1000.
- *
- * All iterators operates by that principle, perhaps suitably labeled as
- * "pull-based", "lazy loaded" or "serialized". Central for the XPath
- * language is that it filters and selects data, and the iterators supports
- * this well by letting the demand of the filter expressions(the callees)
- * decide how "much" source that gets computed. In this way the evaluation
- * of an expression tree can lead to a chain of pipelined iterators, where
- * the first asks the second for data and then performs its specific
- * operations, the second subsequently asks the third, and so forth.
- *
- * However, the iterators are not limited to be used for representing
- * sequences of items in the XPath Data Model. The Iterator is
- * parameterized on one argument, meaning any type of "units" can be
- * iterated, be it Item or any other. One use of this is in the
- * ExpressionSequence(which implements the comma operator) where it creates
- * Iterator instances over Expression instances -- its operands. The
- * parameterization is often used in combination with the MappingIterator
- * and the MappingCallback.
- *
- * @defgroup Patternist_iterators Iterators
- * @author Frans Englich <frans.englich@nokia.com>
- */
-}
diff --git a/src/datavis3d/engine/abstract3dcontroller.cpp b/src/datavis3d/engine/abstract3dcontroller.cpp
new file mode 100644
index 00000000..12f76fd1
--- /dev/null
+++ b/src/datavis3d/engine/abstract3dcontroller.cpp
@@ -0,0 +1,698 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "abstract3dcontroller_p.h"
+#include "camerahelper_p.h"
+#include "qabstractaxis_p.h"
+#include "qvalueaxis.h"
+#include "abstract3drenderer_p.h"
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+Abstract3DController::Abstract3DController(QRect boundRect, QObject *parent) :
+ QObject(parent),
+ m_boundingRect(boundRect.x(), boundRect.y(), boundRect.width(), boundRect.height()),
+ m_horizontalRotation(-45.0f),
+ m_verticalRotation(15.0f),
+ m_theme(),
+ m_font(QFont(QStringLiteral("Arial"))),
+ m_selectionMode(QDataVis::ModeItem),
+ m_shadowQuality(QDataVis::ShadowLow),
+ m_labelTransparency(QDataVis::TransparencyFromTheme),
+ m_isBackgroundEnabled(true),
+ m_isGridEnabled(true),
+ m_cameraHelper(new CameraHelper()),
+ m_zoomLevel(100),
+ m_axisX(0),
+ m_axisY(0),
+ m_axisZ(0),
+ m_renderer(0),
+ m_isDataDirty(false)
+{
+ m_theme.useColorTheme(QDataVis::ThemeSystem);
+}
+
+Abstract3DController::~Abstract3DController()
+{
+ delete m_cameraHelper;
+ delete m_axisX;
+ delete m_axisY;
+ delete m_axisZ;
+}
+
+void Abstract3DController::setRenderer(Abstract3DRenderer *renderer)
+{
+ m_renderer = renderer;
+}
+
+void Abstract3DController::synchDataToRenderer()
+{
+ // If we don't have a renderer, don't do anything
+ if (!m_renderer)
+ return;
+
+ if (m_changeTracker.positionChanged) {
+ m_renderer->updatePosition(m_boundingRect);
+ m_changeTracker.positionChanged = false;
+ }
+
+ if (m_changeTracker.zoomLevelChanged) {
+ m_renderer->updateZoomLevel(m_zoomLevel);
+ m_changeTracker.zoomLevelChanged = false;
+ }
+
+ if (m_changeTracker.themeChanged) {
+ m_renderer->updateTheme(m_theme);
+ m_changeTracker.themeChanged = false;
+ }
+
+ if (m_changeTracker.fontChanged) {
+ m_renderer->updateFont(m_font);
+ m_changeTracker.fontChanged = false;
+ }
+
+ if (m_changeTracker.labelTransparencyChanged) {
+ m_renderer->updateLabelTransparency(m_labelTransparency);
+ m_changeTracker.labelTransparencyChanged = false;
+ }
+
+ if (m_changeTracker.boundingRectChanged || m_changeTracker.sizeChanged) {
+ m_renderer->updateBoundingRect(m_boundingRect);
+ m_changeTracker.boundingRectChanged = false;
+ m_changeTracker.sizeChanged = false;
+ }
+
+ if (m_changeTracker.shadowQualityChanged) {
+ m_renderer->updateShadowQuality(m_shadowQuality);
+ m_changeTracker.shadowQualityChanged = false;
+ }
+
+ if (m_changeTracker.selectionModeChanged) {
+ m_renderer->updateSelectionMode(m_selectionMode);
+ m_changeTracker.selectionModeChanged = false;
+ }
+
+ if (m_changeTracker.objFileChanged) {
+ m_renderer->updateMeshFileName(m_objFile);
+ m_changeTracker.objFileChanged = false;
+ }
+
+ if (m_changeTracker.gridEnabledChanged) {
+ m_renderer->updateGridEnabled(m_isGridEnabled);
+ m_changeTracker.gridEnabledChanged = false;
+ }
+
+ if (m_changeTracker.backgroundEnabledChanged) {
+ m_renderer->updateBackgroundEnabled(m_isBackgroundEnabled);
+ m_changeTracker.backgroundEnabledChanged = false;
+ }
+
+ if (m_changeTracker.axisXTypeChanged) {
+ m_renderer->updateAxisType(QAbstractAxis::AxisOrientationX, m_axisX->type());
+ m_changeTracker.axisXTypeChanged = false;
+ }
+
+ if (m_changeTracker.axisYTypeChanged) {
+ m_renderer->updateAxisType(QAbstractAxis::AxisOrientationY, m_axisY->type());
+ m_changeTracker.axisYTypeChanged = false;
+ }
+
+ if (m_changeTracker.axisZTypeChanged) {
+ m_renderer->updateAxisType(QAbstractAxis::AxisOrientationZ, m_axisZ->type());
+ m_changeTracker.axisZTypeChanged = false;
+ }
+
+ if (m_changeTracker.axisXTitleChanged) {
+ m_renderer->updateAxisTitle(QAbstractAxis::AxisOrientationX, m_axisX->title());
+ m_changeTracker.axisXTitleChanged = false;
+ }
+
+ if (m_changeTracker.axisYTitleChanged) {
+ m_renderer->updateAxisTitle(QAbstractAxis::AxisOrientationY, m_axisY->title());
+ m_changeTracker.axisYTitleChanged = false;
+ }
+
+ if (m_changeTracker.axisZTitleChanged) {
+ m_renderer->updateAxisTitle(QAbstractAxis::AxisOrientationZ, m_axisZ->title());
+ m_changeTracker.axisZTitleChanged = false;
+ }
+
+ if (m_changeTracker.axisXLabelsChanged) {
+ m_renderer->updateAxisLabels(QAbstractAxis::AxisOrientationX, m_axisX->labels());
+ m_changeTracker.axisXLabelsChanged = false;
+ }
+
+ if (m_changeTracker.axisYLabelsChanged) {
+ m_renderer->updateAxisLabels(QAbstractAxis::AxisOrientationY, m_axisY->labels());
+ m_changeTracker.axisYLabelsChanged = false;
+ }
+ if (m_changeTracker.axisZLabelsChanged) {
+ m_renderer->updateAxisLabels(QAbstractAxis::AxisOrientationZ, m_axisZ->labels());
+ m_changeTracker.axisZLabelsChanged = false;
+ }
+
+ if (m_changeTracker.axisXRangeChanged) {
+ m_changeTracker.axisXRangeChanged = false;
+ if (m_axisX->type() & QAbstractAxis::AxisTypeValue) {
+ QValueAxis *valueAxisX = static_cast<QValueAxis *>(m_axisX);
+ m_renderer->updateAxisRange(QAbstractAxis::AxisOrientationX,
+ valueAxisX->min(), valueAxisX->max());
+ }
+ }
+
+ if (m_changeTracker.axisYRangeChanged) {
+ m_changeTracker.axisYRangeChanged = false;
+ if (m_axisY->type() & QAbstractAxis::AxisTypeValue) {
+ QValueAxis *valueAxisY = static_cast<QValueAxis *>(m_axisY);
+ m_renderer->updateAxisRange(QAbstractAxis::AxisOrientationY,
+ valueAxisY->min(), valueAxisY->max());
+ }
+ }
+
+ if (m_changeTracker.axisZRangeChanged) {
+ m_changeTracker.axisZRangeChanged = false;
+ if (m_axisZ->type() & QAbstractAxis::AxisTypeValue) {
+ QValueAxis *valueAxisZ = static_cast<QValueAxis *>(m_axisZ);
+ m_renderer->updateAxisRange(QAbstractAxis::AxisOrientationZ,
+ valueAxisZ->min(), valueAxisZ->max());
+ }
+ }
+
+ if (m_changeTracker.axisXSegmentCountChanged) {
+ m_changeTracker.axisXSegmentCountChanged = false;
+ if (m_axisX->type() & QAbstractAxis::AxisTypeValue) {
+ QValueAxis *valueAxisX = static_cast<QValueAxis *>(m_axisX);
+ m_renderer->updateAxisSegmentCount(QAbstractAxis::AxisOrientationX,
+ valueAxisX->segmentCount());
+ }
+ }
+
+ if (m_changeTracker.axisYSegmentCountChanged) {
+ m_changeTracker.axisYSegmentCountChanged = false;
+ if (m_axisY->type() & QAbstractAxis::AxisTypeValue) {
+ QValueAxis *valueAxisY = static_cast<QValueAxis *>(m_axisY);
+ m_renderer->updateAxisSegmentCount(QAbstractAxis::AxisOrientationY,
+ valueAxisY->segmentCount());
+ }
+ }
+
+ if (m_changeTracker.axisZSegmentCountChanged) {
+ m_changeTracker.axisZSegmentCountChanged = false;
+ if (m_axisZ->type() & QAbstractAxis::AxisTypeValue) {
+ QValueAxis *valueAxisZ = static_cast<QValueAxis *>(m_axisZ);
+ m_renderer->updateAxisSegmentCount(QAbstractAxis::AxisOrientationZ,
+ valueAxisZ->segmentCount());
+ }
+ }
+
+ if (m_changeTracker.axisXSubSegmentCountChanged) {
+ m_changeTracker.axisXSubSegmentCountChanged = false;
+ if (m_axisX->type() & QAbstractAxis::AxisTypeValue) {
+ QValueAxis *valueAxisX = static_cast<QValueAxis *>(m_axisX);
+ m_renderer->updateAxisSubSegmentCount(QAbstractAxis::AxisOrientationX,
+ valueAxisX->subSegmentCount());
+ }
+ }
+
+ if (m_changeTracker.axisYSubSegmentCountChanged) {
+ m_changeTracker.axisYSubSegmentCountChanged = false;
+ if (m_axisY->type() & QAbstractAxis::AxisTypeValue) {
+ QValueAxis *valueAxisY = static_cast<QValueAxis *>(m_axisY);
+ m_renderer->updateAxisSubSegmentCount(QAbstractAxis::AxisOrientationY,
+ valueAxisY->subSegmentCount());
+ }
+ }
+
+ if (m_changeTracker.axisZSubSegmentCountChanged) {
+ m_changeTracker.axisZSubSegmentCountChanged = false;
+ if (m_axisZ->type() & QAbstractAxis::AxisTypeValue) {
+ QValueAxis *valueAxisZ = static_cast<QValueAxis *>(m_axisZ);
+ m_renderer->updateAxisSubSegmentCount(QAbstractAxis::AxisOrientationZ,
+ valueAxisZ->subSegmentCount());
+ }
+ }
+}
+
+void Abstract3DController::render(const GLuint defaultFboHandle)
+{
+ // If not initialized, do nothing.
+ if (!m_renderer)
+ return;
+
+ m_renderer->render(m_cameraHelper, defaultFboHandle);
+}
+
+void Abstract3DController::setSize(const int width, const int height)
+{
+ m_boundingRect.setWidth(width);
+ m_boundingRect.setHeight(height);
+
+ m_changeTracker.boundingRectChanged = true;
+ emit boundingRectChanged(m_boundingRect);
+}
+
+const QSize Abstract3DController::size()
+{
+ return m_boundingRect.size();
+}
+
+const QRect Abstract3DController::boundingRect()
+{
+ return m_boundingRect;
+}
+
+void Abstract3DController::setBoundingRect(const QRect boundingRect)
+{
+ m_boundingRect = boundingRect;
+
+ m_changeTracker.boundingRectChanged = true;
+ emit boundingRectChanged(m_boundingRect);
+}
+
+void Abstract3DController::setWidth(const int width)
+{
+ m_boundingRect.setWidth(width);
+
+ m_changeTracker.sizeChanged = true;
+ emit sizeChanged(m_boundingRect);
+}
+
+int Abstract3DController::width()
+{
+ return m_boundingRect.width();
+}
+
+void Abstract3DController::setHeight(const int height)
+{
+ m_boundingRect.setHeight(height);
+
+ m_changeTracker.sizeChanged = true;
+ emit sizeChanged(m_boundingRect);
+}
+
+int Abstract3DController::height()
+{
+ return m_boundingRect.height();
+}
+
+void Abstract3DController::setX(const int x)
+{
+ m_boundingRect.setX(x);
+
+ m_changeTracker.positionChanged = true;
+ emit positionChanged(m_boundingRect);
+}
+
+int Abstract3DController::x()
+{
+ return m_boundingRect.x();
+}
+
+void Abstract3DController::setY(const int y)
+{
+ m_boundingRect.setY(y);
+
+ m_changeTracker.positionChanged = true;
+ emit positionChanged(m_boundingRect);
+}
+
+int Abstract3DController::y()
+{
+ return m_boundingRect.y();
+}
+
+void Abstract3DController::setAxisX(QAbstractAxis *axis)
+{
+ setAxisHelper(QAbstractAxis::AxisOrientationX, axis, &m_axisX);
+}
+
+QAbstractAxis *Abstract3DController::axisX()
+{
+ return m_axisX;
+}
+
+void Abstract3DController::setAxisY(QAbstractAxis *axis)
+{
+ setAxisHelper(QAbstractAxis::AxisOrientationY, axis, &m_axisY);
+}
+
+QAbstractAxis *Abstract3DController::axisY()
+{
+ return m_axisY;
+}
+
+void Abstract3DController::setAxisZ(QAbstractAxis *axis)
+{
+ setAxisHelper(QAbstractAxis::AxisOrientationZ, axis, &m_axisZ);
+}
+
+QAbstractAxis *Abstract3DController::axisZ()
+{
+ return m_axisZ;
+}
+
+int Abstract3DController::zoomLevel()
+{
+ return m_zoomLevel;
+}
+
+void Abstract3DController::setZoomLevel(int zoomLevel)
+{
+ m_zoomLevel = zoomLevel;
+
+ m_changeTracker.zoomLevelChanged = true;
+ emit zoomLevelChanged(zoomLevel);
+}
+
+void Abstract3DController::setCameraPreset(QDataVis::CameraPreset preset)
+{
+ m_cameraHelper->setCameraPreset(preset);
+}
+
+void Abstract3DController::setCameraPosition(GLfloat horizontal, GLfloat vertical, GLint distance)
+{
+ m_horizontalRotation = qBound(-180.0f, horizontal, 180.0f);
+ m_verticalRotation = qBound(0.0f, vertical, 90.0f);
+ m_zoomLevel = qBound(10, distance, 500);
+ m_cameraHelper->setCameraRotation(QPointF(m_horizontalRotation,
+ m_verticalRotation));
+ //qDebug() << "camera rotation set to" << m_horizontalRotation << m_verticalRotation;
+}
+
+void Abstract3DController::setObjectColor(QColor baseColor, QColor heightColor, QColor depthColor,
+ bool uniform)
+{
+ m_theme.m_baseColor = baseColor;
+ m_theme.m_heightColor = heightColor;
+ m_theme.m_depthColor = depthColor;
+ m_theme.m_uniformColor = uniform;
+
+ m_changeTracker.themeChanged = true;
+ emit themeChanged(m_theme);
+}
+
+void Abstract3DController::setColorTheme(QDataVis::ColorTheme colorTheme)
+{
+ m_theme.useColorTheme(colorTheme);
+
+ m_changeTracker.themeChanged = true;
+ emit themeChanged(m_theme);
+}
+
+Theme Abstract3DController::theme()
+{
+ return m_theme;
+}
+
+void Abstract3DController::setFontSize(float fontsize)
+{
+ m_font.setPointSizeF(fontsize);
+
+ m_changeTracker.fontChanged = true;
+ emit fontChanged(m_font);
+}
+
+float Abstract3DController::fontSize()
+{
+ return m_font.pointSizeF();
+}
+
+void Abstract3DController::setFont(const QFont &font)
+{
+ m_font = font;
+
+ m_changeTracker.fontChanged = true;
+ emit fontChanged(m_font);
+}
+
+QFont Abstract3DController::font()
+{
+ return m_font;
+}
+
+void Abstract3DController::setSelectionMode(QDataVis::SelectionMode mode)
+{
+ m_selectionMode = mode;
+ m_changeTracker.selectionModeChanged = true;
+ emit selectionModeChanged(m_selectionMode);
+}
+
+QDataVis::SelectionMode Abstract3DController::selectionMode()
+{
+ return m_selectionMode;
+}
+
+void Abstract3DController::setShadowQuality(QDataVis::ShadowQuality quality)
+{
+ m_shadowQuality = quality;
+
+ m_changeTracker.shadowQualityChanged = true;
+ emit shadowQualityChanged(m_shadowQuality);
+}
+
+QDataVis::ShadowQuality Abstract3DController::shadowQuality()
+{
+ return m_shadowQuality;
+}
+
+void Abstract3DController::setLabelTransparency(QDataVis::LabelTransparency transparency)
+{
+ m_labelTransparency = transparency;
+
+ m_changeTracker.labelTransparencyChanged = true;
+ emit labelTransparencyChanged(m_labelTransparency);
+}
+
+QDataVis::LabelTransparency Abstract3DController::labelTransparency()
+{
+ return m_labelTransparency;
+}
+
+void Abstract3DController::setBackgroundEnabled(bool enable)
+{
+ m_isBackgroundEnabled = enable;
+ m_changeTracker.backgroundEnabledChanged = true;
+ emit backgroundEnabledChanged(m_isBackgroundEnabled);
+}
+
+bool Abstract3DController::backgroundEnabled()
+{
+ return m_isBackgroundEnabled;
+}
+
+void Abstract3DController::setGridEnabled(bool enable)
+{
+ m_isGridEnabled = enable;
+ m_changeTracker.gridEnabledChanged = true;
+ emit gridEnabledChanged(m_isGridEnabled);
+}
+
+bool Abstract3DController::gridEnabled()
+{
+ return m_isGridEnabled;
+}
+
+void Abstract3DController::setMeshFileName(const QString &fileName)
+{
+ m_objFile = fileName;
+ m_changeTracker.objFileChanged = true;
+ emit meshFileNameChanged(m_objFile);
+}
+
+QString Abstract3DController::meshFileName()
+{
+ return m_objFile;
+}
+
+void Abstract3DController::handleAxisTitleChanged(const QString &title)
+{
+ handleAxisTitleChangedBySender(sender(), title);
+}
+
+void Abstract3DController::handleAxisTitleChangedBySender(QObject *sender, const QString &title)
+{
+ if (sender == m_axisX) {
+ m_changeTracker.axisXTitleChanged = true;
+ emit axisTitleChanged(QAbstractAxis::AxisOrientationX, title);
+ } else if (sender == m_axisY) {
+ m_changeTracker.axisYTitleChanged = true;
+ emit axisTitleChanged(QAbstractAxis::AxisOrientationY, title);
+ } else if (sender == m_axisZ) {
+ m_changeTracker.axisZTitleChanged = true;
+ emit axisTitleChanged(QAbstractAxis::AxisOrientationZ, title);
+ } else {
+ qWarning() << __FUNCTION__ << "invoked for invalid axis";
+ }
+}
+
+void Abstract3DController::handleAxisLabelsChanged()
+{
+ handleAxisLabelsChangedBySender(sender());
+}
+
+void Abstract3DController::handleAxisLabelsChangedBySender(QObject *sender)
+{
+ if (sender == m_axisX) {
+ m_changeTracker.axisXLabelsChanged = true;
+ emit axisLabelsChanged(QAbstractAxis::AxisOrientationX, m_axisX->labels());
+ } else if (sender == m_axisY) {
+ m_changeTracker.axisYLabelsChanged = true;
+ emit axisLabelsChanged(QAbstractAxis::AxisOrientationY, m_axisY->labels());
+ } else if (sender == m_axisZ) {
+ m_changeTracker.axisZLabelsChanged = true;
+ emit axisLabelsChanged(QAbstractAxis::AxisOrientationZ, m_axisZ->labels());
+ } else {
+ qWarning() << __FUNCTION__ << "invoked for invalid axis";
+ }
+}
+
+void Abstract3DController::handleAxisRangeChanged(qreal min, qreal max)
+{
+ handleAxisRangeChangedBySender(sender(), min, max);
+}
+
+void Abstract3DController::handleAxisRangeChangedBySender(QObject *sender, qreal min, qreal max)
+{
+ if (sender == m_axisX) {
+ m_isDataDirty = true;
+ m_changeTracker.axisXRangeChanged = true;
+ emit axisRangeChanged(QAbstractAxis::AxisOrientationX, min, max);
+ } else if (sender == m_axisY) {
+ m_isDataDirty = true;
+ m_changeTracker.axisYRangeChanged = true;
+ emit axisRangeChanged(QAbstractAxis::AxisOrientationY, min, max);
+ } else if (sender == m_axisZ) {
+ m_isDataDirty = true;
+
+ m_changeTracker.axisZRangeChanged = true;
+ emit axisRangeChanged(QAbstractAxis::AxisOrientationZ, min, max);
+ } else {
+ qWarning() << __FUNCTION__ << "invoked for invalid axis";
+ }
+}
+
+void Abstract3DController::handleAxisSegmentCountChanged(int count)
+{
+ handleAxisSegmentCountChangedBySender(sender(), count);
+}
+
+void Abstract3DController::handleAxisSegmentCountChangedBySender(QObject *sender, int count)
+{
+ if (sender == m_axisX) {
+ m_changeTracker.axisXSegmentCountChanged = true;
+ emit axisSegmentCountChanged(QAbstractAxis::AxisOrientationX, count);
+ } else if (sender == m_axisY) {
+ m_changeTracker.axisYSegmentCountChanged = true;
+ emit axisSegmentCountChanged(QAbstractAxis::AxisOrientationY, count);
+ } else if (sender == m_axisZ) {
+ m_changeTracker.axisZSegmentCountChanged = true;
+ emit axisSegmentCountChanged(QAbstractAxis::AxisOrientationZ, count);
+ } else {
+ qWarning() << __FUNCTION__ << "invoked for invalid axis";
+ }
+}
+
+void Abstract3DController::handleAxisSubSegmentCountChanged(int count)
+{
+ handleAxisSubSegmentCountChangedBySender(sender(), count);
+}
+
+void Abstract3DController::handleAxisSubSegmentCountChangedBySender(QObject *sender, int count)
+{
+ if (sender == m_axisX) {
+ m_changeTracker.axisXSubSegmentCountChanged = true;
+ emit axisSubSegmentCountChanged(QAbstractAxis::AxisOrientationX, count);
+ } else if (sender == m_axisY) {
+ m_changeTracker.axisYSubSegmentCountChanged = true;
+ emit axisSubSegmentCountChanged(QAbstractAxis::AxisOrientationY, count);
+ } else if (sender == m_axisZ) {
+ m_changeTracker.axisZSubSegmentCountChanged = true;
+ emit axisSubSegmentCountChanged(QAbstractAxis::AxisOrientationZ, count);
+ } else {
+ qWarning() << __FUNCTION__ << "invoked for invalid axis";
+ }
+}
+
+void Abstract3DController::handleAxisAutoAdjustRangeChanged(bool autoAdjust)
+{
+ QObject *sender = QObject::sender();
+ if (sender != m_axisX && sender != m_axisY && sender != m_axisZ)
+ return;
+
+ QAbstractAxis *axis = static_cast<QAbstractAxis*>(sender);
+ handleAxisAutoAdjustRangeChangedInOrientation(axis->orientation(), autoAdjust);
+}
+
+void Abstract3DController::setAxisHelper(QAbstractAxis::AxisOrientation orientation,
+ QAbstractAxis *axis, QAbstractAxis **axisPtr)
+{
+ Q_ASSERT(axis);
+
+ delete *axisPtr;
+ *axisPtr = axis;
+
+ axis->setParent(0); // Assume ownership
+ axis->d_ptr->setOrientation(orientation);
+
+
+ QObject::connect(axis, &QAbstractAxis::titleChanged,
+ this, &Abstract3DController::handleAxisTitleChanged);
+ QObject::connect(axis, &QAbstractAxis::labelsChanged,
+ this, &Abstract3DController::handleAxisLabelsChanged);
+
+
+ if (orientation == QAbstractAxis::AxisOrientationX)
+ m_changeTracker.axisXTypeChanged = true;
+ else if (orientation == QAbstractAxis::AxisOrientationY)
+ m_changeTracker.axisYTypeChanged = true;
+ else if (orientation == QAbstractAxis::AxisOrientationZ)
+ m_changeTracker.axisZTypeChanged = true;
+ emit axisTypeChanged(orientation, axis->type());
+
+ handleAxisTitleChangedBySender(axis, axis->title());
+ emit axisTitleChanged(orientation, axis->title());
+
+ handleAxisLabelsChangedBySender(axis);
+ emit axisLabelsChanged(orientation, axis->labels());
+
+ if (axis->type() & QAbstractAxis::AxisTypeValue) {
+ QValueAxis *valueAxis = static_cast<QValueAxis *>(axis);
+ QObject::connect(valueAxis, &QValueAxis::rangeChanged,
+ this, &Abstract3DController::handleAxisRangeChanged);
+ QObject::connect(valueAxis, &QValueAxis::segmentCountChanged,
+ this, &Abstract3DController::handleAxisSegmentCountChanged);
+ QObject::connect(valueAxis, &QValueAxis::subSegmentCountChanged,
+ this, &Abstract3DController::handleAxisSubSegmentCountChanged);
+ QObject::connect(valueAxis, &QValueAxis::autoAdjustRangeChanged,
+ this, &Abstract3DController::handleAxisAutoAdjustRangeChanged);
+
+ handleAxisRangeChangedBySender(valueAxis, valueAxis->min(), valueAxis->max());
+ emit axisRangeChanged(orientation, valueAxis->min(), valueAxis->max());
+
+ handleAxisSegmentCountChangedBySender(valueAxis, valueAxis->segmentCount());
+ emit axisSegmentCountChanged(orientation, valueAxis->segmentCount());
+
+ handleAxisSubSegmentCountChangedBySender(valueAxis, valueAxis->subSegmentCount());
+ emit axisSubSegmentCountChanged(orientation, valueAxis->subSegmentCount());
+
+ handleAxisAutoAdjustRangeChangedInOrientation(valueAxis->orientation(),
+ valueAxis->isAutoAdjustRange());
+ }
+}
+
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/engine/abstract3dcontroller_p.h b/src/datavis3d/engine/abstract3dcontroller_p.h
new file mode 100644
index 00000000..8f21c97f
--- /dev/null
+++ b/src/datavis3d/engine/abstract3dcontroller_p.h
@@ -0,0 +1,293 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef CONTROLLER3DBASE_H
+#define CONTROLLER3DBASE_H
+
+#include <QObject>
+
+#include "datavis3dglobal_p.h"
+#include "theme_p.h"
+#include "qabstractaxis.h"
+#include "drawer_p.h"
+
+class QFont;
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class CameraHelper;
+class Abstract3DRenderer;
+
+struct Abstract3DChangeBitField {
+ bool positionChanged : 1;
+ bool zoomLevelChanged : 1;
+ bool themeChanged : 1;
+ bool fontChanged : 1;
+ bool labelTransparencyChanged : 1;
+ bool boundingRectChanged : 1;
+ bool sizeChanged : 1;
+ bool shadowQualityChanged : 1;
+ bool selectionModeChanged : 1;
+ bool objFileChanged : 1;
+ bool gridEnabledChanged : 1;
+ bool backgroundEnabledChanged : 1;
+ bool axisXTypeChanged : 1;
+ bool axisYTypeChanged : 1;
+ bool axisZTypeChanged : 1;
+ bool axisXTitleChanged : 1;
+ bool axisYTitleChanged : 1;
+ bool axisZTitleChanged : 1;
+ bool axisXLabelsChanged : 1;
+ bool axisYLabelsChanged : 1;
+ bool axisZLabelsChanged : 1;
+ bool axisXRangeChanged : 1;
+ bool axisYRangeChanged : 1;
+ bool axisZRangeChanged : 1;
+ bool axisXSegmentCountChanged : 1;
+ bool axisYSegmentCountChanged : 1;
+ bool axisZSegmentCountChanged : 1;
+ bool axisXSubSegmentCountChanged : 1;
+ bool axisYSubSegmentCountChanged : 1;
+ bool axisZSubSegmentCountChanged : 1;
+
+ Abstract3DChangeBitField() :
+ positionChanged(true),
+ zoomLevelChanged(true),
+ themeChanged(true),
+ fontChanged(true),
+ labelTransparencyChanged(true),
+ boundingRectChanged(true),
+ sizeChanged(true),
+ shadowQualityChanged(true),
+ selectionModeChanged(true),
+ objFileChanged(true),
+ gridEnabledChanged(true),
+ backgroundEnabledChanged(true),
+ axisXTypeChanged(true),
+ axisYTypeChanged(true),
+ axisZTypeChanged(true),
+ axisXTitleChanged(true),
+ axisYTitleChanged(true),
+ axisZTitleChanged(true),
+ axisXLabelsChanged(true),
+ axisYLabelsChanged(true),
+ axisZLabelsChanged(true),
+ axisXRangeChanged(true),
+ axisYRangeChanged(true),
+ axisZRangeChanged(true),
+ axisXSegmentCountChanged(true),
+ axisYSegmentCountChanged(true),
+ axisZSegmentCountChanged(true),
+ axisXSubSegmentCountChanged(true),
+ axisYSubSegmentCountChanged(true),
+ axisZSubSegmentCountChanged(true)
+ {
+ }
+};
+
+class QT_DATAVIS3D_EXPORT Abstract3DController : public QObject
+{
+ Q_OBJECT
+
+public:
+ enum SelectionType {
+ SelectionNone = 0,
+ SelectionItem,
+ SelectionRow,
+ SelectionColumn
+ };
+
+ enum MouseState {
+ MouseNone = 0,
+ MouseOnScene,
+ MouseOnOverview,
+ MouseOnZoom,
+ MouseRotating,
+ MouseOnPinch
+ };
+
+private:
+ Abstract3DChangeBitField m_changeTracker;
+ QRect m_boundingRect;
+ GLfloat m_horizontalRotation;
+ GLfloat m_verticalRotation;
+ Theme m_theme;
+ QFont m_font;
+ QDataVis::SelectionMode m_selectionMode;
+ QDataVis::ShadowQuality m_shadowQuality;
+ QDataVis::LabelTransparency m_labelTransparency;
+ bool m_isBackgroundEnabled;
+ bool m_isGridEnabled;
+ QString m_objFile;
+
+protected:
+ CameraHelper *m_cameraHelper;
+ int m_zoomLevel;
+ QAbstractAxis *m_axisX;
+ QAbstractAxis *m_axisY;
+ QAbstractAxis *m_axisZ;
+ Abstract3DRenderer *m_renderer;
+ bool m_isDataDirty;
+
+ explicit Abstract3DController(QRect boundRect, QObject *parent = 0);
+ ~Abstract3DController();
+
+public:
+
+ inline bool isInitialized() { return (m_renderer != 0); }
+
+ /**
+ * @brief synchDataToRenderer Called on the render thread while main GUI thread is blocked before rendering.
+ */
+ virtual void synchDataToRenderer();
+
+
+ virtual void render(const GLuint defaultFboHandle = 0);
+
+ /**
+ * @brief setRenderer Sets the renderer to be used. isInitialized returns true from this point onwards.
+ * @param renderer Renderer to be used.
+ */
+ void setRenderer(Abstract3DRenderer *renderer);
+
+ // Size
+ virtual void setSize(const int width, const int height);
+ virtual const QSize size();
+ virtual const QRect boundingRect();
+ virtual void setBoundingRect(const QRect boundingRect);
+ virtual void setWidth(const int width);
+ virtual int width();
+ virtual void setHeight(const int height);
+ virtual int height();
+ virtual void setX(const int x);
+ virtual int x();
+ virtual void setY(const int y);
+ virtual int y();
+ virtual void setAxisX(QAbstractAxis *axis);
+ virtual QAbstractAxis *axisX();
+ virtual void setAxisY(QAbstractAxis *axis);
+ virtual QAbstractAxis *axisY();
+ virtual void setAxisZ(QAbstractAxis *axis);
+ virtual QAbstractAxis *axisZ();
+
+ virtual int zoomLevel();
+ virtual void setZoomLevel(int zoomLevel);
+
+ // Select preset camera placement
+ virtual void setCameraPreset(QDataVis::CameraPreset preset);
+
+ // Set camera rotation if you don't want to use the presets (in horizontal (-180...180) and
+ // vertical (0...90) (or (-90...90) if there are negative values) angles and distance in
+ // percentage (10...500))
+ virtual void setCameraPosition(GLfloat horizontal, GLfloat vertical, GLint distance = 100);
+
+ // Set color if you don't want to use themes. Set uniform to false if you want the (height)
+ // color to change from bottom to top
+ virtual void setObjectColor(QColor baseColor, QColor heightColor, QColor depthColor,
+ bool uniform = true);
+
+ // Set theme (bar colors, shaders, window color, background colors, light intensity and text
+ // colors are affected)
+ virtual void setColorTheme(QDataVis::ColorTheme colorTheme);
+ virtual Theme theme();
+
+ // Font size adjustment
+ virtual void setFontSize(float fontsize);
+ virtual float fontSize();
+
+ // Set font
+ virtual void setFont(const QFont &font);
+ virtual QFont font();
+
+ // Selection mode
+ virtual void setSelectionMode(QDataVis::SelectionMode mode);
+ virtual QDataVis::SelectionMode selectionMode();
+
+ // Adjust shadow quality
+ virtual void setShadowQuality(QDataVis::ShadowQuality quality);
+ virtual QDataVis::ShadowQuality shadowQuality();
+
+ // Label transparency adjustment
+ virtual void setLabelTransparency(QDataVis::LabelTransparency transparency);
+ virtual QDataVis::LabelTransparency labelTransparency();
+
+ // Enable or disable background mesh
+ virtual void setBackgroundEnabled(bool enable);
+ virtual bool backgroundEnabled();
+
+ // Enable or disable background grid
+ virtual void setGridEnabled(bool enable);
+ virtual bool gridEnabled();
+
+ // override bar type with own mesh
+ virtual void setMeshFileName(const QString &fileName);
+ virtual QString meshFileName();
+
+ virtual void handleAxisTitleChangedBySender(QObject *sender, const QString &title);
+ virtual void handleAxisLabelsChangedBySender(QObject *sender);
+ virtual void handleAxisRangeChangedBySender(QObject *sender, qreal min, qreal max);
+ virtual void handleAxisSegmentCountChangedBySender(QObject *sender, int count);
+ virtual void handleAxisSubSegmentCountChangedBySender(QObject *sender, int count);
+ virtual void handleAxisAutoAdjustRangeChangedInOrientation(QAbstractAxis::AxisOrientation orientation, bool autoAdjust) = 0;
+
+public slots:
+ void handleAxisTitleChanged(const QString &title);
+ void handleAxisLabelsChanged();
+ void handleAxisRangeChanged(qreal min, qreal max);
+ void handleAxisSegmentCountChanged(int count);
+ void handleAxisSubSegmentCountChanged(int count);
+ void handleAxisAutoAdjustRangeChanged(bool autoAdjust);
+
+signals:
+ void boundingRectChanged(QRect boundingRect);
+ void sizeChanged(QRect boundingRect);
+ void positionChanged(QRect boundingRect);
+ void zoomLevelChanged(int zoomLevel);
+ void themeChanged(Theme theme);
+ void fontChanged(QFont font); // TODO should be handled via axis?? What about font for selection label?
+ void shadowQualityChanged(QDataVis::ShadowQuality quality);
+ void labelTransparencyChanged(QDataVis::LabelTransparency transparency);
+ void axisTypeChanged(QAbstractAxis::AxisOrientation orientation, QAbstractAxis::AxisType type);
+ void axisTitleChanged(QAbstractAxis::AxisOrientation orientation, QString title);
+ void axisLabelsChanged(QAbstractAxis::AxisOrientation orientation, QStringList labels);
+ void axisRangeChanged(QAbstractAxis::AxisOrientation orientation, qreal min, qreal max);
+ void axisSegmentCountChanged(QAbstractAxis::AxisOrientation orientation, int count);
+ void axisSubSegmentCountChanged(QAbstractAxis::AxisOrientation orientation, int count);
+ void selectionModeChanged(QDataVis::SelectionMode mode);
+ void backgroundEnabledChanged(bool enable);
+ void gridEnabledChanged(bool enable); // TODO: Should be handled via axes?
+ void meshFileNameChanged(QString fileName);
+
+private:
+ void setAxisHelper(QAbstractAxis::AxisOrientation orientation, QAbstractAxis *axis,
+ QAbstractAxis **axisPtr);
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif // CONTROLLER3DBASE_H
diff --git a/src/datavis3d/engine/abstract3drenderer.cpp b/src/datavis3d/engine/abstract3drenderer.cpp
new file mode 100644
index 00000000..b25e5a15
--- /dev/null
+++ b/src/datavis3d/engine/abstract3drenderer.cpp
@@ -0,0 +1,219 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "abstract3drenderer_p.h"
+#include "qvalueaxis.h"
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+Abstract3DRenderer::Abstract3DRenderer(Abstract3DController *controller)
+ : QObject(controller),
+ m_controller(controller),
+ m_isInitialized(false),
+ m_hasNegativeValues(false),
+ m_drawer(new Drawer(m_cachedTheme, m_cachedFont, m_cachedLabelTransparency)),
+ m_autoScaleAdjustment(1.0f),
+ m_cachedZoomLevel(100)
+
+{
+ QObject::connect(m_drawer, &Drawer::drawerChanged, this, &Abstract3DRenderer::updateTextures);
+}
+
+void Abstract3DRenderer::initializeOpenGL()
+{
+ axisCacheForOrientation(QAbstractAxis::AxisOrientationX).setDrawer(m_drawer);
+ axisCacheForOrientation(QAbstractAxis::AxisOrientationY).setDrawer(m_drawer);
+ axisCacheForOrientation(QAbstractAxis::AxisOrientationZ).setDrawer(m_drawer);
+}
+
+void Abstract3DRenderer::updateDataModel(QAbstractDataProxy *dataProxy)
+{
+ m_cachedItemLabelFormat = dataProxy->itemLabelFormat();
+}
+
+QString Abstract3DRenderer::itemLabelFormat() const
+{
+ return m_cachedItemLabelFormat;
+}
+
+void Abstract3DRenderer::updateBoundingRect(const QRect boundingRect)
+{
+ m_cachedBoundingRect = boundingRect;
+ handleResize();
+}
+
+void Abstract3DRenderer::updatePosition(const QRect boundingRect)
+{
+ m_cachedBoundingRect = boundingRect;
+}
+
+void Abstract3DRenderer::updateTheme(Theme theme)
+{
+ m_cachedTheme.setFromTheme(theme);
+
+ m_drawer->setTheme(m_cachedTheme);
+ // Re-initialize shaders
+ handleShadowQualityChange();
+}
+
+void Abstract3DRenderer::handleShadowQualityChange()
+{
+#if !defined(QT_OPENGL_ES_2)
+ if (m_cachedShadowQuality > QDataVis::ShadowNone) {
+ if (!m_cachedTheme.m_uniformColor) {
+ initShaders(QStringLiteral(":/shaders/vertexShadow"),
+ QStringLiteral(":/shaders/fragmentShadowNoTexColorOnY"));
+ } else {
+ initShaders(QStringLiteral(":/shaders/vertexShadow"),
+ QStringLiteral(":/shaders/fragmentShadowNoTex"));
+ }
+ initBackgroundShaders(QStringLiteral(":/shaders/vertexShadow"),
+ QStringLiteral(":/shaders/fragmentShadowNoTex"));
+ } else {
+ if (!m_cachedTheme.m_uniformColor) {
+ initShaders(QStringLiteral(":/shaders/vertex"),
+ QStringLiteral(":/shaders/fragmentColorOnY"));
+ } else {
+ initShaders(QStringLiteral(":/shaders/vertex"),
+ QStringLiteral(":/shaders/fragment"));
+ }
+ initBackgroundShaders(QStringLiteral(":/shaders/vertex"),
+ QStringLiteral(":/shaders/fragment"));
+ }
+#else
+ if (!m_cachedTheme.m_uniformColor) {
+ initShaders(QStringLiteral(":/shaders/vertexES2"),
+ QStringLiteral(":/shaders/fragmentColorOnYES2"));
+ } else {
+ initShaders(QStringLiteral(":/shaders/vertexES2"),
+ QStringLiteral(":/shaders/fragmentES2"));
+ }
+ initBackgroundShaders(QStringLiteral(":/shaders/vertexES2"),
+ QStringLiteral(":/shaders/fragmentES2"));
+#endif
+}
+
+void Abstract3DRenderer::updateFont(const QFont &font)
+{
+ m_cachedFont = font;
+ m_drawer->setFont(font);
+}
+
+void Abstract3DRenderer::updateLabelTransparency(QDataVis::LabelTransparency transparency)
+{
+ m_cachedLabelTransparency = transparency;
+ m_drawer->setTransparency(transparency);
+}
+
+void Abstract3DRenderer::updateMeshFileName(const QString &objFileName)
+{
+ m_cachedObjFile = objFileName;
+}
+
+void Abstract3DRenderer::updateSelectionMode(QDataVis::SelectionMode mode)
+{
+ m_cachedSelectionMode = mode;
+}
+
+void Abstract3DRenderer::updateGridEnabled(bool enable)
+{
+ m_cachedIsGridEnabled = enable;
+}
+
+void Abstract3DRenderer::updateBackgroundEnabled(bool enable)
+{
+ m_cachedIsBackgroundEnabled = enable;
+}
+
+void Abstract3DRenderer::handleResize()
+{
+ if (m_cachedBoundingRect.width() == 0 || m_cachedBoundingRect.height() == 0)
+ return;
+ qDebug() << __FUNCTION__ << m_cachedBoundingRect.width() << "x" << m_cachedBoundingRect.height();
+ // Calculate zoom level based on aspect ratio
+ GLfloat div;
+ GLfloat zoomAdjustment;
+ div = qMin(m_cachedBoundingRect.width(), m_cachedBoundingRect.height());
+ zoomAdjustment = defaultRatio * ((m_cachedBoundingRect.width() / div)
+ / (m_cachedBoundingRect.height() / div));
+ //qDebug() << "zoom adjustment" << zoomAdjustment;
+ m_autoScaleAdjustment = qMin(zoomAdjustment, 1.0f); // clamp to 1.0f
+
+ // Re-init selection buffer
+ initSelectionBuffer();
+
+#if !defined(QT_OPENGL_ES_2)
+ // Re-init depth buffer
+ updateDepthBuffer();
+#endif
+}
+
+void Abstract3DRenderer::updateZoomLevel(int newZoomLevel)
+{
+ m_cachedZoomLevel = newZoomLevel;
+}
+
+void Abstract3DRenderer::updateAxisType(QAbstractAxis::AxisOrientation orientation, QAbstractAxis::AxisType type)
+{
+ axisCacheForOrientation(orientation).setType(type);
+}
+
+void Abstract3DRenderer::updateAxisTitle(QAbstractAxis::AxisOrientation orientation, const QString &title)
+{
+ axisCacheForOrientation(orientation).setTitle(title);
+}
+
+void Abstract3DRenderer::updateAxisLabels(QAbstractAxis::AxisOrientation orientation, const QStringList &labels)
+{
+ axisCacheForOrientation(orientation).setLabels(labels);
+}
+
+void Abstract3DRenderer::updateAxisRange(QAbstractAxis::AxisOrientation orientation, qreal min, qreal max)
+{
+ AxisRenderCache &cache = axisCacheForOrientation(orientation);
+ cache.setMin(min);
+ cache.setMax(max);
+}
+
+void Abstract3DRenderer::updateAxisSegmentCount(QAbstractAxis::AxisOrientation orientation, int count)
+{
+ axisCacheForOrientation(orientation).setSegmentCount(count);
+}
+
+void Abstract3DRenderer::updateAxisSubSegmentCount(QAbstractAxis::AxisOrientation orientation, int count)
+{
+ axisCacheForOrientation(orientation).setSubSegmentCount(count);
+}
+
+AxisRenderCache &Abstract3DRenderer::axisCacheForOrientation(QAbstractAxis::AxisOrientation orientation)
+{
+ switch (orientation) {
+ case QAbstractAxis::AxisOrientationX:
+ return m_axisCacheX;
+ case QAbstractAxis::AxisOrientationY:
+ return m_axisCacheY;
+ case QAbstractAxis::AxisOrientationZ:
+ return m_axisCacheZ;
+ default:
+ qFatal(__FUNCTION__);
+ return m_axisCacheX;
+ }
+}
+
+
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/engine/abstract3drenderer_p.h b/src/datavis3d/engine/abstract3drenderer_p.h
new file mode 100644
index 00000000..3c5d1388
--- /dev/null
+++ b/src/datavis3d/engine/abstract3drenderer_p.h
@@ -0,0 +1,117 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef ABSTRACT3DRENDERER_P_H
+#define ABSTRACT3DRENDERER_P_H
+
+#include <QtGui/QOpenGLFunctions>
+#include <QtGui/QFont>
+
+#include "datavis3dglobal_p.h"
+#include "abstract3dcontroller_p.h"
+#include "axisrendercache_p.h"
+#include "qabstractdataproxy.h"
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class Abstract3DRenderer : public QObject, protected QOpenGLFunctions
+{
+protected:
+ Abstract3DController *m_controller;
+ bool m_isInitialized;
+ bool m_hasNegativeValues;
+ QRect m_cachedBoundingRect;
+ QDataVis::ShadowQuality m_cachedShadowQuality;
+ Theme m_cachedTheme;
+ QFont m_cachedFont;
+ QDataVis::LabelTransparency m_cachedLabelTransparency;
+ Drawer *m_drawer;
+ GLfloat m_autoScaleAdjustment;
+ QString m_cachedItemLabelFormat;
+ QString m_cachedObjFile;
+ QDataVis::SelectionMode m_cachedSelectionMode;
+ bool m_cachedIsGridEnabled;
+ bool m_cachedIsBackgroundEnabled;
+ int m_cachedZoomLevel;
+
+ AxisRenderCache m_axisCacheX;
+ AxisRenderCache m_axisCacheY;
+ AxisRenderCache m_axisCacheZ;
+
+ Abstract3DRenderer(Abstract3DController *controller);
+ virtual void initializeOpenGL();
+
+public:
+ inline bool isInitialized() { return m_isInitialized; }
+
+ virtual void updateBoundingRect(const QRect boundingRect);
+ virtual void updatePosition(const QRect boundingRect);
+ virtual void handleResize();
+
+ virtual void updateZoomLevel(int newZoomLevel);
+ virtual void updateTheme(Theme theme);
+ virtual void updateFont(const QFont &font);
+ virtual void updateLabelTransparency(QDataVis::LabelTransparency transparency);
+ virtual void updateSelectionMode(QDataVis::SelectionMode newMode);
+ virtual void updateGridEnabled(bool enable);
+ virtual void updateBackgroundEnabled(bool enable);
+ virtual void updateMeshFileName(const QString &objFileName);
+
+ virtual void handleShadowQualityChange();
+
+ void updateDataModel(QAbstractDataProxy *dataProxy);
+ virtual QString itemLabelFormat() const;
+ virtual void requestSelectionAtPoint(const QPoint &point) = 0;
+ virtual void updateTextures() = 0;
+ virtual void initSelectionBuffer() = 0;
+#if !defined(QT_OPENGL_ES_2)
+ virtual void updateDepthBuffer() = 0;
+#endif
+ virtual void updateShadowQuality(QDataVis::ShadowQuality quality) = 0;
+ virtual void initShaders(const QString &vertexShader, const QString &fragmentShader) = 0;
+ virtual void initBackgroundShaders(const QString &vertexShader, const QString &fragmentShader) = 0;
+ virtual void updateAxisType(QAbstractAxis::AxisOrientation orientation, QAbstractAxis::AxisType type);
+ virtual void updateAxisTitle(QAbstractAxis::AxisOrientation orientation, const QString &title);
+ virtual void updateAxisLabels(QAbstractAxis::AxisOrientation orientation, const QStringList &labels);
+ virtual void updateAxisRange(QAbstractAxis::AxisOrientation orientation, qreal min, qreal max);
+ virtual void updateAxisSegmentCount(QAbstractAxis::AxisOrientation orientation, int count);
+ virtual void updateAxisSubSegmentCount(QAbstractAxis::AxisOrientation orientation, int count);
+
+ AxisRenderCache &axisCacheForOrientation(QAbstractAxis::AxisOrientation orientation);
+
+public:
+ /**
+ * @brief render Implements OpenGL rendering that occurs in the rendering thread.
+ * @param defaultFboHandle Defaults FBO handle (defaults to 0).
+ */
+ virtual void render(CameraHelper *camera, const GLuint defaultFboHandle) = 0;
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif // ABSTRACT3DRENDERER_P_H
diff --git a/src/datavis3d/engine/axisrendercache.cpp b/src/datavis3d/engine/axisrendercache.cpp
new file mode 100644
index 00000000..4374d545
--- /dev/null
+++ b/src/datavis3d/engine/axisrendercache.cpp
@@ -0,0 +1,153 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "axisrendercache_p.h"
+#include "qmath.h"
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+AxisRenderCache::AxisRenderCache()
+ : m_type(QAbstractAxis::AxisTypeNone),
+ m_min(0.0),
+ m_max(10.0),
+ m_segmentCount(5),
+ m_subSegmentCount(1),
+ m_drawer(0),
+ m_segmentStep(10.0f),
+ m_subSegmentStep(10.0f)
+{
+}
+
+AxisRenderCache::~AxisRenderCache()
+{
+ foreach (LabelItem *label, m_labelItems)
+ delete label;
+}
+
+void AxisRenderCache::setDrawer(Drawer *drawer)
+{
+ m_drawer = drawer;
+ if (m_drawer) {
+ QObject::connect(m_drawer, &Drawer::drawerChanged, this, &AxisRenderCache::updateTextures);
+ updateTextures();
+ }
+}
+
+void AxisRenderCache::setType(QAbstractAxis::AxisType type)
+{
+ m_type = type;
+
+ // If type is set, it means completely new axis instance, so clear all generated label items.
+ m_titleItem.clear();
+ foreach (LabelItem *label, m_labelItems)
+ delete label;
+ m_labelItems.clear();
+}
+
+void AxisRenderCache::setTitle(const QString &title)
+{
+ if (m_title != title) {
+ m_title = title;
+ // Generate axis label texture
+ if (m_drawer)
+ m_drawer->generateLabelItem(m_titleItem, title);
+ }
+}
+
+void AxisRenderCache::setLabels(const QStringList &labels)
+{
+ if (m_labels != labels) {
+ int newSize(labels.size());
+ int oldSize(m_labels.size());
+
+ for (int i = newSize; i < oldSize; i++)
+ delete m_labelItems.takeLast();
+
+ m_labelItems.reserve(newSize);
+
+ if (m_drawer) {
+ for (int i = 0; i < newSize; i++) {
+ if (i >= oldSize)
+ m_labelItems.append(new LabelItem);
+ if (labels.at(i).isEmpty())
+ m_labelItems[i]->clear();
+ else if (i >= oldSize || labels.at(i) != m_labels.at(i))
+ m_drawer->generateLabelItem(*m_labelItems[i], labels.at(i));
+ }
+ }
+ m_labels = labels;
+ }
+}
+
+void AxisRenderCache::setMin(qreal min)
+{
+ m_min = min;
+ updateSegmentStep();
+}
+
+void AxisRenderCache::setMax(qreal max)
+{
+ m_max = max;
+ updateSegmentStep();
+}
+
+void AxisRenderCache::setSegmentCount(int count)
+{
+ m_segmentCount = count;
+ updateSegmentStep();
+}
+
+void AxisRenderCache::setSubSegmentCount(int count)
+{
+ m_subSegmentCount = count;
+ updateSubSegmentStep();
+}
+
+void AxisRenderCache::updateTextures()
+{
+ if (m_title.isEmpty())
+ m_titleItem.clear();
+ else
+ m_drawer->generateLabelItem(m_titleItem, m_title);
+
+ for (int i = 0; i < m_labels.size(); i++) {
+ if (m_labels.at(i).isEmpty())
+ m_labelItems[i]->clear();
+ else
+ m_drawer->generateLabelItem(*m_labelItems[i], m_labels.at(i));
+ }
+}
+
+void AxisRenderCache::updateSegmentStep()
+{
+ if (m_segmentCount > 0)
+ m_segmentStep = qFabs((m_max - m_min) / m_segmentCount);
+ else
+ m_segmentStep = 0.0f; // Irrelevant
+ updateSubSegmentStep();
+}
+
+void AxisRenderCache::updateSubSegmentStep()
+{
+ if (m_subSegmentCount > 1)
+ m_subSegmentStep = m_segmentStep / m_subSegmentCount;
+ else
+ m_subSegmentStep = m_segmentStep;
+}
+
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/engine/axisrendercache_p.h b/src/datavis3d/engine/axisrendercache_p.h
new file mode 100644
index 00000000..4b38fa20
--- /dev/null
+++ b/src/datavis3d/engine/axisrendercache_p.h
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef AXISRENDERCACHE_P_H
+#define AXISRENDERCACHE_P_H
+
+#include "datavis3dglobal_p.h"
+#include "labelitem_p.h"
+#include "qabstractaxis_p.h"
+#include "drawer_p.h"
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class AxisRenderCache : public QObject
+{
+ Q_OBJECT
+public:
+ AxisRenderCache();
+ virtual ~AxisRenderCache();
+
+ void setDrawer(Drawer *drawer);
+
+ void setType(QAbstractAxis::AxisType type);
+ inline QAbstractAxis::AxisType type() const { return m_type; }
+ void setTitle(const QString &title);
+ inline const QString &title() { return m_title; }
+ void setLabels(const QStringList &labels);
+ inline const QStringList &labels() { return m_labels; }
+ void setMin(qreal min);
+ inline qreal min() { return m_min; }
+ void setMax(qreal max);
+ inline qreal max() { return m_max; }
+ void setSegmentCount(int count);
+ inline int segmentCount() const { return m_segmentCount; }
+ void setSubSegmentCount(int count);
+ inline int subSegmentCount() const { return m_subSegmentCount; }
+
+ inline LabelItem &titleItem() { return m_titleItem; }
+ inline QList<LabelItem *> &labelItems() { return m_labelItems; }
+ inline GLfloat segmentStep() const { return m_segmentStep; }
+ inline GLfloat subSegmentStep() const { return m_subSegmentStep; }
+
+public slots:
+ void updateTextures();
+
+private:
+ void updateSegmentStep();
+ void updateSubSegmentStep();
+
+ // Cached axis values
+ QAbstractAxis::AxisType m_type;
+ QString m_title;
+ QStringList m_labels;
+ qreal m_min;
+ qreal m_max;
+ int m_segmentCount;
+ int m_subSegmentCount;
+
+ // Renderer items
+ Drawer *m_drawer; // Not owned
+ LabelItem m_titleItem;
+ QList<LabelItem *> m_labelItems;
+ GLfloat m_segmentStep;
+ GLfloat m_subSegmentStep;
+
+ Q_DISABLE_COPY(AxisRenderCache)
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/engine/bars3dcontroller.cpp b/src/datavis3d/engine/bars3dcontroller.cpp
new file mode 100644
index 00000000..3f5a31b2
--- /dev/null
+++ b/src/datavis3d/engine/bars3dcontroller.cpp
@@ -0,0 +1,457 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "bars3dcontroller_p.h"
+#include "bars3drenderer_p.h"
+#include "camerahelper_p.h"
+#include "qabstractaxis_p.h"
+#include "qvalueaxis_p.h"
+#include "qcategoryaxis.h"
+#include "qbardataproxy_p.h"
+
+#include <QMatrix4x4>
+#include <QMouseEvent>
+#include <qmath.h>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+Bars3dController::Bars3dController(QRect boundRect)
+ : Abstract3DController(boundRect),
+ m_rowCount(0),
+ m_columnCount(0),
+ m_mouseState(MouseNone),
+ m_mousePos(QPoint(0, 0)),
+ m_isSlicingActivated(false),
+ m_isBarSpecRelative(true),
+ m_barThickness(QSizeF(0.75f, 0.75f)),
+ m_barSpacing(m_barThickness * 3.0f),
+ m_renderer(0),
+ m_data(0)
+{
+ // Default axes
+ setAxisX(new QCategoryAxis());
+ setAxisY(new QValueAxis());
+ setAxisZ(new QCategoryAxis());
+
+ setBarType(QDataVis::Bars, false); // default object type
+
+ setDataProxy(new QBarDataProxy);
+}
+
+Bars3dController::~Bars3dController()
+{
+ delete m_data;
+}
+
+void Bars3dController::initializeOpenGL()
+{
+ // Initialization is called multiple times when Qt Quick components are used
+ if (isInitialized())
+ return;
+
+ m_renderer = new Bars3dRenderer(this);
+ setRenderer(m_renderer);
+}
+
+void Bars3dController::synchDataToRenderer()
+{
+ Abstract3DController::synchDataToRenderer();
+
+ if (!isInitialized())
+ return;
+
+ // Notify changes to renderer
+ if (m_changeTracker.slicingActiveChanged) {
+ m_renderer->updateSlicingActive(m_isSlicingActivated);
+ m_changeTracker.slicingActiveChanged = false;
+ }
+
+ if (m_changeTracker.sampleSpaceChanged) {
+ m_renderer->updateSampleSpace(m_rowCount, m_columnCount);
+ m_changeTracker.sampleSpaceChanged = false;
+ }
+
+ if (m_changeTracker.barSpecsChanged) {
+ m_renderer->updateBarSpecs(m_barThickness, m_barSpacing, m_isBarSpecRelative);
+ m_changeTracker.barSpecsChanged = false;
+ }
+
+ if (m_isDataDirty) {
+ m_renderer->updateDataModel(m_data);
+ m_isDataDirty = false;
+ }
+}
+
+QMatrix4x4 Bars3dController::calculateViewMatrix(int zoom, int viewPortWidth,
+ int viewPortHeight, bool showUnder)
+{
+ return m_cameraHelper->calculateViewMatrix(m_mousePos,
+ zoom,
+ viewPortWidth,
+ viewPortHeight,
+ showUnder);
+}
+
+bool Bars3dController::isSlicingActive()
+{
+ return m_isSlicingActivated;
+}
+
+void Bars3dController::setSlicingActive(bool isSlicing)
+{
+ m_isSlicingActivated = isSlicing;
+
+ m_changeTracker.slicingActiveChanged = true;
+ emit slicingActiveChanged(m_isSlicingActivated);
+}
+
+Bars3dController::MouseState Bars3dController::mouseState()
+{
+ return m_mouseState;
+}
+
+
+#if defined(Q_OS_ANDROID)
+void Bars3dController::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ if (!m_isSlicingActivated) {
+ m_mouseState = Bars3dController::MouseOnScene;
+ // update mouse positions to prevent jumping when releasing or repressing a button
+ m_mousePos = event->pos();
+ }
+}
+
+void Bars3dController::touchEvent(QTouchEvent *event)
+{
+ static int prevDistance = 0;
+
+ QList<QTouchEvent::TouchPoint> points;
+ points = event->touchPoints();
+
+ if (!m_isSlicingActivated && points.count() == 2) {
+ m_mouseState = Bars3dController::MouseOnPinch;
+
+ QPointF distance = points.at(0).pos() - points.at(1).pos();
+ int newDistance = distance.manhattanLength();
+ int zoomRate = 1;
+ int zoomLevel = m_zoomLevel;
+ if (zoomLevel > 100)
+ zoomRate = 5;
+ if (newDistance > prevDistance)
+ zoomLevel += zoomRate;
+ else
+ zoomLevel -= zoomRate;
+ if (zoomLevel > 500)
+ zoomLevel = 500;
+ else if (zoomLevel < 10)
+ zoomLevel = 10;
+ setZoomLevel(zoomLevel);
+ prevDistance = newDistance;
+ //qDebug() << "distance" << distance.manhattanLength();
+ }
+}
+#endif
+
+void Bars3dController::mousePressEvent(QMouseEvent *event, const QPoint &mousePos)
+{
+ QRect mainViewPort = m_renderer->mainViewPort();
+ if (Qt::LeftButton == event->button()) {
+ if (m_isSlicingActivated) {
+ if (mousePos.x() <= mainViewPort.width()
+ && mousePos.y() <= mainViewPort.height()) {
+ m_mouseState = Bars3dController::MouseOnOverview;
+ //qDebug() << "Mouse pressed on overview";
+ } else {
+ m_mouseState = Bars3dController::MouseOnZoom;
+ //qDebug() << "Mouse pressed on zoom";
+ }
+ } else {
+#if !defined(Q_OS_ANDROID)
+ m_mouseState = Bars3dController::MouseOnScene;
+#else
+ m_mouseState = Bars3dController::MouseRotating;
+#endif
+ // update mouse positions to prevent jumping when releasing or repressing a button
+ m_mousePos = mousePos;
+ //qDebug() << "Mouse pressed on scene";
+ }
+ } else if (Qt::MiddleButton == event->button()) {
+ // reset rotations
+ m_mousePos = QPoint(0, 0);
+ } else if (!m_isSlicingActivated && Qt::RightButton == event->button()) {
+ // disable rotating when in slice view
+#if !defined(Q_OS_ANDROID)
+ m_mouseState = Bars3dController::MouseRotating;
+#else
+ m_mouseState = Bars3dController::MouseOnScene;
+#endif
+ // update mouse positions to prevent jumping when releasing or repressing a button
+ m_mousePos = mousePos;
+ }
+ m_cameraHelper->updateMousePos(m_mousePos);
+}
+
+void Bars3dController::mouseReleaseEvent(QMouseEvent *event, const QPoint &mousePos)
+{
+ Q_UNUSED(event);
+ if (Bars3dController::MouseRotating == m_mouseState) {
+ // update mouse positions to prevent jumping when releasing or repressing a button
+ m_mousePos = mousePos;
+ m_cameraHelper->updateMousePos(mousePos);
+ }
+ m_mouseState = Bars3dController::MouseNone;
+}
+
+void Bars3dController::mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos)
+{
+ Q_UNUSED(event);
+ if (Bars3dController::MouseRotating == m_mouseState)
+ m_mousePos = mousePos;
+}
+
+void Bars3dController::wheelEvent(QWheelEvent *event)
+{
+ // disable zooming if in slice view
+ if (m_isSlicingActivated)
+ return;
+
+ int zoomLevel = m_zoomLevel;
+ if (zoomLevel > 100)
+ zoomLevel += event->angleDelta().y() / 12;
+ else if (zoomLevel > 50)
+ zoomLevel += event->angleDelta().y() / 60;
+ else
+ zoomLevel += event->angleDelta().y() / 120;
+ if (zoomLevel > 500)
+ zoomLevel = 500;
+ else if (zoomLevel < 10)
+ zoomLevel = 10;
+
+ setZoomLevel(zoomLevel);
+}
+
+void Bars3dController::setDataProxy(QBarDataProxy *proxy)
+{
+ delete m_data;
+ m_data = proxy;
+
+ QObject::connect(m_data, &QBarDataProxy::arrayReset, this,
+ &Bars3dController::handleArrayReset);
+ QObject::connect(m_data, &QBarDataProxy::rowsAdded, this,
+ &Bars3dController::handleRowsAdded);
+ QObject::connect(m_data, &QBarDataProxy::rowsChanged, this,
+ &Bars3dController::handleRowsChanged);
+ QObject::connect(m_data, &QBarDataProxy::rowsRemoved, this,
+ &Bars3dController::handleRowsRemoved);
+ QObject::connect(m_data, &QBarDataProxy::rowsInserted, this,
+ &Bars3dController::handleRowsInserted);
+ QObject::connect(m_data, &QBarDataProxy::itemChanged, this,
+ &Bars3dController::handleItemChanged);
+
+ adjustValueAxisRange();
+ m_isDataDirty = true;
+}
+
+QBarDataProxy *Bars3dController::dataProxy()
+{
+ return m_data;
+}
+
+void Bars3dController::handleArrayReset()
+{
+ setSlicingActive(false);
+ adjustValueAxisRange();
+ m_isDataDirty = true;
+}
+
+void Bars3dController::handleRowsAdded(int startIndex, int count)
+{
+ Q_UNUSED(startIndex)
+ Q_UNUSED(count)
+ // TODO check if affects data window
+ // TODO should update slice instead of deactivating?
+ setSlicingActive(false);
+ adjustValueAxisRange();
+ m_isDataDirty = true;
+}
+
+void Bars3dController::handleRowsChanged(int startIndex, int count)
+{
+ Q_UNUSED(startIndex)
+ Q_UNUSED(count)
+ // TODO check if affects data window
+ // TODO should update slice instead of deactivating?
+ setSlicingActive(false);
+ adjustValueAxisRange();
+ m_isDataDirty = true;
+}
+
+void Bars3dController::handleRowsRemoved(int startIndex, int count)
+{
+ Q_UNUSED(startIndex)
+ Q_UNUSED(count)
+ // TODO check if affects data window
+ // TODO should update slice instead of deactivating?
+ setSlicingActive(false);
+ adjustValueAxisRange();
+ m_isDataDirty = true;
+}
+
+void Bars3dController::handleRowsInserted(int startIndex, int count)
+{
+ Q_UNUSED(startIndex)
+ Q_UNUSED(count)
+ // TODO check if affects data window
+ // TODO should update slice instead of deactivating?
+ setSlicingActive(false);
+ adjustValueAxisRange();
+ m_isDataDirty = true;
+}
+
+void Bars3dController::handleItemChanged(int rowIndex, int columnIndex)
+{
+ Q_UNUSED(rowIndex)
+ Q_UNUSED(columnIndex)
+ // TODO check if affects data window
+ // TODO should update slice instead of deactivating?
+ setSlicingActive(false);
+ adjustValueAxisRange();
+ m_isDataDirty = true;
+}
+
+void Bars3dController::handleAxisAutoAdjustRangeChangedInOrientation(QAbstractAxis::AxisOrientation orientation, bool autoAdjust)
+{
+ Q_UNUSED(orientation)
+ Q_UNUSED(autoAdjust)
+ adjustValueAxisRange();
+}
+
+void Bars3dController::setBarSpecs(QSizeF thickness, QSizeF spacing, bool relative)
+{
+ m_barThickness = thickness;
+ m_barSpacing = spacing;
+ m_isBarSpecRelative = relative;
+
+ m_changeTracker.barSpecsChanged = true;
+ emit barSpecsChanged(thickness, spacing, relative);
+}
+
+QSizeF Bars3dController::barThickness()
+{
+ return m_barThickness;
+}
+
+QSizeF Bars3dController::barSpacing()
+{
+ return m_barSpacing;
+}
+
+bool Bars3dController::isBarSpecRelative()
+{
+ return m_isBarSpecRelative;
+}
+
+void Bars3dController::setBarType(QDataVis::MeshStyle style, bool smooth)
+{
+ QString objFile;
+ if (style == QDataVis::Bars) {
+ if (smooth)
+ objFile = QStringLiteral(":/defaultMeshes/barSmooth");
+ else
+ objFile = QStringLiteral(":/defaultMeshes/bar");
+ } else if (style == QDataVis::Pyramids) {
+ if (smooth)
+ objFile = QStringLiteral(":/defaultMeshes/pyramidSmooth");
+ else
+ objFile = QStringLiteral(":/defaultMeshes/pyramid");
+ } else if (style == QDataVis::Cones) {
+ if (smooth)
+ objFile = QStringLiteral(":/defaultMeshes/coneSmooth");
+ else
+ objFile = QStringLiteral(":/defaultMeshes/cone");
+ } else if (style == QDataVis::Cylinders) {
+ if (smooth)
+ objFile = QStringLiteral(":/defaultMeshes/cylinderSmooth");
+ else
+ objFile = QStringLiteral(":/defaultMeshes/cylinder");
+ } else if (style == QDataVis::BevelBars) {
+ if (smooth)
+ objFile = QStringLiteral(":/defaultMeshes/bevelbarSmooth");
+ else
+ objFile = QStringLiteral(":/defaultMeshes/bevelbar");
+ }
+ Abstract3DController::setMeshFileName(objFile);
+}
+
+// TODO: This sets data window. Needs more parameters, now assumes window always starts at 0,0.
+void Bars3dController::setupSampleSpace(int rowCount, int columnCount)
+{
+ // Disable zoom mode if we're in it (causes crash if not, as zoom selection is deleted)
+ setSlicingActive(false);
+
+ m_rowCount = rowCount;
+ m_columnCount = columnCount;
+
+ adjustValueAxisRange();
+
+ m_changeTracker.sampleSpaceChanged = true;
+ emit sampleSpaceChanged(rowCount, columnCount);
+}
+
+void Bars3dController::setSelectionMode(QDataVis::SelectionMode mode)
+{
+ // Disable zoom if selection mode changes
+ setSlicingActive(false);
+ Abstract3DController::setSelectionMode(mode);
+}
+
+QPoint Bars3dController::mousePosition()
+{
+ return m_mousePos;
+}
+
+int Bars3dController::columnCount()
+{
+ return m_columnCount;
+}
+
+int Bars3dController::rowCount()
+{
+ return m_rowCount;
+}
+
+void Bars3dController::adjustValueAxisRange()
+{
+ QValueAxis *valueAxis = static_cast<QValueAxis *>(m_axisY);
+ if (valueAxis && valueAxis->isAutoAdjustRange() && m_data) {
+ QPair<GLfloat, GLfloat> limits = m_data->dptr()->limitValues(0, m_rowCount,
+ 0, m_columnCount);
+ if (limits.first < 0) {
+ // TODO: Currently we only support symmetric y-axis for bar chart if there are negative values
+ qreal maxAbs = qMax(qFabs(limits.first), qFabs(limits.second));
+ // Call private implementation to avoid unsetting auto adjust flag
+ valueAxis->dptr()->setRange(-maxAbs, maxAbs);
+ } else if (limits.second == 0.0) {
+ valueAxis->dptr()->setRange(0.0, 1.0); // Only zero value values in data set, set range to something.
+ } else {
+ valueAxis->dptr()->setRange(0.0, limits.second);
+ }
+ }
+}
+
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/engine/bars3dcontroller_p.h b/src/datavis3d/engine/bars3dcontroller_p.h
new file mode 100644
index 00000000..9811eb0d
--- /dev/null
+++ b/src/datavis3d/engine/bars3dcontroller_p.h
@@ -0,0 +1,157 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Q3DBARSCONTROLLER_p_H
+#define Q3DBARSCONTROLLER_p_H
+
+#include "datavis3dglobal_p.h"
+#include "abstract3dcontroller_p.h"
+
+//#define DISPLAY_RENDER_SPEED
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class Bars3dRenderer;
+class QBarDataProxy;
+
+struct Bars3DChangeBitField {
+ bool slicingActiveChanged : 1;
+ bool sampleSpaceChanged : 1;
+ bool barSpecsChanged : 1;
+
+ Bars3DChangeBitField() :
+ slicingActiveChanged(true),
+ sampleSpaceChanged(true),
+ barSpecsChanged(true)
+ {
+ }
+};
+
+class QT_DATAVIS3D_EXPORT Bars3dController : public Abstract3DController
+{
+ Q_OBJECT
+
+private:
+
+
+ Bars3DChangeBitField m_changeTracker;
+
+ // Data
+ int m_rowCount;
+ int m_columnCount;
+
+ // Interaction
+ MouseState m_mouseState;
+ QPoint m_mousePos;
+ bool m_isSlicingActivated;
+
+ // Look'n'feel
+ bool m_isBarSpecRelative;
+ QSizeF m_barThickness;
+ QSizeF m_barSpacing;
+
+ // Rendering
+ Bars3dRenderer *m_renderer;
+ QBarDataProxy *m_data;
+
+public:
+ explicit Bars3dController(QRect rect);
+ ~Bars3dController();
+
+ void initializeOpenGL();
+ virtual void synchDataToRenderer();
+
+ int columnCount();
+ int rowCount();
+
+ MouseState mouseState();
+ QPoint mousePosition();
+
+ bool isSlicingActive();
+ void setSlicingActive(bool isSlicing);
+
+ QMatrix4x4 calculateViewMatrix(int zoom, int viewPortWidth, int viewPortHeight, bool showUnder = false);
+
+ // bar thickness, spacing between bars, and is spacing relative to thickness or absolute
+ // y -component sets the thickness/spacing of z -direction
+ // With relative 0.0f means side-to-side, 1.0f = one thickness in between
+ void setBarSpecs(QSizeF thickness = QSizeF(1.0f, 1.0f),
+ QSizeF spacing = QSizeF(1.0f, 1.0f),
+ bool relative = true);
+ QSizeF barThickness();
+ QSizeF barSpacing();
+ bool isBarSpecRelative();
+
+ // bar type; bars (=cubes), pyramids, cones, cylinders, etc.
+ void setBarType(QDataVis::MeshStyle style, bool smooth = false);
+
+ // how many samples per row and column, and names for axes
+ void setupSampleSpace(int samplesRow, int samplesColumn);
+
+ // Change selection mode; single bar, bar and row, bar and column, or all
+ void setSelectionMode(QDataVis::SelectionMode mode);
+
+#if defined(Q_OS_ANDROID)
+ void mouseDoubleClickEvent(QMouseEvent *event);
+ void touchEvent(QTouchEvent *event);
+#endif
+ void mousePressEvent(QMouseEvent *event, const QPoint &mousePos);
+ void mouseReleaseEvent(QMouseEvent *event, const QPoint &mousePos);
+ void mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos);
+ void wheelEvent(QWheelEvent *event);
+
+ // Sets the data proxy. Assumes ownership of the data proxy. Deletes old proxy.
+ void setDataProxy(QBarDataProxy *proxy);
+ QBarDataProxy *dataProxy();
+ virtual void handleAxisAutoAdjustRangeChangedInOrientation(QAbstractAxis::AxisOrientation orientation, bool autoAdjust);
+
+public slots:
+ void handleArrayReset();
+ void handleRowsAdded(int startIndex, int count);
+ void handleRowsChanged(int startIndex, int count);
+ void handleRowsRemoved(int startIndex, int count);
+ void handleRowsInserted(int startIndex, int count);
+ void handleItemChanged(int rowIndex, int columnIndex);
+
+
+signals:
+ void slicingActiveChanged(bool isSlicing);
+ void sampleSpaceChanged(int samplesRow, int samplesColumn);
+ void barSpecsChanged(QSizeF thickness, QSizeF spacing, bool relative);
+
+private:
+ void adjustValueAxisRange();
+
+ Q_DISABLE_COPY(Bars3dController)
+
+};
+
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/engine/bars3drenderer.cpp b/src/datavis3d/engine/bars3drenderer.cpp
new file mode 100644
index 00000000..908b7888
--- /dev/null
+++ b/src/datavis3d/engine/bars3drenderer.cpp
@@ -0,0 +1,1839 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "bars3drenderer_p.h"
+#include "bars3dcontroller_p.h"
+#include "camerahelper_p.h"
+#include "shaderhelper_p.h"
+#include "objecthelper_p.h"
+#include "texturehelper_p.h"
+#include "theme_p.h"
+#include "utils_p.h"
+#include "drawer_p.h"
+#include "qbardataitem.h"
+
+#include <QMatrix4x4>
+#include <QMouseEvent>
+#include <QThread>
+#include <qmath.h>
+#include <QDebug>
+
+// Commenting this draws the shadow map with perspective projection. Otherwise it's drawn in
+// orthographic projection.
+//#define USE_WIDER_SHADOWS
+
+// You can verify that depth buffer drawing works correctly by uncommenting this.
+// You should see the scene from where the light is
+//#define SHOW_DEPTH_TEXTURE_SCENE
+
+#ifdef DISPLAY_RENDER_SPEED
+#include <QTime>
+#endif
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+#define DISPLAY_FULL_DATA_ON_SELECTION // Append selection value text with row and column labels
+
+const GLfloat gridLineWidth = 0.005f;
+static QVector3D selectionSkipColor = QVector3D(255, 255, 255); // Selection texture's background color
+
+Bars3dRenderer::Bars3dRenderer(Bars3dController *controller)
+ : Abstract3DRenderer(controller),
+ m_controller(controller),
+ m_selectedBar(0),
+ m_previouslySelectedBar(0),
+ m_sliceSelection(0),
+ m_sliceCache(0),
+ m_sliceTitleItem(0),
+ m_xFlipped(false),
+ m_zFlipped(false),
+ m_yFlipped(false),
+ m_updateLabels(false),
+ m_barShader(0),
+ m_depthShader(0),
+ m_selectionShader(0),
+ m_backgroundShader(0),
+ m_labelShader(0),
+ m_barObj(0),
+ m_backgroundObj(0),
+ m_gridLineObj(0),
+ m_labelObj(0),
+ m_bgrTexture(0),
+ m_depthTexture(0),
+ m_selectionTexture(0),
+ m_depthFrameBuffer(0),
+ m_selectionFrameBuffer(0),
+ m_selectionDepthBuffer(0),
+ m_shadowQualityToShader(33.3f),
+ m_heightNormalizer(1.0f),
+ m_yAdjustment(0.0f),
+ m_rowWidth(0),
+ m_columnDepth(0),
+ m_maxDimension(0),
+ m_scaleX(0),
+ m_scaleZ(0),
+ m_scaleFactor(0),
+ m_maxSceneSize(40.0),
+ m_selection(selectionSkipColor),
+ m_hasHeightAdjustmentChanged(true)
+ #ifdef DISPLAY_RENDER_SPEED
+ ,m_isFirstFrame(true),
+ m_numFrames(0)
+ #endif
+{
+ m_dummyBarRenderItem.setRenderer(this);
+ initializeOpenGLFunctions();
+ initializeOpenGL();
+}
+
+Bars3dRenderer::~Bars3dRenderer()
+{
+ m_textureHelper->glDeleteFramebuffers(1, &m_selectionFrameBuffer);
+ m_textureHelper->glDeleteRenderbuffers(1, &m_selectionDepthBuffer);
+ m_textureHelper->deleteTexture(&m_selectionTexture);
+ m_textureHelper->glDeleteFramebuffers(1, &m_depthFrameBuffer);
+ m_textureHelper->deleteTexture(&m_bgrTexture);
+ if (m_sliceSelection) {
+ m_sliceSelection->clear(); // Slice doesn't own its items
+ delete m_sliceSelection;
+ }
+ delete m_barShader;
+ delete m_depthShader;
+ delete m_selectionShader;
+ delete m_backgroundShader;
+ delete m_barObj;
+ delete m_backgroundObj;
+ delete m_gridLineObj;
+ delete m_textureHelper;
+ delete m_drawer;
+}
+
+void Bars3dRenderer::initializeOpenGL()
+{
+ m_textureHelper = new TextureHelper();
+ m_drawer->initializeOpenGL();
+
+ // Initialize shaders
+ handleShadowQualityChange();
+ initLabelShaders(QStringLiteral(":/shaders/vertexLabel"),
+ QStringLiteral(":/shaders/fragmentLabel"));
+
+#if !defined(QT_OPENGL_ES_2)
+ // Init depth shader (for shadows). Init in any case, easier to handle shadow activation if done via api.
+ initDepthShader();
+#endif
+
+ // Init selection shader
+ initSelectionShader();
+
+ // Load grid line mesh
+ loadGridLineMesh();
+
+ // Load label mesh
+ loadLabelMesh();
+
+ // Set OpenGL features
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_LESS);
+ glEnable(GL_CULL_FACE);
+ glCullFace(GL_BACK);
+
+#if !defined(QT_OPENGL_ES_2)
+ glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
+ glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
+ glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
+#endif
+
+ // Set view port
+ glViewport(m_sliceViewPort.x(), m_sliceViewPort.y(),
+ m_sliceViewPort.width(), m_sliceViewPort.height());
+
+ // Load background mesh (we need to be initialized first)
+ loadBackgroundMesh();
+
+ Abstract3DRenderer::initializeOpenGL();
+}
+
+void Bars3dRenderer::updateDataModel(QBarDataProxy *dataProxy)
+{
+ // Update cached data window
+ int dataRowCount = dataProxy->rowCount();
+ for (int i = 0; i < m_renderItemArray.size(); i++) {
+ int j = 0;
+ if (i < dataRowCount) {
+ const QBarDataRow *dataRow = dataProxy->rowAt(i);
+ int updateSize = qMin(dataRow->size(), m_renderItemArray[i].size());
+ if (dataRow) {
+ for (; j < updateSize ; j++) {
+ qreal value = dataRow->at(j).value();
+ m_renderItemArray[i][j].setValue(value);
+ m_renderItemArray[i][j].setHeight(value / m_heightNormalizer);
+ }
+ }
+ }
+ for (; j < m_renderItemArray[i].size(); j++) {
+ m_renderItemArray[i][j].setValue(0.0);
+ m_renderItemArray[i][j].setHeight(0.0f);
+ }
+ }
+
+ Abstract3DRenderer::updateDataModel(dataProxy);
+}
+
+void Bars3dRenderer::render(CameraHelper *camera, const GLuint defaultFboHandle)
+{
+#ifdef DISPLAY_RENDER_SPEED
+ // For speed computation
+ if (m_isFirstFrame) {
+ m_lastFrameTime.start();
+ m_isFirstFrame = false;
+ }
+
+ // Measure speed (as milliseconds per frame)
+ m_numFrames++;
+ if (m_lastFrameTime.elapsed() >= 1000) { // print only if last measurement was more than 1s ago
+ qDebug() << qreal(m_lastFrameTime.elapsed()) / qreal(m_numFrames) << "ms/frame (=" << qreal(m_numFrames) << "fps)";
+ m_numFrames = 0;
+ m_lastFrameTime.restart();
+ }
+#endif
+
+ if (defaultFboHandle) {
+ glDepthMask(true);
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_LESS);
+ glEnable(GL_CULL_FACE);
+ glCullFace(GL_BACK);
+ }
+
+ QVector3D clearColor = Utils::vectorFromColor(m_cachedTheme.m_windowColor);
+ glClearColor(clearColor.x(), clearColor.y(), clearColor.z(), 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ if (m_hasHeightAdjustmentChanged) {
+ // Set initial camera position. Also update if height adjustment has changed.
+ camera->setDefaultCameraOrientation(QVector3D(0.0f, 0.0f, 6.0f + zComp),
+ QVector3D(0.0f, -m_yAdjustment, zComp),
+ QVector3D(0.0f, 1.0f, 0.0f));
+ m_hasHeightAdjustmentChanged = false;
+ }
+
+ // If slice selection is on, draw the sliced scene
+ if (m_cachedIsSlicingActivated)
+ drawSlicedScene(camera, m_axisCacheX.titleItem(), m_axisCacheY.titleItem(), m_axisCacheZ.titleItem());
+
+ // Draw bars scene
+ drawScene(camera, defaultFboHandle);
+}
+
+void Bars3dRenderer::drawSlicedScene(CameraHelper *camera,
+ const LabelItem &xLabel,
+ const LabelItem &yLabel,
+ const LabelItem &zLabel)
+{
+ GLfloat barPosX = 0;
+ GLint startBar = 0;
+ GLint stopBar = m_sliceSelection->size();
+ GLint stepBar = 1;
+ QVector3D lightPos;
+
+ // Specify viewport
+ glViewport(m_sliceViewPort.x(), m_sliceViewPort.y(),
+ m_sliceViewPort.width(), m_sliceViewPort.height());
+
+ // Set up projection matrix
+ QMatrix4x4 projectionMatrix;
+ projectionMatrix.perspective(45.0f, (GLfloat)m_sliceViewPort.width()
+ / (GLfloat)m_sliceViewPort.height(), 0.1f, 100.0f);
+
+#ifdef ROTATE_ZOOM_SELECTION
+ // Calculate view matrix
+ QMatrix4x4 viewMatrix = m_controller->calculateViewMatrix(m_cachedZoomLevel * m_autoScaleAdjustment,
+ m_sliceViewPort.width(),
+ m_sliceViewPort.height());
+
+ // Get light position (rotate light with camera, a bit above it (as set in defaultLightPos))
+ lightPos = camera->calculateLightPosition(defaultLightPos);
+
+ if (viewMatrix.row(0).z() <= 0) {
+ startBar = m_sliceSelection->size() - 1;
+ stopBar = -1;
+ stepBar = -1;
+ }
+#else
+ // Set view matrix
+ QMatrix4x4 viewMatrix;
+
+ // Adjust scaling (zoom rate based on aspect ratio)
+ GLfloat camPosZoomed = 5.0f / m_autoScaleAdjustment + zComp;
+
+ viewMatrix.lookAt(QVector3D(0.0f, 0.0f, camPosZoomed),
+ QVector3D(0.0f, 0.0f, zComp),
+ QVector3D(0.0f, 1.0f, 0.0f));
+
+ // Set light position a bit below the camera to reduce glare (depends on do we have row or column zoom)
+ QVector3D sliceLightPos = defaultLightPos;
+ sliceLightPos.setY(-10.0f);
+ if (QDataVis::ModeZoomColumn == m_cachedSelectionMode)
+ lightPos = camera->calculateLightPosition(sliceLightPos, -85.0f);
+ else
+ lightPos = camera->calculateLightPosition(sliceLightPos, 5.0f);
+#endif
+
+ // Bind bar shader
+ m_barShader->bind();
+
+ // Draw bars
+ // Draw the selected row / column
+ for (int bar = startBar; bar != stopBar; bar += stepBar) {
+ BarRenderItem *item = m_sliceSelection->at(bar);
+ if (!item)
+ continue;
+
+ if (item->height() < 0)
+ glCullFace(GL_FRONT);
+ else
+ glCullFace(GL_BACK);
+
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+ QMatrix4x4 itModelMatrix;
+
+ GLfloat barPosY = item->translation().y() - m_yAdjustment / 2.0f + 0.2f; // we need some room for labels underneath; add +0.2f
+ if (QDataVis::ModeZoomRow == m_cachedSelectionMode)
+ barPosX = item->translation().x();
+ else
+ barPosX = -(item->translation().z() - zComp); // flip z; frontmost bar to the left
+ modelMatrix.translate(barPosX, barPosY, zComp);
+ modelMatrix.scale(QVector3D(m_scaleX, item->height(), m_scaleZ));
+ itModelMatrix.scale(QVector3D(m_scaleX, item->height(), m_scaleZ));
+
+ MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
+
+ QVector3D baseColor = Utils::vectorFromColor(m_cachedTheme.m_baseColor);
+ QVector3D heightColor = Utils::vectorFromColor(m_cachedTheme.m_heightColor) * item->height();
+
+ QVector3D barColor = baseColor + heightColor;
+
+ GLfloat lightStrength = m_cachedTheme.m_lightStrength;
+
+ if (item->height() != 0) {
+ // Set shader bindings
+ m_barShader->setUniformValue(m_barShader->lightP(), lightPos);
+ m_barShader->setUniformValue(m_barShader->view(), viewMatrix);
+ m_barShader->setUniformValue(m_barShader->model(), modelMatrix);
+ m_barShader->setUniformValue(m_barShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ m_barShader->setUniformValue(m_barShader->MVP(), MVPMatrix);
+ m_barShader->setUniformValue(m_barShader->color(), barColor);
+ m_barShader->setUniformValue(m_barShader->lightS(), lightStrength);
+ m_barShader->setUniformValue(m_barShader->ambientS(), m_cachedTheme.m_ambientStrength);
+
+ // Draw the object
+ m_drawer->drawObject(m_barShader, m_barObj);
+ }
+ }
+
+ // Release bar shader
+ m_barShader->release();
+
+ // Draw labels
+ m_labelShader->bind();
+ glDisable(GL_DEPTH_TEST);
+ glEnable(GL_TEXTURE_2D);
+ glCullFace(GL_BACK);
+ if (m_cachedLabelTransparency > QDataVis::TransparencyNone) {
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ }
+
+ // Draw labels for axes
+ BarRenderItem *dummyItem(0);
+ const LabelItem &sliceSelectionLabel = *m_sliceTitleItem;
+ if (QDataVis::ModeZoomRow == m_cachedSelectionMode) {
+ if (m_sliceTitleItem) {
+ m_drawer->drawLabel(*dummyItem, sliceSelectionLabel, viewMatrix, projectionMatrix,
+ QVector3D(0.0f, m_yAdjustment, zComp),
+ QVector3D(0.0f, 0.0f, 0.0f), 0,
+ m_cachedSelectionMode, m_labelShader,
+ m_labelObj, camera, false, false, Drawer::LabelTop);
+ }
+ m_drawer->drawLabel(*dummyItem, zLabel, viewMatrix, projectionMatrix,
+ QVector3D(0.0f, m_yAdjustment, zComp),
+ QVector3D(0.0f, 0.0f, 0.0f), 0,
+ m_cachedSelectionMode, m_labelShader,
+ m_labelObj, camera, false, false, Drawer::LabelBottom);
+ } else {
+ m_drawer->drawLabel(*dummyItem, xLabel, viewMatrix, projectionMatrix,
+ QVector3D(0.0f, m_yAdjustment, zComp),
+ QVector3D(0.0f, 0.0f, 0.0f), 0,
+ m_cachedSelectionMode, m_labelShader,
+ m_labelObj, camera, false, false, Drawer::LabelBottom);
+ if (m_sliceTitleItem) {
+ m_drawer->drawLabel(*dummyItem, sliceSelectionLabel, viewMatrix, projectionMatrix,
+ QVector3D(0.0f, m_yAdjustment, zComp),
+ QVector3D(0.0f, 0.0f, 0.0f), 0,
+ m_cachedSelectionMode, m_labelShader,
+ m_labelObj, camera, false, false, Drawer::LabelTop);
+ }
+ }
+ m_drawer->drawLabel(*dummyItem, yLabel, viewMatrix, projectionMatrix,
+ QVector3D(0.0f, m_yAdjustment, zComp),
+ QVector3D(0.0f, 0.0f, 90.0f), 0,
+ m_cachedSelectionMode, m_labelShader,
+ m_labelObj, camera, false, false, Drawer::LabelLeft);
+
+ // Draw labels for bars
+ for (int col = 0; col < m_sliceSelection->size(); col++) {
+ BarRenderItem *item = m_sliceSelection->at(col);
+ // Draw values
+ m_drawer->drawLabel(*item, item->labelItem(), viewMatrix, projectionMatrix,
+ QVector3D(0.0f, m_yAdjustment, zComp),
+ QVector3D(0.0f, 0.0f, 0.0f), item->height(),
+ m_cachedSelectionMode, m_labelShader,
+ m_labelObj, camera);
+
+ // Draw labels
+ if (m_sliceCache->labelItems().size() > col) {
+ const LabelItem *labelItem(0);
+ // If draw order of bars is flipped, label draw order should be too
+ if (m_xFlipped) {
+ labelItem = m_sliceCache->labelItems().at(
+ m_sliceCache->labelItems().size() - col - 1);
+ } else {
+ labelItem = m_sliceCache->labelItems().at(col);
+ }
+ m_drawer->drawLabel(*item, *labelItem, viewMatrix, projectionMatrix,
+ QVector3D(0.0f, m_yAdjustment, zComp),
+ QVector3D(0.0f, 0.0f, -45.0f), item->height(),
+ m_cachedSelectionMode, m_labelShader,
+ m_labelObj, camera, false, false, Drawer::LabelBelow);
+ }
+ }
+
+ glDisable(GL_TEXTURE_2D);
+ if (m_cachedLabelTransparency > QDataVis::TransparencyNone)
+ glDisable(GL_BLEND);
+ glEnable(GL_DEPTH_TEST);
+
+ // Release label shader
+ m_labelShader->release();
+}
+
+void Bars3dRenderer::drawScene(CameraHelper *camera,
+ const GLuint defaultFboHandle)
+{
+ GLint startBar = 0;
+ GLint stopBar = 0;
+ GLint stepBar = 0;
+
+ GLint startRow = 0;
+ GLint stopRow = 0;
+ GLint stepRow = 0;
+
+ GLfloat backgroundRotation = 0;
+
+ GLfloat barPos = 0;
+ GLfloat rowPos = 0;
+
+ //m_selection = selectionSkipColor;
+
+ // Specify viewport
+ glViewport(m_mainViewPort.x(), m_mainViewPort.y(),
+ m_mainViewPort.width(), m_mainViewPort.height());
+
+ // Set up projection matrix
+ QMatrix4x4 projectionMatrix;
+ projectionMatrix.perspective(45.0f, (GLfloat)m_mainViewPort.width()
+ / (GLfloat)m_mainViewPort.height(), 0.1f, 100.0f);
+
+ // Calculate view matrix
+ QMatrix4x4 viewMatrix = m_controller->calculateViewMatrix(
+ m_cachedZoomLevel * m_autoScaleAdjustment,
+ m_mainViewPort.width(),
+ m_mainViewPort.height(),
+ m_hasNegativeValues);
+
+ // Calculate drawing order
+ // Draw order is reversed to optimize amount of drawing (ie. draw front objects first, depth test handles not needing to draw objects behind them)
+ if (viewMatrix.row(0).x() > 0) {
+ startRow = 0;
+ stopRow = m_cachedRowCount;
+ stepRow = 1;
+ m_zFlipped = false;
+ } else {
+ startRow = m_cachedRowCount - 1;
+ stopRow = -1;
+ stepRow = -1;
+ m_zFlipped = true;
+ }
+ if (viewMatrix.row(0).z() <= 0) {
+ startBar = 0;
+ stopBar = m_cachedColumnCount;
+ stepBar = 1;
+ m_xFlipped = false;
+ } else {
+ startBar = m_cachedColumnCount - 1;
+ stopBar = -1;
+ stepBar = -1;
+ m_xFlipped = true;
+ }
+
+ // Check if we're viewing the scene from below
+ if (viewMatrix.row(2).y() < 0)
+ m_yFlipped = true;
+ else
+ m_yFlipped = false;
+
+ // calculate background rotation based on view matrix rotation
+ if (viewMatrix.row(0).x() > 0 && viewMatrix.row(0).z() <= 0)
+ backgroundRotation = 270.0f;
+ else if (viewMatrix.row(0).x() > 0 && viewMatrix.row(0).z() > 0)
+ backgroundRotation = 180.0f;
+ else if (viewMatrix.row(0).x() <= 0 && viewMatrix.row(0).z() > 0)
+ backgroundRotation = 90.0f;
+ else if (viewMatrix.row(0).x() <= 0 && viewMatrix.row(0).z() <= 0)
+ backgroundRotation = 0.0f;
+
+ // Get light position (rotate light with camera, a bit above it (as set in defaultLightPos))
+ QVector3D lightPos = camera->calculateLightPosition(defaultLightPos);
+
+ // Skip depth rendering if we're in slice mode
+ // TODO: Fix this, causes problems if depth rendering is off in slice mode
+ // Introduce regardless of shadow quality to simplify logic
+ QMatrix4x4 depthViewMatrix;
+ QMatrix4x4 depthProjectionMatrix;
+
+#if !defined(QT_OPENGL_ES_2)
+ if (m_cachedShadowQuality > QDataVis::ShadowNone/*!m_cachedIsSlicingActivated*/) {
+ // Render scene into a depth texture for using with shadow mapping
+ // Enable drawing to depth framebuffer
+ glBindFramebuffer(GL_FRAMEBUFFER, m_depthFrameBuffer);
+ glClear(GL_DEPTH_BUFFER_BIT);
+
+ // Bind depth shader
+ m_depthShader->bind();
+
+ // Set viewport for depth map rendering. Must match texture size. Larger values give smoother shadows.
+ glViewport(m_mainViewPort.x(), m_mainViewPort.y(),
+ m_mainViewPort.width() * m_cachedShadowQuality,
+ m_mainViewPort.height() * m_cachedShadowQuality);
+
+ // Get the depth view matrix
+ // It may be possible to hack lightPos here if we want to make some tweaks to shadow
+ QVector3D depthLightPos = camera->calculateLightPosition(
+ QVector3D(0.0f, 0.0f, zComp), 0.0f, 1.5f / m_autoScaleAdjustment);
+ depthViewMatrix.lookAt(depthLightPos, QVector3D(0.0f, -m_yAdjustment, zComp),
+ QVector3D(0.0f, 1.0f, 0.0f));
+ // TODO: Why does depthViewMatrix.column(3).y() goes to zero when we're directly above? That causes the scene to be not drawn from above -> must be fixed
+ //qDebug() << lightPos << depthViewMatrix << depthViewMatrix.column(3);
+ // Set the depth projection matrix
+#ifndef USE_WIDER_SHADOWS
+ // Use this for perspective shadows
+ depthProjectionMatrix.perspective(15.0f, (GLfloat)m_mainViewPort.width()
+ / (GLfloat)m_mainViewPort.height(), 3.0f, 100.0f);
+#else
+ // Use these for orthographic shadows
+ //GLfloat testAspectRatio = (GLfloat)m_mainViewPort.width() / (GLfloat)m_mainViewPort.height();
+ //qDebug() << m_autoScaleAdjustment << m_yAdjustment;
+ depthProjectionMatrix.ortho(-2.0f * 2.0f, 2.0f * 2.0f,
+ -2.0f, 2.0f,
+ 0.0f, 100.0f);
+#endif
+ // Draw bars to depth buffer
+ for (int row = startRow; row != stopRow; row += stepRow) {
+ for (int bar = startBar; bar != stopBar; bar += stepBar) {
+ const BarRenderItem &item = m_renderItemArray.at(row).at(bar);
+ if (!item.value())
+ continue;
+
+ // Set front face culling for positive valued bars and back face culling for
+ // negative valued bars to reduce self-shadowing issues
+ if (item.height() < 0)
+ glCullFace(GL_BACK);
+ else
+ glCullFace(GL_FRONT);
+
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+
+ barPos = (bar + 1) * (m_cachedBarSpacing.width());
+ rowPos = (row + 1) * (m_cachedBarSpacing.height());
+
+ modelMatrix.translate((m_rowWidth - barPos) / m_scaleFactor,
+ item.height() - m_yAdjustment,
+ (m_columnDepth - rowPos) / m_scaleFactor + zComp);
+ modelMatrix.scale(QVector3D(m_scaleX, item.height(), m_scaleZ));
+
+ MVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
+
+ m_depthShader->setUniformValue(m_depthShader->MVP(), MVPMatrix);
+
+ // 1st attribute buffer : vertices
+ glEnableVertexAttribArray(m_depthShader->posAtt());
+ glBindBuffer(GL_ARRAY_BUFFER, m_barObj->vertexBuf());
+ glVertexAttribPointer(m_depthShader->posAtt(), 3, GL_FLOAT, GL_FALSE, 0,
+ (void *)0);
+
+ // Index buffer
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_barObj->elementBuf());
+
+ // Draw the triangles
+ glDrawElements(GL_TRIANGLES, m_barObj->indexCount(), GL_UNSIGNED_SHORT,
+ (void *)0);
+
+ // Free buffers
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ glDisableVertexAttribArray(m_depthShader->posAtt());
+ }
+ }
+
+ // Disable drawing to depth framebuffer (= enable drawing to screen)
+ glBindFramebuffer(GL_FRAMEBUFFER, defaultFboHandle);
+
+ // Release depth shader
+ m_depthShader->release();
+
+#if 0 // Use this if you want to see what is being drawn to the framebuffer
+ // You'll also have to comment out GL_COMPARE_R_TO_TEXTURE -line in texturehelper (if using it)
+ m_labelShader->bind();
+ glCullFace(GL_BACK);
+ glEnable(GL_TEXTURE_2D);
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 viewmatrix;
+ viewmatrix.lookAt(QVector3D(0.0f, 0.0f, 2.5f + zComp),
+ QVector3D(0.0f, 0.0f, zComp),
+ QVector3D(0.0f, 1.0f, 0.0f));
+ modelMatrix.translate(0.0, 0.0, zComp);
+ QMatrix4x4 MVPMatrix = projectionMatrix * viewmatrix * modelMatrix;
+ m_labelShader->setUniformValue(m_labelShader->MVP(), MVPMatrix);
+ m_drawer->drawObject(m_labelShader, m_labelObj,
+ m_depthTexture);
+ glDisable(GL_TEXTURE_2D);
+ m_labelShader->release();
+#endif
+ // Reset culling to normal
+ glCullFace(GL_BACK);
+
+ // Revert to original viewport
+ glViewport(m_mainViewPort.x(), m_mainViewPort.y(),
+ m_mainViewPort.width(), m_mainViewPort.height());
+ }
+#endif
+
+ // Skip selection mode drawing if we're slicing or have no selection mode
+ if (!m_cachedIsSlicingActivated && m_cachedSelectionMode > QDataVis::ModeNone) {
+ // Bind selection shader
+ m_selectionShader->bind();
+
+ // Draw bars to selection buffer
+ glBindFramebuffer(GL_FRAMEBUFFER, m_selectionFrameBuffer);
+ glEnable(GL_DEPTH_TEST); // Needed, otherwise the depth render buffer is not used
+ glClearColor(selectionSkipColor.x() / 255, selectionSkipColor.y() / 255,
+ selectionSkipColor.z() / 255, 1.0f); // Set clear color to white (= selectionSkipColor)
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Needed for clearing the frame buffer
+ glDisable(GL_DITHER); // disable dithering, it may affect colors if enabled
+ for (int row = startRow; row != stopRow; row += stepRow) {
+ for (int bar = startBar; bar != stopBar; bar += stepBar) {
+ const BarRenderItem &item = m_renderItemArray.at(row).at(bar);
+ if (!item.value())
+ continue;
+
+ if (item.height() < 0)
+ glCullFace(GL_FRONT);
+ else
+ glCullFace(GL_BACK);
+
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+
+ barPos = (bar + 1) * (m_cachedBarSpacing.width());
+ rowPos = (row + 1) * (m_cachedBarSpacing.height());
+
+ modelMatrix.translate((m_rowWidth - barPos) / m_scaleFactor,
+ item.height() - m_yAdjustment,
+ (m_columnDepth - rowPos) / m_scaleFactor + zComp);
+ modelMatrix.scale(QVector3D(m_scaleX, item.height(), m_scaleZ));
+
+ MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
+
+ // TODO: Save position to qdataitem, so that we don't need to calculate it each time?
+
+ //#if !defined(QT_OPENGL_ES_2)
+ // QVector3D barColor = QVector3D((GLdouble)row / 32767.0,
+ // (GLdouble)bar / 32767.0,
+ // 0.0);
+ //#else
+ QVector3D barColor = QVector3D((GLdouble)row / 255.0,
+ (GLdouble)bar / 255.0,
+ 0.0);
+ //#endif
+
+ m_selectionShader->setUniformValue(m_selectionShader->MVP(), MVPMatrix);
+ m_selectionShader->setUniformValue(m_selectionShader->color(), barColor);
+
+ // 1st attribute buffer : vertices
+ glEnableVertexAttribArray(m_selectionShader->posAtt());
+ glBindBuffer(GL_ARRAY_BUFFER, m_barObj->vertexBuf());
+ glVertexAttribPointer(m_selectionShader->posAtt(), 3, GL_FLOAT, GL_FALSE, 0,
+ (void *)0);
+
+ // Index buffer
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_barObj->elementBuf());
+
+ // Draw the triangles
+ glDrawElements(GL_TRIANGLES, m_barObj->indexCount(), GL_UNSIGNED_SHORT, (void *)0);
+
+ // Free buffers
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ glDisableVertexAttribArray(m_selectionShader->posAtt());
+ }
+ }
+ glEnable(GL_DITHER);
+
+ // Read color under cursor
+ if (Bars3dController::MouseOnScene == m_controller->mouseState())
+ m_selection = Utils::getSelection(m_controller->mousePosition(), m_cachedBoundingRect.height());
+
+ QMutexLocker locker(&m_mutex);
+ if (m_isSelectionPointRequestActive) {
+ m_isSelectionPointRequestActive = false;
+ m_selection = Utils::getSelection(m_selectionPointRequest, m_cachedBoundingRect.height());
+ emit selectionUpdated(m_selection);
+ }
+ locker.unlock();
+
+ glBindFramebuffer(GL_FRAMEBUFFER, defaultFboHandle);
+
+ // Release selection shader
+ m_selectionShader->release();
+
+#if 0 // Use this if you want to see what is being drawn to the framebuffer
+ glCullFace(GL_BACK);
+ m_labelShader->bind();
+ glDisable(GL_DEPTH_TEST);
+ glEnable(GL_TEXTURE_2D);
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 viewmatrix;
+ viewmatrix.lookAt(QVector3D(0.0f, 0.0f, 2.0f + zComp),
+ QVector3D(0.0f, 0.0f, zComp),
+ QVector3D(0.0f, 1.0f, 0.0f));
+ modelMatrix.translate(0.0, 0.0, zComp);
+ QMatrix4x4 MVPMatrix = projectionMatrix * viewmatrix * modelMatrix;
+ m_labelShader->setUniformValue(m_labelShader->MVP(), MVPMatrix);
+ m_drawer->drawObject(m_labelShader, m_labelObj, m_selectionTexture);
+ glDisable(GL_TEXTURE_2D);
+ m_labelShader->release();
+#endif
+ }
+
+ // Enable texturing
+ glEnable(GL_TEXTURE_2D);
+
+ // Bind bar shader
+ m_barShader->bind();
+
+ // Draw bars
+ if (!m_cachedIsSlicingActivated && m_sliceSelection) {
+ m_sliceSelection->clear(); // Slice doesn't own its items
+ m_sliceCache = 0;
+ m_sliceTitleItem = 0;
+ }
+ bool barSelectionFound = false;
+ for (int row = startRow; row != stopRow; row += stepRow) {
+ for (int bar = startBar; bar != stopBar; bar += stepBar) {
+ BarRenderItem &item = m_renderItemArray[row][bar];
+
+ if (item.height() < 0)
+ glCullFace(GL_FRONT);
+ else
+ glCullFace(GL_BACK);
+
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 itModelMatrix;
+ QMatrix4x4 MVPMatrix;
+ QMatrix4x4 depthMVPMatrix;
+
+ barPos = (bar + 1) * (m_cachedBarSpacing.width());
+ rowPos = (row + 1) * (m_cachedBarSpacing.height());
+ modelMatrix.translate((m_rowWidth - barPos) / m_scaleFactor,
+ item.height() - m_yAdjustment,
+ (m_columnDepth - rowPos) / m_scaleFactor + zComp);
+ modelMatrix.scale(QVector3D(m_scaleX, item.height(), m_scaleZ));
+ itModelMatrix.scale(QVector3D(m_scaleX, item.height(), m_scaleZ));
+#ifdef SHOW_DEPTH_TEXTURE_SCENE
+ MVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
+#else
+ MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
+#endif
+ depthMVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
+
+ QVector3D baseColor = Utils::vectorFromColor(m_cachedTheme.m_baseColor);
+ QVector3D heightColor = Utils::vectorFromColor(m_cachedTheme.m_heightColor) * item.height();
+ QVector3D depthColor = Utils::vectorFromColor(m_cachedTheme.m_depthColor)
+ * (float(row) / GLfloat(m_cachedRowCount));
+
+ QVector3D barColor = baseColor + heightColor + depthColor;
+
+ GLfloat lightStrength = m_cachedTheme.m_lightStrength;
+
+ if (m_cachedSelectionMode > QDataVis::ModeNone) {
+ Bars3dController::SelectionType selectionType = isSelected(row, bar);
+
+ switch (selectionType) {
+ case Bars3dController::SelectionItem: {
+ barColor = Utils::vectorFromColor(m_cachedTheme.m_highlightBarColor);
+ lightStrength = m_cachedTheme.m_highlightLightStrength;
+ // Insert data to QDataItem. We have no ownership, don't delete the previous one
+ if (!m_cachedIsSlicingActivated) {
+ m_selectedBar = &item;
+ m_selectedBar->setPosition(QPoint(row, bar));
+ item.setTranslation(modelMatrix.column(3).toVector3D());
+ barSelectionFound = true;
+ if (m_cachedSelectionMode >= QDataVis::ModeZoomRow) {
+ item.setTranslation(modelMatrix.column(3).toVector3D());
+ m_sliceSelection->append(&item);
+ }
+ }
+ break;
+ }
+ case Bars3dController::SelectionRow: {
+ // Current bar is on the same row as the selected bar
+ barColor = Utils::vectorFromColor(m_cachedTheme.m_highlightRowColor);
+ lightStrength = m_cachedTheme.m_highlightLightStrength;
+ if (!m_cachedIsSlicingActivated && QDataVis::ModeZoomRow == m_cachedSelectionMode) {
+ item.setTranslation(modelMatrix.column(3).toVector3D());
+ m_sliceSelection->append(&item);
+ if (!m_sliceCache) {
+ // m_sliceCache is the axis for labels, while title comes from different axis.
+ m_sliceCache = &m_axisCacheZ;
+ if (m_axisCacheX.labelItems().size() > row)
+ m_sliceTitleItem = m_axisCacheX.labelItems().at(row);
+ }
+ }
+ break;
+ }
+ case Bars3dController::SelectionColumn: {
+ // Current bar is on the same column as the selected bar
+ barColor = Utils::vectorFromColor(m_cachedTheme.m_highlightColumnColor);
+ lightStrength = m_cachedTheme.m_highlightLightStrength;
+ if (!m_cachedIsSlicingActivated
+ && QDataVis::ModeZoomColumn == m_cachedSelectionMode) {
+ item.setTranslation(modelMatrix.column(3).toVector3D());
+ m_sliceSelection->append(&item);
+ if (!m_sliceCache) {
+ // m_sliceCache is the axis for labels, while title comes from different axis.
+ m_sliceCache = &m_axisCacheX;
+ if (m_axisCacheZ.labelItems().size() > bar)
+ m_sliceTitleItem = m_axisCacheZ.labelItems().at(bar);
+ }
+ }
+ break;
+ }
+ case Bars3dController::SelectionNone: {
+ // Current bar is not selected, nor on a row or column
+ // do nothing
+ break;
+ }
+ }
+ }
+
+ // Skip drawing of 0 -height bars
+ if (item.height() != 0) {
+ // Set shader bindings
+ m_barShader->setUniformValue(m_barShader->lightP(), lightPos);
+ m_barShader->setUniformValue(m_barShader->view(), viewMatrix);
+ m_barShader->setUniformValue(m_barShader->model(), modelMatrix);
+ m_barShader->setUniformValue(m_barShader->nModel(),
+ itModelMatrix.transposed().inverted());
+ m_barShader->setUniformValue(m_barShader->MVP(), MVPMatrix);
+ m_barShader->setUniformValue(m_barShader->color(), barColor);
+ m_barShader->setUniformValue(m_barShader->ambientS(), m_cachedTheme.m_ambientStrength);
+
+#if !defined(QT_OPENGL_ES_2)
+ if (m_cachedShadowQuality > QDataVis::ShadowNone) {
+ // Set shadow shader bindings
+ m_barShader->setUniformValue(m_barShader->shadowQ(), m_shadowQualityToShader);
+ m_barShader->setUniformValue(m_barShader->depth(), depthMVPMatrix);
+ m_barShader->setUniformValue(m_barShader->lightS(), lightStrength / 10.0f);
+
+ // Draw the object
+ m_drawer->drawObject(m_barShader, m_barObj, 0, m_depthTexture);
+ } else
+#endif
+ {
+ // Set shadowless shader bindings
+ m_barShader->setUniformValue(m_barShader->lightS(), lightStrength);
+
+ // Draw the object
+ m_drawer->drawObject(m_barShader, m_barObj);
+ }
+ }
+ }
+ }
+
+ // Release bar shader
+ m_barShader->release();
+
+ // Bind background shader
+ m_backgroundShader->bind();
+
+ if (m_hasNegativeValues)
+ glDisable(GL_CULL_FACE);
+ else
+ glCullFace(GL_BACK);
+
+ // Draw background
+ if (m_cachedIsBackgroundEnabled && m_backgroundObj) {
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+ QMatrix4x4 depthMVPMatrix;
+ QMatrix4x4 itModelMatrix;
+
+ modelMatrix.translate(0.0f, 1.0f - m_yAdjustment, zComp);
+ modelMatrix.scale(QVector3D(m_rowWidth / m_scaleFactor,
+ 1.0f,
+ m_columnDepth / m_scaleFactor));
+ modelMatrix.rotate(backgroundRotation, 0.0f, 1.0f, 0.0f);
+ itModelMatrix.scale(QVector3D(m_rowWidth / m_scaleFactor,
+ 1.0f,
+ m_columnDepth / m_scaleFactor));
+
+#ifdef SHOW_DEPTH_TEXTURE_SCENE
+ MVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
+#else
+ MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
+#endif
+ depthMVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
+
+ QVector3D backgroundColor = Utils::vectorFromColor(m_cachedTheme.m_backgroundColor);
+
+ // Set shader bindings
+ m_backgroundShader->setUniformValue(m_backgroundShader->lightP(), lightPos);
+ m_backgroundShader->setUniformValue(m_backgroundShader->view(), viewMatrix);
+ m_backgroundShader->setUniformValue(m_backgroundShader->model(), modelMatrix);
+ m_backgroundShader->setUniformValue(m_backgroundShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ m_backgroundShader->setUniformValue(m_backgroundShader->MVP(), MVPMatrix);
+ m_backgroundShader->setUniformValue(m_backgroundShader->color(), backgroundColor);
+ m_backgroundShader->setUniformValue(m_backgroundShader->ambientS(),
+ m_cachedTheme.m_ambientStrength * 2.0f);
+
+#if !defined(QT_OPENGL_ES_2)
+ if (m_cachedShadowQuality > QDataVis::ShadowNone) {
+ // Set shadow shader bindings
+ m_backgroundShader->setUniformValue(m_backgroundShader->shadowQ(),
+ m_shadowQualityToShader);
+ m_backgroundShader->setUniformValue(m_backgroundShader->depth(), depthMVPMatrix);
+ m_backgroundShader->setUniformValue(m_backgroundShader->lightS(),
+ m_cachedTheme.m_lightStrength / 10.0f);
+
+ // Draw the object
+ m_drawer->drawObject(m_backgroundShader, m_backgroundObj, 0, m_depthTexture);
+ } else
+#endif
+ {
+ // Set shadowless shader bindings
+ m_backgroundShader->setUniformValue(m_backgroundShader->lightS(),
+ m_cachedTheme.m_lightStrength);
+
+ // Draw the object
+ m_drawer->drawObject(m_backgroundShader, m_backgroundObj);
+ }
+ }
+
+ // Release background shader
+ m_backgroundShader->release();
+
+ // Disable textures
+ glDisable(GL_TEXTURE_2D);
+
+ // Reset culling
+ if (m_hasNegativeValues) {
+ glEnable(GL_CULL_FACE);
+ glCullFace(GL_BACK);
+ }
+
+ // Draw grid lines
+ if (m_cachedIsGridEnabled && m_heightNormalizer) {
+ // Bind bar shader
+ m_barShader->bind();
+
+ // Set unchanging shader bindings
+ QVector3D barColor = Utils::vectorFromColor(m_cachedTheme.m_gridLine);
+ m_barShader->setUniformValue(m_barShader->lightP(), lightPos);
+ m_barShader->setUniformValue(m_barShader->view(), viewMatrix);
+ m_barShader->setUniformValue(m_barShader->color(), barColor);
+ m_barShader->setUniformValue(m_barShader->ambientS(), m_cachedTheme.m_ambientStrength);
+
+ // Floor lines: rows
+ for (GLfloat row = 0.0f; row <= m_cachedRowCount; row++) {
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+ QMatrix4x4 depthMVPMatrix;
+ QMatrix4x4 itModelMatrix;
+
+ rowPos = (row + 0.5f) * (m_cachedBarSpacing.height());
+ modelMatrix.translate(0.0f, -m_yAdjustment,
+ (m_columnDepth - rowPos) / m_scaleFactor + zComp);
+ modelMatrix.scale(QVector3D(m_rowWidth / m_scaleFactor, gridLineWidth,
+ gridLineWidth));
+ itModelMatrix.scale(QVector3D(m_rowWidth / m_scaleFactor, gridLineWidth,
+ gridLineWidth));
+ // If we're viewing from below, grid line object must be flipped
+ if (m_yFlipped)
+ modelMatrix.rotate(180.0f, 1.0, 0.0, 0.0);
+
+ MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
+ depthMVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
+
+ // Set the rest of the shader bindings
+ m_barShader->setUniformValue(m_barShader->model(), modelMatrix);
+ m_barShader->setUniformValue(m_barShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ m_barShader->setUniformValue(m_barShader->MVP(), MVPMatrix);
+
+#if !defined(QT_OPENGL_ES_2)
+ if (m_cachedShadowQuality > QDataVis::ShadowNone) {
+ // Set shadow shader bindings
+ m_barShader->setUniformValue(m_barShader->shadowQ(), m_shadowQualityToShader);
+ m_barShader->setUniformValue(m_barShader->depth(), depthMVPMatrix);
+ m_barShader->setUniformValue(m_barShader->lightS(),
+ m_cachedTheme.m_lightStrength / 10.0f);
+
+ // Draw the object
+ m_drawer->drawObject(m_barShader, m_gridLineObj, 0, m_depthTexture);
+ } else
+#endif
+ {
+ // Set shadowless shader bindings
+ m_barShader->setUniformValue(m_barShader->lightS(), m_cachedTheme.m_lightStrength);
+
+ // Draw the object
+ m_drawer->drawObject(m_barShader, m_gridLineObj);
+ }
+ }
+
+ // Floor lines: columns
+ for (GLfloat bar = 0.0f; bar <= m_cachedColumnCount; bar++) {
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+ QMatrix4x4 depthMVPMatrix;
+ QMatrix4x4 itModelMatrix;
+
+ barPos = (bar + 0.5f) * (m_cachedBarSpacing.width());
+ modelMatrix.translate((m_rowWidth - barPos) / m_scaleFactor,
+ -m_yAdjustment, zComp);
+ modelMatrix.scale(QVector3D(gridLineWidth, gridLineWidth,
+ m_columnDepth / m_scaleFactor));
+ itModelMatrix.scale(QVector3D(gridLineWidth, gridLineWidth,
+ m_columnDepth / m_scaleFactor));
+
+ // If we're viewing from below, grid line object must be flipped
+ if (m_yFlipped)
+ modelMatrix.rotate(180.0f, 1.0, 0.0, 0.0);
+
+ MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
+ depthMVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
+
+ // Set the rest of the shader bindings
+ m_barShader->setUniformValue(m_barShader->model(), modelMatrix);
+ m_barShader->setUniformValue(m_barShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ m_barShader->setUniformValue(m_barShader->MVP(), MVPMatrix);
+
+#if !defined(QT_OPENGL_ES_2)
+ if (m_cachedShadowQuality > QDataVis::ShadowNone) {
+ // Set shadow shader bindings
+ m_barShader->setUniformValue(m_barShader->shadowQ(), m_shadowQualityToShader);
+ m_barShader->setUniformValue(m_barShader->depth(), depthMVPMatrix);
+ m_barShader->setUniformValue(m_barShader->lightS(),
+ m_cachedTheme.m_lightStrength / 10.0f);
+
+ // Draw the object
+ m_drawer->drawObject(m_barShader, m_gridLineObj, 0, m_depthTexture);
+ } else
+#endif
+ {
+ // Set shadowless shader bindings
+ m_barShader->setUniformValue(m_barShader->lightS(), m_cachedTheme.m_lightStrength);
+
+ // Draw the object
+ m_drawer->drawObject(m_barShader, m_gridLineObj);
+ }
+ }
+
+ if (m_axisCacheY.segmentCount() > 0) {
+ // Wall lines: back wall
+ GLfloat heightStep = m_axisCacheY.subSegmentStep();
+ GLfloat startLine = 0.0f;
+
+ if (m_hasNegativeValues)
+ startLine = -m_heightNormalizer;
+
+ for (GLfloat lineHeight = startLine; lineHeight <= m_heightNormalizer;
+ lineHeight += heightStep) {
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+ QMatrix4x4 depthMVPMatrix;
+ QMatrix4x4 itModelMatrix;
+
+ if (m_zFlipped) {
+ modelMatrix.translate(0.0f,
+ 2.0f * lineHeight / m_heightNormalizer - m_yAdjustment,
+ m_columnDepth / m_scaleFactor + zComp);
+ } else {
+ modelMatrix.translate(0.0f,
+ 2.0f * lineHeight / m_heightNormalizer - m_yAdjustment,
+ -m_columnDepth / m_scaleFactor + zComp);
+ }
+ modelMatrix.scale(QVector3D(m_rowWidth / m_scaleFactor, gridLineWidth,
+ gridLineWidth));
+ itModelMatrix.scale(QVector3D(m_rowWidth / m_scaleFactor, gridLineWidth,
+ gridLineWidth));
+
+ MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
+ depthMVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
+
+ // Set the rest of the shader bindings
+ m_barShader->setUniformValue(m_barShader->model(), modelMatrix);
+ m_barShader->setUniformValue(m_barShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ m_barShader->setUniformValue(m_barShader->MVP(), MVPMatrix);
+
+#if !defined(QT_OPENGL_ES_2)
+ if (m_cachedShadowQuality > QDataVis::ShadowNone) {
+ // Set shadow shader bindings
+ m_barShader->setUniformValue(m_barShader->shadowQ(), m_shadowQualityToShader);
+ m_barShader->setUniformValue(m_barShader->depth(), depthMVPMatrix);
+ m_barShader->setUniformValue(m_barShader->lightS(),
+ m_cachedTheme.m_lightStrength / 10.0f);
+
+ // Draw the object
+ m_drawer->drawObject(m_barShader, m_gridLineObj, 0, m_depthTexture);
+ } else
+#endif
+ {
+ // Set shadowless shader bindings
+ m_barShader->setUniformValue(m_barShader->lightS(), m_cachedTheme.m_lightStrength);
+
+ // Draw the object
+ m_drawer->drawObject(m_barShader, m_gridLineObj);
+ }
+ }
+
+ // Wall lines: side wall
+ for (GLfloat lineHeight = startLine; lineHeight <= m_heightNormalizer;
+ lineHeight += heightStep) {
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+ QMatrix4x4 depthMVPMatrix;
+ QMatrix4x4 itModelMatrix;
+
+ if (m_xFlipped) {
+ modelMatrix.translate(m_rowWidth / m_scaleFactor,
+ 2.0f * lineHeight / m_heightNormalizer - m_yAdjustment,
+ zComp);
+ } else {
+ modelMatrix.translate(-m_rowWidth / m_scaleFactor,
+ 2.0f * lineHeight / m_heightNormalizer - m_yAdjustment,
+ zComp);
+ }
+ modelMatrix.scale(QVector3D(gridLineWidth, gridLineWidth,
+ m_columnDepth / m_scaleFactor));
+ itModelMatrix.scale(QVector3D(gridLineWidth, gridLineWidth,
+ m_columnDepth / m_scaleFactor));
+
+ MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
+ depthMVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
+
+ // Set the rest of the shader bindings
+ m_barShader->setUniformValue(m_barShader->model(), modelMatrix);
+ m_barShader->setUniformValue(m_barShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ m_barShader->setUniformValue(m_barShader->MVP(), MVPMatrix);
+
+#if !defined(QT_OPENGL_ES_2)
+ if (m_cachedShadowQuality > QDataVis::ShadowNone) {
+ // Set shadow shader bindings
+ m_barShader->setUniformValue(m_barShader->shadowQ(), m_shadowQualityToShader);
+ m_barShader->setUniformValue(m_barShader->depth(), depthMVPMatrix);
+ m_barShader->setUniformValue(m_barShader->lightS(),
+ m_cachedTheme.m_lightStrength / 10.0f);
+
+ // Draw the object
+ m_drawer->drawObject(m_barShader, m_gridLineObj, 0, m_depthTexture);
+ } else
+#endif
+ {
+ // Set shadowless shader bindings
+ m_barShader->setUniformValue(m_barShader->lightS(), m_cachedTheme.m_lightStrength);
+
+ // Draw the object
+ m_drawer->drawObject(m_barShader, m_gridLineObj);
+ }
+ }
+ }
+ // Release bar shader
+ m_barShader->release();
+ }
+
+ // Generate label textures for slice selection if m_updateLabels is set
+ if (m_cachedIsSlicingActivated && m_updateLabels) {
+ // Create label textures
+ for (int col = 0; col < m_sliceSelection->size(); col++) {
+ BarRenderItem *item = m_sliceSelection->at(col);
+ m_drawer->generateLabelTexture(item);
+ }
+ }
+
+ // Handle slice activation and label drawing
+ if (!barSelectionFound) {
+ // We have no ownership, don't delete. Just NULL the pointer.
+ m_selectedBar = NULL;
+ if (m_cachedIsSlicingActivated
+ && Bars3dController::MouseOnOverview == m_controller->mouseState())
+ m_controller->setSlicingActive(false);
+ } else if (m_cachedSelectionMode >= QDataVis::ModeZoomRow
+ && Bars3dController::MouseOnScene == m_controller->mouseState()) {
+ // Activate slice mode
+ m_controller->setSlicingActive(true);
+
+ // Create label textures
+ for (int col = 0; col < m_sliceSelection->size(); col++) {
+ BarRenderItem *item = m_sliceSelection->at(col);
+ m_drawer->generateLabelTexture(item);
+ }
+ } else {
+ // Print value of selected bar
+ m_labelShader->bind();
+ glDisable(GL_DEPTH_TEST);
+ glEnable(GL_TEXTURE_2D);
+ if (m_cachedLabelTransparency > QDataVis::TransparencyNone) {
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ }
+#ifndef DISPLAY_FULL_DATA_ON_SELECTION
+ // Draw just the value string of the selected bar
+ if (m_previouslySelectedBar != m_selectedBar || m_updateLabels) {
+ m_drawer->generateLabelTexture(m_selectedBar);
+ m_previouslySelectedBar = m_selectedBar;
+ }
+
+ m_drawer->drawLabel(*m_selectedBar, m_selectedBar->labelItem(),
+ viewMatrix, projectionMatrix,
+ QVector3D(0.0f, m_yAdjustment, zComp),
+ QVector3D(0.0f, 0.0f, 0.0f), m_selectedBar->height(),
+ m_cachedSelectionMode, m_labelShader,
+ m_labelObj, true);
+#else
+ // Draw the value string followed by row label and column label
+ LabelItem &labelItem = m_selectedBar->selectionLabel();
+ if (m_previouslySelectedBar != m_selectedBar || m_updateLabels || !labelItem.textureId()) {
+ QString labelText = m_selectedBar->label();
+ if ((m_axisCacheZ.labels().size() > m_selectedBar->position().y())
+ && (m_axisCacheX.labels().size() > m_selectedBar->position().x())) {
+ labelText.append(QStringLiteral(" ("));
+ labelText.append(m_axisCacheX.labels().at(m_selectedBar->position().x()));
+ labelText.append(QStringLiteral(", "));
+ labelText.append(m_axisCacheZ.labels().at(m_selectedBar->position().y()));
+ labelText.append(QStringLiteral(")"));
+ //qDebug() << labelText;
+ }
+ m_drawer->generateLabelItem(labelItem, labelText);
+ m_previouslySelectedBar = m_selectedBar;
+ }
+
+ m_drawer->drawLabel(*m_selectedBar, labelItem, viewMatrix, projectionMatrix,
+ QVector3D(0.0f, m_yAdjustment, zComp),
+ QVector3D(0.0f, 0.0f, 0.0f), m_selectedBar->height(),
+ m_cachedSelectionMode, m_labelShader,
+ m_labelObj, camera, true, false);
+#endif
+ glDisable(GL_TEXTURE_2D);
+ if (m_cachedLabelTransparency > QDataVis::TransparencyNone)
+ glDisable(GL_BLEND);
+ glEnable(GL_DEPTH_TEST);
+
+ // Release label shader
+ m_labelShader->release();
+
+ // Reset label update flag; they should have been updated when we get here
+ m_updateLabels = false;
+ }
+
+ // TODO: Calculations done temporarily here. When optimizing, move to after data set addition? Keep drawing of the labels here.
+ // Bind label shader
+ m_labelShader->bind();
+
+ glEnable(GL_TEXTURE_2D);
+ if (m_cachedLabelTransparency > QDataVis::TransparencyNone) {
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ }
+
+ // Calculate the positions for row and column labels and store them
+ for (int row = 0; row != m_cachedRowCount; row++) {
+ if (m_axisCacheX.labelItems().size() > row) {
+ // Go through all rows and get position of max+1 or min-1 column, depending on x flip
+ // We need only positions for them, labels have already been generated at QDataSetPrivate. Just add LabelItems
+ rowPos = (row + 1) * (m_cachedBarSpacing.height());
+ barPos = m_rowWidth;
+ GLfloat rotLabelX = -90.0f;
+ GLfloat rotLabelY = 0.0f;
+ GLfloat rotLabelZ = 0.0f;
+ Qt::AlignmentFlag alignment = Qt::AlignRight;
+ if (m_zFlipped)
+ rotLabelY = 180.0f;
+ if (m_xFlipped) {
+ barPos = -m_rowWidth;
+ alignment = Qt::AlignLeft;
+ }
+ if (m_yFlipped) {
+ if (m_zFlipped)
+ rotLabelY = 0.0f;
+ else
+ rotLabelY = 180.0f;
+ rotLabelZ = 180.0f;
+ }
+ QVector3D labelPos = QVector3D(barPos / m_scaleFactor,
+ -m_yAdjustment + 0.005f, // raise a bit over background to avoid depth "glimmering"
+ (m_columnDepth - rowPos) / m_scaleFactor + zComp);
+
+ m_dummyBarRenderItem.setTranslation(labelPos);
+ const LabelItem &axisLabelItem = *m_axisCacheX.labelItems().at(row);
+ //qDebug() << "labelPos, row" << row + 1 << ":" << labelPos << m_axisCacheX.labels().at(row);
+
+ m_drawer->drawLabel(m_dummyBarRenderItem, axisLabelItem, viewMatrix, projectionMatrix,
+ QVector3D(0.0f, m_yAdjustment, zComp),
+ QVector3D(rotLabelX, rotLabelY, rotLabelZ),
+ 0, m_cachedSelectionMode,
+ m_labelShader, m_labelObj, camera, true, true, Drawer::LabelMid,
+ alignment);
+ }
+
+ }
+ for (int bar = 0; bar != m_cachedColumnCount; bar += 1) {
+ if (m_axisCacheZ.labelItems().size() > bar) {
+ // Go through all columns and get position of max+1 or min-1 row, depending on z flip
+ // We need only positions for them, labels have already been generated at QDataSetPrivate. Just add LabelItems
+ barPos = (bar + 1) * (m_cachedBarSpacing.width());
+ rowPos = m_columnDepth;
+ GLfloat rotLabelX = -90.0f;
+ GLfloat rotLabelY = 90.0f;
+ GLfloat rotLabelZ = 0.0f;
+ Qt::AlignmentFlag alignment = Qt::AlignLeft;
+ if (m_xFlipped)
+ rotLabelY = -90.0f;
+ if (m_zFlipped) {
+ rowPos = -m_columnDepth;
+ alignment = Qt::AlignRight;
+ }
+ if (m_yFlipped) {
+ if (m_xFlipped)
+ rotLabelY = -90.0f;
+ else
+ rotLabelY = 90.0f;
+ rotLabelZ = 180.0f;
+ }
+ QVector3D labelPos = QVector3D((m_rowWidth - barPos) / m_scaleFactor,
+ -m_yAdjustment + 0.005f, // raise a bit over background to avoid depth "glimmering"
+ rowPos / m_scaleFactor + zComp);
+
+ // TODO: Try it; draw the label here
+
+ m_dummyBarRenderItem.setTranslation(labelPos);
+ const LabelItem &axisLabelItem = *m_axisCacheZ.labelItems().at(bar);
+ //qDebug() << "labelPos, col" << bar + 1 << ":" << labelPos << m_axisCacheZ.labels().at(bar);
+
+ m_drawer->drawLabel(m_dummyBarRenderItem, axisLabelItem, viewMatrix, projectionMatrix,
+ QVector3D(0.0f, m_yAdjustment, zComp),
+ QVector3D(rotLabelX, rotLabelY, rotLabelZ),
+ 0, m_cachedSelectionMode,
+ m_labelShader, m_labelObj, camera, true, true, Drawer::LabelMid,
+ alignment);
+ }
+ }
+
+ // Y Labels
+ int labelNbr = 0;
+ GLfloat heightStep = m_axisCacheY.segmentStep();
+ GLfloat startLine = 0.0f;
+ int labelCount = m_axisCacheY.labels().size();
+ if (m_hasNegativeValues)
+ startLine = -m_heightNormalizer;
+ GLfloat labelPos = startLine;
+
+ for (int i = 0; i < labelCount; i++) {
+ if (m_axisCacheY.labelItems().size() > labelNbr) {
+ GLfloat labelXTrans = m_rowWidth / m_scaleFactor;
+ GLfloat labelZTrans = m_columnDepth / m_scaleFactor;
+ GLfloat labelYTrans = 2.0f * labelPos / m_heightNormalizer - m_yAdjustment;
+ GLfloat rotLabelX = 0.0f;
+ GLfloat rotLabelY = -90.0f;
+ GLfloat rotLabelZ = 0.0f;
+ Qt::AlignmentFlag alignment = Qt::AlignLeft;
+ if (!m_xFlipped) {
+ labelXTrans = -labelXTrans;
+ rotLabelY = 90.0f;
+ }
+ if (m_zFlipped) {
+ labelZTrans = -labelZTrans;
+ alignment = Qt::AlignRight;
+ }
+
+ const LabelItem &axisLabelItem = *m_axisCacheY.labelItems().at(labelNbr);
+
+ // Back wall
+ QVector3D labelTrans = QVector3D(labelXTrans, labelYTrans, labelZTrans + zComp);
+
+ //qDebug() << "labelPos, value:" << labelTrans;
+
+ m_dummyBarRenderItem.setTranslation(labelTrans);
+ m_drawer->drawLabel(m_dummyBarRenderItem, axisLabelItem, viewMatrix, projectionMatrix,
+ QVector3D(0.0f, m_yAdjustment, zComp),
+ QVector3D(rotLabelX, rotLabelY, rotLabelZ),
+ 0, m_cachedSelectionMode,
+ m_labelShader, m_labelObj, camera, true, true, Drawer::LabelMid,
+ alignment);
+
+ // Side wall
+ if (m_xFlipped)
+ alignment = Qt::AlignLeft;
+ else
+ alignment = Qt::AlignRight;
+ if (m_zFlipped)
+ rotLabelY = 180.0f;
+ else
+ rotLabelY = 0.0f;
+
+ labelTrans = QVector3D(-labelXTrans, labelYTrans, -labelZTrans + zComp);
+
+ m_dummyBarRenderItem.setTranslation(labelTrans);
+ m_drawer->drawLabel(m_dummyBarRenderItem, axisLabelItem, viewMatrix, projectionMatrix,
+ QVector3D(0.0f, m_yAdjustment, zComp),
+ QVector3D(rotLabelX, rotLabelY, rotLabelZ),
+ 0, m_cachedSelectionMode,
+ m_labelShader, m_labelObj, camera, true, true, Drawer::LabelMid,
+ alignment);
+ }
+ labelNbr++;
+ labelPos += heightStep;
+ }
+
+ glDisable(GL_TEXTURE_2D);
+ if (m_cachedLabelTransparency > QDataVis::TransparencyNone)
+ glDisable(GL_BLEND);
+
+ // Release label shader
+ m_labelShader->release();
+}
+
+void Bars3dRenderer::requestSelectionAtPoint(const QPoint &point)
+{
+ QMutexLocker locker(&m_mutex);
+ m_selectionPointRequest.setX(point.x());
+ m_selectionPointRequest.setY(point.y());
+ m_isSelectionPointRequestActive = true;
+}
+
+void Bars3dRenderer::handleResize()
+{
+ if (m_cachedBoundingRect.width() == 0 || m_cachedBoundingRect.height() == 0)
+ return;
+
+ // Set view port
+ if (m_cachedIsSlicingActivated) {
+ m_mainViewPort = QRect(0,
+ m_cachedBoundingRect.height() - m_cachedBoundingRect.height() / 5,
+ m_cachedBoundingRect.width() / 5,
+ m_cachedBoundingRect.height() / 5);
+ } else {
+ m_mainViewPort = QRect(0, 0, m_cachedBoundingRect.width(), m_cachedBoundingRect.height());
+ }
+ m_sliceViewPort = QRect(0, 0, m_cachedBoundingRect.width(), m_cachedBoundingRect.height());
+
+ Abstract3DRenderer::handleResize();
+}
+
+void Bars3dRenderer::updateBarSpecs(QSizeF thickness, QSizeF spacing, bool relative)
+{
+ m_cachedBarThickness = thickness;
+ if (relative) {
+ m_cachedBarSpacing.setWidth((thickness.width() * 2) * (spacing.width() + 1.0f));
+ m_cachedBarSpacing.setHeight((thickness.height() * 2) * (spacing.height() + 1.0f));
+ } else {
+ m_cachedBarSpacing = thickness * 2 + spacing * 2;
+ }
+
+ // Calculate here and at setting sample space
+ calculateSceneScalingFactors();
+}
+
+void Bars3dRenderer::updateMeshFileName(const QString &objFileName)
+{
+ Abstract3DRenderer::updateMeshFileName(objFileName);
+ loadBarMesh();
+}
+
+void Bars3dRenderer::updateAxisRange(QAbstractAxis::AxisOrientation orientation, qreal min, qreal max)
+{
+ Abstract3DRenderer::updateAxisRange(orientation, min, max);
+ calculateHeightAdjustment();
+
+ // Check if we have negative values
+ if (min < 0 && !m_hasNegativeValues) {
+ m_hasNegativeValues = true;
+ // Reload background
+ loadBackgroundMesh();
+ } else if (min >= 0 && m_hasNegativeValues) {
+ m_hasNegativeValues = false;
+ // Reload background
+ loadBackgroundMesh();
+ }
+
+ // TODO Currently barchart only supports zero centered or zero minimum ranges
+ if (min > 0.0 || (min != 0.0 && (qFabs(min) != qFabs(max))))
+ qWarning() << __FUNCTION__ << "Bar chart currently properly supports only zero-centered and zero minimum ranges for Y-axis.";
+}
+
+void Bars3dRenderer::updateSampleSpace(int rowCount, int columnCount)
+{
+ // Destroy old render items and reallocate new array
+ // TODO is there a way to allocate the whole array with one allocation?
+ m_renderItemArray.clear();
+ m_renderItemArray.resize(rowCount);
+ for (int i = 0; i < rowCount; i++) {
+ m_renderItemArray[i].resize(columnCount);
+ for (int j = 0; j < columnCount; j++)
+ m_renderItemArray[i][j].setRenderer(this);
+ }
+
+ // Force update for selection related items
+ m_sliceCache = 0;
+ m_sliceTitleItem = 0;
+ if (m_sliceSelection)
+ m_sliceSelection->clear();
+
+ m_cachedColumnCount = columnCount;
+ m_cachedRowCount = rowCount;
+ // TODO: Invent "idiotproof" max scene size formula..
+ // This seems to work ok if spacing is not negative (and row/column or column/row ratio is not too high)
+ m_maxSceneSize = 2 * qSqrt(columnCount * rowCount);
+ //qDebug() << "maxSceneSize" << m_maxSceneSize;
+ // Calculate here and at setting bar specs
+ calculateSceneScalingFactors();
+}
+
+void Bars3dRenderer::updateSelectionMode(QDataVis::SelectionMode mode)
+{
+ Abstract3DRenderer::updateSelectionMode(mode);
+
+ // Create zoom selection if there isn't one
+ if (mode >= QDataVis::ModeZoomRow && !m_sliceSelection) {
+ m_sliceSelection = new QList<BarRenderItem *>;
+ if (mode == QDataVis::ModeZoomRow)
+ m_sliceSelection->reserve(m_cachedRowCount);
+ else
+ m_sliceSelection->reserve(m_cachedColumnCount);
+ }
+}
+
+void Bars3dRenderer::updateBackgroundEnabled(bool enable)
+{
+ if (enable != m_cachedIsBackgroundEnabled) {
+ Abstract3DRenderer::updateBackgroundEnabled(enable);
+ loadBarMesh(); // Load changed bar type
+ }
+}
+
+void Bars3dRenderer::updateShadowQuality(QDataVis::ShadowQuality quality)
+{
+ qDebug() << "Bars3dRenderer::setShadowQuality" << quality;
+ m_cachedShadowQuality = quality;
+ switch (quality) {
+ case QDataVis::ShadowLow:
+ m_shadowQualityToShader = 33.3f;
+ break;
+ case QDataVis::ShadowMedium:
+ m_shadowQualityToShader = 100.0f;
+ break;
+ case QDataVis::ShadowHigh:
+ m_shadowQualityToShader = 200.0f;
+ break;
+ default:
+ m_shadowQualityToShader = 0.0f;
+ break;
+ }
+#if !defined(QT_OPENGL_ES_2)
+ if (m_cachedShadowQuality > QDataVis::ShadowNone) {
+ // Re-init shaders
+ if (!m_cachedTheme.m_uniformColor) {
+ initShaders(QStringLiteral(":/shaders/vertexShadow"),
+ QStringLiteral(":/shaders/fragmentShadowNoTexColorOnY"));
+ } else {
+ initShaders(QStringLiteral(":/shaders/vertexShadow"),
+ QStringLiteral(":/shaders/fragmentShadowNoTex"));
+ }
+ initBackgroundShaders(QStringLiteral(":/shaders/vertexShadow"),
+ QStringLiteral(":/shaders/fragmentShadowNoTex"));
+ } else {
+ // Re-init shaders
+ if (!m_cachedTheme.m_uniformColor) {
+ initShaders(QStringLiteral(":/shaders/vertex"),
+ QStringLiteral(":/shaders/fragmentColorOnY"));
+ } else {
+ initShaders(QStringLiteral(":/shaders/vertex"),
+ QStringLiteral(":/shaders/fragment"));
+ }
+ initBackgroundShaders(QStringLiteral(":/shaders/vertex"),
+ QStringLiteral(":/shaders/fragment"));
+ }
+ // Re-init depth buffer
+ updateDepthBuffer();
+#else
+ if (!m_cachedTheme.m_uniformColor) {
+ initShaders(QStringLiteral(":/shaders/vertexES2"),
+ QStringLiteral(":/shaders/fragmentColorOnYES2"));
+ } else {
+ initShaders(QStringLiteral(":/shaders/vertexES2"),
+ QStringLiteral(":/shaders/fragmentES2"));
+ }
+ initBackgroundShaders(QStringLiteral(":/shaders/vertexES2"),
+ QStringLiteral(":/shaders/fragmentES2"));
+#endif
+}
+
+void Bars3dRenderer::loadBarMesh()
+{
+ QString objectFileName = m_cachedObjFile;
+ if (m_barObj)
+ delete m_barObj;
+ // If background is disabled, load full version of bar mesh
+ if (!m_cachedIsBackgroundEnabled)
+ objectFileName.append(QStringLiteral("Full"));
+ m_barObj = new ObjectHelper(objectFileName);
+ m_barObj->load();
+}
+
+void Bars3dRenderer::loadBackgroundMesh()
+{
+ if (m_backgroundObj)
+ delete m_backgroundObj;
+ if (m_hasNegativeValues)
+ m_backgroundObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/negativeBackground"));
+ else
+ m_backgroundObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/background"));
+ m_backgroundObj->load();
+}
+
+void Bars3dRenderer::loadGridLineMesh()
+{
+ if (m_gridLineObj)
+ delete m_gridLineObj;
+ m_gridLineObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/bar"));
+ m_gridLineObj->load();
+}
+
+void Bars3dRenderer::loadLabelMesh()
+{
+ if (m_labelObj)
+ delete m_labelObj;
+ m_labelObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/label"));
+ m_labelObj->load();
+}
+
+void Bars3dRenderer::updateTextures()
+{
+ // Drawer has changed; this flag needs to be checked when checking if we need to update labels
+ m_updateLabels = true;
+}
+
+void Bars3dRenderer::calculateSceneScalingFactors()
+{
+ // Calculate scene scaling and translation factors
+ m_rowWidth = ((m_cachedColumnCount + 1) * m_cachedBarSpacing.width()) / 2.0f;
+ m_columnDepth = ((m_cachedRowCount + 1) * m_cachedBarSpacing.height()) / 2.0f;
+ m_maxDimension = qMax(m_rowWidth, m_columnDepth);
+ m_scaleFactor = qMin((m_cachedColumnCount * (m_maxDimension / m_maxSceneSize)),
+ (m_cachedRowCount * (m_maxDimension / m_maxSceneSize)));
+ m_scaleX = m_cachedBarThickness.width() / m_scaleFactor;
+ m_scaleZ = m_cachedBarThickness.height() / m_scaleFactor;
+ //qDebug() << "m_scaleX" << m_scaleX << "m_scaleFactor" << m_scaleFactor;
+ //qDebug() << "m_scaleZ" << m_scaleZ << "m_scaleFactor" << m_scaleFactor;
+ //qDebug() << "m_rowWidth:" << m_rowWidth << "m_columnDepth:" << m_columnDepth << "m_maxDimension:" << m_maxDimension;
+}
+
+void Bars3dRenderer::calculateHeightAdjustment()
+{
+ m_heightNormalizer = (GLfloat)qMax(qFabs(m_axisCacheY.min()), qFabs(m_axisCacheY.max()));
+
+ // 2.0f = max difference between minimum and maximum value after scaling with m_heightNormalizer
+ GLfloat newAdjustment = 2.0f - ((m_heightNormalizer - m_axisCacheY.min()) / m_heightNormalizer);
+ if (newAdjustment != m_yAdjustment) {
+ m_hasHeightAdjustmentChanged = true;
+ m_yAdjustment = newAdjustment;
+ }
+ //qDebug() << m_yAdjustment;
+}
+
+Bars3dController::SelectionType Bars3dRenderer::isSelected(GLint row, GLint bar)
+{
+ //static QVector3D prevSel = m_selection; // TODO: For debugging
+ Bars3dController::SelectionType isSelectedType = Bars3dController::SelectionNone;
+ if (m_selection == selectionSkipColor)
+ return isSelectedType; // skip window
+
+ //#if !defined(QT_OPENGL_ES_2)
+ // QVector3D current = QVector3D((GLuint)row, (GLuint)bar, 0);
+ //#else
+ QVector3D current = QVector3D((GLubyte)row, (GLubyte)bar, 0);
+ //#endif
+
+ // TODO: For debugging
+ //if (selection != prevSel) {
+ // qDebug() << "current" << current.x() << current .y() << current.z();
+ // qDebug() << "selection" << selection.x() << selection .y() << selection.z();
+ // prevSel = selection;
+ //}
+ if (current == m_selection) {
+ isSelectedType = Bars3dController::SelectionItem;
+ }
+ else if (current.y() == m_selection.y() && (m_cachedSelectionMode == QDataVis::ModeItemAndColumn
+ || m_cachedSelectionMode == QDataVis::ModeItemRowAndColumn
+ || m_cachedSelectionMode == QDataVis::ModeZoomColumn)) {
+ isSelectedType = Bars3dController::SelectionColumn;
+ }
+ else if (current.x() == m_selection.x() && (m_cachedSelectionMode == QDataVis::ModeItemAndRow
+ || m_cachedSelectionMode == QDataVis::ModeItemRowAndColumn
+ || m_cachedSelectionMode == QDataVis::ModeZoomRow)) {
+ isSelectedType = Bars3dController::SelectionRow;
+ }
+ return isSelectedType;
+}
+
+void Bars3dRenderer::updateSlicingActive(bool isSlicing)
+{
+ m_cachedIsSlicingActivated = isSlicing;
+ if (isSlicing) {
+ m_mainViewPort = QRect(0, m_cachedBoundingRect.height() - m_cachedBoundingRect.height() / 5,
+ m_cachedBoundingRect.width() / 5, m_cachedBoundingRect.height() / 5);
+ } else {
+ m_mainViewPort = QRect(0, 0, this->m_cachedBoundingRect.width(),
+ this->m_cachedBoundingRect.height());
+ }
+}
+
+QRect Bars3dRenderer::mainViewPort()
+{
+ return m_mainViewPort;
+}
+
+void Bars3dRenderer::initShaders(const QString &vertexShader, const QString &fragmentShader)
+{
+ if (m_barShader)
+ delete m_barShader;
+ m_barShader = new ShaderHelper(this, vertexShader, fragmentShader);
+ m_barShader->initialize();
+}
+
+void Bars3dRenderer::initSelectionShader()
+{
+ if (m_selectionShader)
+ delete m_selectionShader;
+ m_selectionShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexSelection"),
+ QStringLiteral(":/shaders/fragmentSelection"));
+ m_selectionShader->initialize();
+}
+
+void Bars3dRenderer::initSelectionBuffer()
+{
+ if (m_selectionTexture)
+ m_textureHelper->deleteTexture(&m_selectionTexture);
+
+ m_selectionTexture = m_textureHelper->createSelectionTexture(m_mainViewPort.size(),
+ m_selectionFrameBuffer,
+ m_selectionDepthBuffer);
+}
+
+#if !defined(QT_OPENGL_ES_2)
+void Bars3dRenderer::initDepthShader()
+{
+ if (m_depthShader)
+ delete m_depthShader;
+ m_depthShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexDepth"),
+ QStringLiteral(":/shaders/fragmentDepth"));
+ m_depthShader->initialize();
+}
+
+void Bars3dRenderer::updateDepthBuffer()
+{
+ if (m_depthTexture) {
+ m_textureHelper->deleteTexture(&m_depthTexture);
+ m_depthTexture = 0;
+ }
+
+ if (m_cachedShadowQuality > QDataVis::ShadowNone) {
+ m_depthTexture = m_textureHelper->createDepthTexture(m_mainViewPort.size(),
+ m_depthFrameBuffer,
+ m_cachedShadowQuality);
+ if (!m_depthTexture) {
+ switch (m_cachedShadowQuality) {
+ case QDataVis::ShadowHigh:
+ qWarning("Creating high quality shadows failed. Changing to medium quality.");
+ (void)m_controller->setShadowQuality(QDataVis::ShadowMedium);
+ break;
+ case QDataVis::ShadowMedium:
+ qWarning("Creating medium quality shadows failed. Changing to low quality.");
+ (void)m_controller->setShadowQuality(QDataVis::ShadowLow);
+ break;
+ case QDataVis::ShadowLow:
+ qWarning("Creating low quality shadows failed. Switching shadows off.");
+ (void)m_controller->setShadowQuality(QDataVis::ShadowNone);
+ break;
+ default:
+ // You'll never get here
+ break;
+ }
+ }
+ }
+}
+#endif
+
+void Bars3dRenderer::initBackgroundShaders(const QString &vertexShader,
+ const QString &fragmentShader)
+{
+ if (m_backgroundShader)
+ delete m_backgroundShader;
+ m_backgroundShader = new ShaderHelper(this, vertexShader, fragmentShader);
+ m_backgroundShader->initialize();
+}
+
+void Bars3dRenderer::initLabelShaders(const QString &vertexShader, const QString &fragmentShader)
+{
+ if (m_labelShader)
+ delete m_labelShader;
+ m_labelShader = new ShaderHelper(this, vertexShader, fragmentShader);
+ m_labelShader->initialize();
+}
+
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/engine/bars3drenderer_p.h b/src/datavis3d/engine/bars3drenderer_p.h
new file mode 100644
index 00000000..93d47cf1
--- /dev/null
+++ b/src/datavis3d/engine/bars3drenderer_p.h
@@ -0,0 +1,200 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Q3DBARSRENDERER_p_H
+#define Q3DBARSRENDERER_p_H
+
+#include <QtCore/QSize>
+#include <QtCore/QObject>
+#include <QtGui/QOpenGLFunctions>
+#include <QtGui/QFont>
+#include <QTime>
+#include <QWindow>
+#include <QMutex>
+
+#include "datavis3dglobal_p.h"
+#include "bars3dcontroller_p.h"
+#include "abstract3drenderer_p.h"
+#include "qbardataproxy.h"
+#include "barrenderitem_p.h"
+
+//#define DISPLAY_RENDER_SPEED
+
+class QPoint;
+class QSizeF;
+class QOpenGLShaderProgram;
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class ShaderHelper;
+class ObjectHelper;
+class TextureHelper;
+class Theme;
+class Drawer;
+class LabelItem;
+class CameraHelper;
+
+class QT_DATAVIS3D_EXPORT Bars3dRenderer : public Abstract3DRenderer
+{
+ Q_OBJECT
+
+private:
+ // TODO: Filter to the set of attributes to be moved to the model object.
+ Bars3dController *m_controller;
+
+ // Mutex for sharing resources between render and main threads.
+ // TODO this mutex needs to go, too...
+ QMutex m_mutex;
+
+ // Cached state based on emitted signals from the controller
+ QSizeF m_cachedBarThickness;
+ QSizeF m_cachedBarSpacing;
+ bool m_cachedIsSlicingActivated;
+ int m_cachedRowCount;
+ int m_cachedColumnCount;
+
+ // Internal state
+ BarRenderItem *m_selectedBar; // points to renderitem array
+ BarRenderItem *m_previouslySelectedBar; // points to renderitem array
+ QList<BarRenderItem *> *m_sliceSelection;
+ AxisRenderCache *m_sliceCache; // not owned
+ const LabelItem *m_sliceTitleItem; // not owned
+ bool m_xFlipped;
+ bool m_zFlipped;
+ bool m_yFlipped;
+ QRect m_mainViewPort;
+ QRect m_sliceViewPort;
+ bool m_updateLabels;
+ ShaderHelper *m_barShader;
+ ShaderHelper *m_depthShader;
+ ShaderHelper *m_selectionShader;
+ ShaderHelper *m_backgroundShader;
+ ShaderHelper *m_labelShader;
+ ObjectHelper *m_barObj;
+ ObjectHelper *m_backgroundObj;
+ ObjectHelper *m_gridLineObj;
+ ObjectHelper *m_labelObj;
+ TextureHelper *m_textureHelper;
+ GLuint m_bgrTexture;
+ GLuint m_depthTexture;
+ GLuint m_selectionTexture;
+ GLuint m_depthFrameBuffer;
+ GLuint m_selectionFrameBuffer;
+ GLuint m_selectionDepthBuffer;
+ GLfloat m_shadowQualityToShader;
+ GLfloat m_heightNormalizer;
+ GLfloat m_yAdjustment;
+ GLfloat m_rowWidth;
+ GLfloat m_columnDepth;
+ GLfloat m_maxDimension;
+ GLfloat m_scaleX;
+ GLfloat m_scaleZ;
+ GLfloat m_scaleFactor;
+ GLfloat m_maxSceneSize;
+ QVector3D m_selection;
+
+ QPoint m_selectionPointRequest;
+ bool m_isSelectionPointRequestActive;
+
+ bool m_hasHeightAdjustmentChanged;
+ BarRenderItem m_dummyBarRenderItem;
+
+ BarRenderItemArray m_renderItemArray;
+
+#ifdef DISPLAY_RENDER_SPEED
+ bool m_isFirstFrame;
+ QTime m_lastFrameTime;
+ GLint m_numFrames;
+#endif
+
+public:
+ explicit Bars3dRenderer(Bars3dController *controller);
+ ~Bars3dRenderer();
+
+ void updateDataModel(QBarDataProxy *dataProxy);
+ void render(CameraHelper *camera, const GLuint defaultFboHandle = 0);
+
+ QRect mainViewPort();
+
+public slots:
+ void updateBarSpecs(QSizeF thickness = QSizeF(1.0f, 1.0f),
+ QSizeF spacing = QSizeF(1.0f, 1.0f),
+ bool relative = true);
+ void updateSelectionMode(QDataVis::SelectionMode newMode);
+ void updateSlicingActive(bool isSlicing);
+ void updateSampleSpace(int rowCount, int columnCount);
+ void updateBackgroundEnabled(bool enable);
+ void updateMeshFileName(const QString &objFileName);
+
+ // Overloaded from abstract renderer
+ virtual void updateAxisRange(QAbstractAxis::AxisOrientation orientation, qreal min, qreal max);
+
+ // Requests that upon next render pass the column and row under the given point is inspected for selection.
+ // Only one request can be queued per render pass at this point. New request will override any pending requests.
+ // After inspection the selectionUpdated signal is emitted.
+ virtual void requestSelectionAtPoint(const QPoint &point);
+
+signals:
+ void selectionUpdated(QVector3D selection);
+
+private:
+ virtual void initializeOpenGL();
+ virtual void initShaders(const QString &vertexShader, const QString &fragmentShader);
+ virtual void updateShadowQuality(QDataVis::ShadowQuality quality);
+ virtual void updateTextures();
+
+ void drawSlicedScene(CameraHelper *camera,
+ const LabelItem &xLabel, const LabelItem &yLabel, const LabelItem &zLabel);
+ void drawScene(CameraHelper *camera, const GLuint defaultFboHandle);
+ void handleResize();
+
+ void loadBarMesh();
+ void loadBackgroundMesh();
+ void loadGridLineMesh();
+ void loadLabelMesh();
+ void initSelectionShader();
+ void initBackgroundShaders(const QString &vertexShader, const QString &fragmentShader);
+ void initLabelShaders(const QString &vertexShader, const QString &fragmentShader);
+ void initSelectionBuffer();
+#if !defined(QT_OPENGL_ES_2)
+ void initDepthShader();
+ void updateDepthBuffer();
+#endif
+ void calculateSceneScalingFactors();
+ void calculateHeightAdjustment();
+ Abstract3DController::SelectionType isSelected(GLint row, GLint bar);
+
+ Q_DISABLE_COPY(Bars3dRenderer)
+
+ friend class BarRenderItem;
+};
+
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/engine/bars3dshared.cpp b/src/datavis3d/engine/bars3dshared.cpp
deleted file mode 100644
index 55efb7cc..00000000
--- a/src/datavis3d/engine/bars3dshared.cpp
+++ /dev/null
@@ -1,2421 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtDataVis3D module.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** 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 Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "bars3dshared_p.h"
-#include "camerahelper_p.h"
-#include "qdataitem_p.h"
-#include "qdatarow_p.h"
-#include "qdataset_p.h"
-#include "shaderhelper_p.h"
-#include "objecthelper_p.h"
-#include "texturehelper_p.h"
-#include "theme_p.h"
-#include "utils_p.h"
-#include "drawer_p.h"
-
-#include <QMatrix4x4>
-#include <QOpenGLPaintDevice>
-#include <QPainter>
-#include <QScreen>
-#include <QMouseEvent>
-
-#include <qmath.h>
-
-#include <QDebug>
-
-// Uncommenting this draws the shadow map with wider FOV than scene itself, making the light
-// seem to be closer to scene than it actually is. This way shadows look slightly better (to me anyway)
-#define USE_WIDER_SHADOWS
-
-// You can verify that depth buffer drawing works correctly by uncommenting this.
-// You should see the scene from where the light is
-//#define SHOW_DEPTH_TEXTURE_SCENE
-
-//#define DISPLAY_RENDER_SPEED
-
-#ifdef DISPLAY_RENDER_SPEED
-#include <QTime>
-#endif
-
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
-
-//#define USE_HAX0R_SELECTION // keep this defined until the "real" method works
-#define DISPLAY_FULL_DATA_ON_SELECTION // Append selection value text with row and column labels
-
-const GLfloat gridLineWidth = 0.005f;
-static QVector3D skipColor = QVector3D(255, 255, 255); // Selection texture's background color
-
-Bars3dShared::Bars3dShared(QRect rect, GLuint fbohandle)
- : m_boundingRect(rect.x(), rect.y(), rect.width(), rect.height()),
- m_paintDevice(0),
- m_barShader(0),
- m_depthShader(0),
- m_selectionShader(0),
- m_backgroundShader(0),
- m_labelShader(0),
- m_barObj(0),
- m_backgroundObj(0),
- m_gridLineObj(0),
- m_labelObj(0),
- m_sampleCount(0, 0),
- m_objFile(QStringLiteral(":/defaultMeshes/bar")),
- m_mousePressed(MouseNone),
- m_mousePos(QPoint(0, 0)),
- m_zoomLevel(100),
- m_zoomAdjustment(1.0f),
- m_horizontalRotation(-45.0f),
- m_verticalRotation(15.0f),
- m_barThickness(QSizeF(0.75f, 0.75f)),
- m_barSpacing(m_barThickness * 3.0f),
- m_heightNormalizer(0.0f),
- m_yAdjustment(0.0f),
- m_rowWidth(0),
- m_columnDepth(0),
- m_maxDimension(0),
- m_scaleX(0),
- m_scaleZ(0),
- m_scaleFactor(0),
- m_maxSceneSize(40.0),
- m_theme(new Theme()),
- m_isInitialized(false),
- m_selectionMode(ModeBar),
- m_selectedBar(0),
- m_zoomSelection(0),
- m_dataSet(new QDataSet()),
- m_axisLabelX(QStringLiteral("X")),
- m_axisLabelZ(QStringLiteral("Z")),
- m_axisLabelY(QStringLiteral("Y")),
- m_sceneViewPort(rect.x(), rect.y(), rect.width(), rect.height()),
- m_zoomViewPort(rect.x(), rect.y(), rect.width(), rect.height()),
- m_zoomActivated(false),
- m_labelTransparency(TransparencyFromTheme),
- m_font(QFont(QStringLiteral("Arial"))),
- m_drawer(new Drawer(*m_theme, m_font, m_labelTransparency)),
- m_xFlipped(false),
- m_zFlipped(false),
- m_yFlipped(false),
- m_bgrTexture(0),
- m_depthTexture(0),
- m_selectionTexture(0),
- m_depthFrameBuffer(0),
- m_selectionFrameBuffer(0),
- m_selectionDepthBuffer(0),
- m_updateLabels(false),
- m_gridEnabled(true),
- m_bgrEnabled(true),
- m_shadowQuality(ShadowLow),
- m_shadowQualityToShader(33.3f),
- m_tickCount(0),
- m_tickStep(0),
- m_negativeValues(false),
- m_fbohandle(fbohandle)
-{
- m_theme = new Theme();
- m_dataSet->d_ptr->setDrawer(m_drawer);
- QObject::connect(m_drawer, &Drawer::drawerChanged, this, &Bars3dShared::updateTextures);
-}
-
-Bars3dShared::~Bars3dShared()
-{
-#ifndef USE_HAX0R_SELECTION
- glDeleteFramebuffers(1, &m_selectionFrameBuffer);
- glDeleteRenderbuffers(1, &m_selectionDepthBuffer);
- m_textureHelper->deleteTexture(&m_selectionTexture);
-#endif
- glDeleteFramebuffers(1, &m_depthFrameBuffer);
- m_textureHelper->deleteTexture(&m_bgrTexture);
- delete m_dataSet;
- if (m_zoomSelection) {
- m_zoomSelection->d_ptr->clear();
- delete m_zoomSelection;
- }
- delete m_barShader;
- delete m_depthShader;
- delete m_selectionShader;
- delete m_backgroundShader;
- delete m_barObj;
- delete m_backgroundObj;
- delete m_gridLineObj;
- delete m_textureHelper;
- delete m_drawer;
-}
-
-
-void Bars3dShared::render()
-{
- if (!m_isInitialized)
- return;
-
-#ifdef DISPLAY_RENDER_SPEED
- // For speed computation
- static bool firstRender = true;
- static QTime lastTime;
- static GLint nbFrames = 0;
- if (firstRender) {
- lastTime.start();
- firstRender = false;
- }
-
- // Measure speed (as milliseconds per frame)
- nbFrames++;
- if (lastTime.elapsed() >= 1000) { // print only if last measurement was more than 1s ago
- qDebug() << qreal(lastTime.elapsed()) / qreal(nbFrames) << "ms/frame (=" << qreal(nbFrames) << "fps)";
- nbFrames = 0;
- lastTime.restart();
- }
-#endif
-
- // If zoom selection is on, draw zoom scene
- drawZoomScene();
- // Draw bars scene
- drawScene();
-}
-
-void Bars3dShared::initializeOpenGL()
-{
- // Initialization is called multiple times when Qt Quick components are used
- if (m_isInitialized)
- return;
-
- initializeOpenGLFunctions();
-
- m_textureHelper = new TextureHelper();
- m_drawer->initializeOpenGL();
-
- // Resize in case we've missed resize events
- resizeNotify();
-
- // Initialize shaders
-#if !defined(QT_OPENGL_ES_2)
- if (m_shadowQuality > ShadowNone) {
- if (!m_theme->m_uniformColor) {
- initShaders(QStringLiteral(":/shaders/vertexShadow"),
- QStringLiteral(":/shaders/fragmentShadowNoTexColorOnY"));
- } else {
- initShaders(QStringLiteral(":/shaders/vertexShadow"),
- QStringLiteral(":/shaders/fragmentShadowNoTex"));
- }
- initBackgroundShaders(QStringLiteral(":/shaders/vertexShadow"),
- QStringLiteral(":/shaders/fragmentShadowNoTex"));
- // Init the depth buffer (for shadows)
- initDepthBuffer();
- } else {
- if (!m_theme->m_uniformColor) {
- initShaders(QStringLiteral(":/shaders/vertex"),
- QStringLiteral(":/shaders/fragmentColorOnY"));
- } else {
- initShaders(QStringLiteral(":/shaders/vertex"),
- QStringLiteral(":/shaders/fragment"));
- }
- initBackgroundShaders(QStringLiteral(":/shaders/vertex"),
- QStringLiteral(":/shaders/fragment"));
- }
-#else
- if (!m_theme->m_uniformColor) {
- initShaders(QStringLiteral(":/shaders/vertexES2"),
- QStringLiteral(":/shaders/fragmentColorOnYES2"));
- } else {
- initShaders(QStringLiteral(":/shaders/vertexES2"),
- QStringLiteral(":/shaders/fragmentES2"));
- }
- initBackgroundShaders(QStringLiteral(":/shaders/vertexES2"),
- QStringLiteral(":/shaders/fragmentES2"));
-#endif
-
- initLabelShaders(QStringLiteral(":/shaders/vertexLabel"),
- QStringLiteral(":/shaders/fragmentLabel"));
-
-#if !defined(QT_OPENGL_ES_2)
- // Init depth shader (for shadows). Init in any case, easier to handle shadow activation if done via api.
- initDepthShader();
-#endif
-
- // Init selection shader
- initSelectionShader();
-
-#ifndef USE_HAX0R_SELECTION
- // Init the selection buffer
- initSelectionBuffer();
-#endif
-
- // Load default mesh
- loadBarMesh();
-
- // Load background mesh
- loadBackgroundMesh();
-
- // Load grid line mesh
- loadGridLineMesh();
-
- // Load label mesh
- loadLabelMesh();
-
- // Set OpenGL features
- glEnable(GL_DEPTH_TEST);
- glDepthFunc(GL_LESS);
- glEnable(GL_CULL_FACE);
- glCullFace(GL_BACK);
-
-#if !defined(QT_OPENGL_ES_2)
- glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
- glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
- glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
-#endif
-
- // Set initial camera position
- // X must be 0 for rotation to work - we can use "setCameraRotation" for setting it later
- CameraHelper::setDefaultCameraOrientation(QVector3D(0.0f, 0.0f, 6.0f + zComp),
- QVector3D(0.0f, 0.0f, zComp),
- QVector3D(0.0f, 1.0f, 0.0f));
-
- // Set view port
- glViewport(0, 0, width(), height());
-
- // Set initialized -flag
- m_isInitialized = true;
-
- // Load background mesh
- loadBackgroundMesh();
-}
-
-void Bars3dShared::drawZoomScene()
-{
- // Set clear color
- QVector3D clearColor = Utils::vectorFromColor(m_theme->m_windowColor);
- glClearColor(clearColor.x(), clearColor.y(), clearColor.z(), 1.0f);
-
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- // If no zoom, return
- if (!m_zoomActivated)
- return;
-
- GLfloat barPosX = 0;
- GLint startBar = 0;
- GLint stopBar = m_zoomSelection->d_ptr->row().size();
- GLint stepBar = 1;
- QVector3D lightPos;
-
- // Specify viewport
- glViewport(m_zoomViewPort.x(), m_zoomViewPort.y(),
- m_zoomViewPort.width(), m_zoomViewPort.height());
-
- // Set up projection matrix
- QMatrix4x4 projectionMatrix;
- projectionMatrix.perspective(45.0f, (GLfloat)m_zoomViewPort.width()
- / (GLfloat)m_zoomViewPort.height(), 0.1f, 100.0f);
-
-#ifdef ROTATE_ZOOM_SELECTION
- // Calculate view matrix
- QMatrix4x4 viewMatrix = CameraHelper::calculateViewMatrix(m_mousePos,
- m_zoomLevel
- * m_zoomAdjustment,
- m_zoomViewPort.width(),
- m_zoomViewPort.height());
-
- // Get light position (rotate light with camera, a bit above it (as set in defaultLightPos))
- lightPos = CameraHelper::calculateLightPosition(defaultLightPos);
-
- if (viewMatrix.row(0).z() <= 0) {
- startBar = m_zoomSelection->d_ptr->row().size() - 1;
- stopBar = -1;
- stepBar = -1;
- }
-#else
- // Set view matrix
- QMatrix4x4 viewMatrix;
-
- // Adjust scaling (zoom rate based on aspect ratio)
- GLfloat camPosZoomed = 5.0f / m_zoomAdjustment + zComp;
-
- viewMatrix.lookAt(QVector3D(0.0f, 0.0f, camPosZoomed),
- QVector3D(0.0f, 0.0f, zComp),
- QVector3D(0.0f, 1.0f, 0.0f));
-
- // Set light position a bit below the camera to reduce glare (depends on do we have row or column zoom)
- QVector3D zoomLightPos = defaultLightPos;
- zoomLightPos.setY(-10.0f);
- if (ModeZoomColumn == m_selectionMode)
- lightPos = CameraHelper::calculateLightPosition(zoomLightPos, -85.0f);
- else
- lightPos = CameraHelper::calculateLightPosition(zoomLightPos, 5.0f);
-#endif
-
- // Bind bar shader
- m_barShader->bind();
-
- // Draw bars
- // Draw the selected row / column
- for (int bar = startBar; bar != stopBar; bar += stepBar) {
- QDataItem *item = m_zoomSelection->d_ptr->getItem(bar);
- if (!item)
- continue;
-
- GLfloat barHeight = item->d_ptr->value() / m_heightNormalizer;
-
- if (barHeight < 0)
- glCullFace(GL_FRONT);
- else
- glCullFace(GL_BACK);
-
- QMatrix4x4 modelMatrix;
- QMatrix4x4 MVPMatrix;
- QMatrix4x4 itModelMatrix;
-
- GLfloat barPosY = item->d_ptr->translation().y() - m_yAdjustment / 2.0f + 0.2f; // we need some room for labels underneath; add +0.2f
- if (ModeZoomRow == m_selectionMode)
- barPosX = item->d_ptr->translation().x();
- else
- barPosX = -(item->d_ptr->translation().z() - zComp); // flip z; frontmost bar to the left
- modelMatrix.translate(barPosX, barPosY, zComp);
- modelMatrix.scale(QVector3D(m_scaleX, barHeight, m_scaleZ));
- itModelMatrix.scale(QVector3D(m_scaleX, barHeight, m_scaleZ));
-
- MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
-
- QVector3D baseColor = Utils::vectorFromColor(m_theme->m_baseColor);
- QVector3D heightColor = Utils::vectorFromColor(m_theme->m_heightColor) * barHeight;
-
- QVector3D barColor = baseColor + heightColor;
-
- GLfloat lightStrength = m_theme->m_lightStrength;
-
- if (barHeight != 0) {
- // Set shader bindings
- m_barShader->setUniformValue(m_barShader->lightP(), lightPos);
- m_barShader->setUniformValue(m_barShader->view(), viewMatrix);
- m_barShader->setUniformValue(m_barShader->model(), modelMatrix);
- m_barShader->setUniformValue(m_barShader->nModel(),
- itModelMatrix.inverted().transposed());
- m_barShader->setUniformValue(m_barShader->MVP(), MVPMatrix);
- m_barShader->setUniformValue(m_barShader->color(), barColor);
- m_barShader->setUniformValue(m_barShader->lightS(), lightStrength);
- m_barShader->setUniformValue(m_barShader->ambientS(),
- m_theme->m_ambientStrength);
-
- // Draw the object
- m_drawer->drawObject(m_barShader, m_barObj);
- }
- }
-
- // Release bar shader
- m_barShader->release();
-
- // Draw labels
- m_labelShader->bind();
- glDisable(GL_DEPTH_TEST);
- glEnable(GL_TEXTURE_2D);
- glCullFace(GL_BACK);
- if (m_labelTransparency > TransparencyNone) {
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- }
-
- // Draw labels for axes
- QDataItem *dummyItem = NULL;
- LabelItem x;
- LabelItem z;
- LabelItem y;
- m_dataSet->d_ptr->axisLabelItems(&x, &z, &y);
- LabelItem zoomSelectionLabel = m_zoomSelection->d_ptr->labelItem();
- if (ModeZoomRow == m_selectionMode) {
- m_drawer->drawLabel(*dummyItem, zoomSelectionLabel, viewMatrix, projectionMatrix,
- QVector3D(0.0f, m_yAdjustment, zComp),
- QVector3D(0.0f, 0.0f, 0.0f), m_heightNormalizer,
- m_selectionMode, m_labelShader,
- m_labelObj, false, false, LabelTop);
- m_drawer->drawLabel(*dummyItem, z, viewMatrix, projectionMatrix,
- QVector3D(0.0f, m_yAdjustment, zComp),
- QVector3D(0.0f, 0.0f, 0.0f), m_heightNormalizer,
- m_selectionMode, m_labelShader,
- m_labelObj, false, false, LabelBottom);
- } else {
- m_drawer->drawLabel(*dummyItem, x, viewMatrix, projectionMatrix,
- QVector3D(0.0f, m_yAdjustment, zComp),
- QVector3D(0.0f, 0.0f, 0.0f), m_heightNormalizer,
- m_selectionMode, m_labelShader,
- m_labelObj, false, false, LabelBottom);
- m_drawer->drawLabel(*dummyItem, zoomSelectionLabel, viewMatrix, projectionMatrix,
- QVector3D(0.0f, m_yAdjustment, zComp),
- QVector3D(0.0f, 0.0f, 0.0f), m_heightNormalizer,
- m_selectionMode, m_labelShader,
- m_labelObj, false, false, LabelTop);
- }
- m_drawer->drawLabel(*dummyItem, y, viewMatrix, projectionMatrix,
- QVector3D(0.0f, m_yAdjustment, zComp),
- QVector3D(0.0f, 0.0f, 90.0f), m_heightNormalizer,
- m_selectionMode, m_labelShader,
- m_labelObj, false, false, LabelLeft);
-
- // Draw labels for bars
- for (int col = 0; col < m_zoomSelection->d_ptr->row().size(); col++) {
- QDataItem *item = m_zoomSelection->d_ptr->getItem(col);
- // Draw values
- m_drawer->drawLabel(*item, item->d_ptr->label(), viewMatrix, projectionMatrix,
- QVector3D(0.0f, m_yAdjustment, zComp),
- QVector3D(0.0f, 0.0f, 0.0f), m_heightNormalizer,
- m_selectionMode, m_labelShader,
- m_labelObj);
- // Draw labels
- LabelItem labelItem;
- if (ModeZoomRow == m_selectionMode) {
- if (m_dataSet->d_ptr->columnLabelItems().size() > col) {
- // If draw order of bars is flipped, label draw order should be too
- if (m_xFlipped) {
- labelItem = m_dataSet->d_ptr->columnLabelItems().at(
- m_dataSet->d_ptr->columnLabelItems().size() - col - 1);
- } else {
- labelItem = m_dataSet->d_ptr->columnLabelItems().at(col);
- }
- }
- } else {
- if (m_dataSet->d_ptr->rowLabelItems().size() > col) {
- // If draw order of bars is flipped, label draw order should be too
- if (m_zFlipped) {
- labelItem = m_dataSet->d_ptr->rowLabelItems().at(
- m_dataSet->d_ptr->rowLabelItems().size() - col - 1);
- } else {
- labelItem = m_dataSet->d_ptr->rowLabelItems().at(col);
- }
- }
- }
- m_drawer->drawLabel(*item, labelItem, viewMatrix, projectionMatrix,
- QVector3D(0.0f, m_yAdjustment, zComp),
- QVector3D(0.0f, 0.0f, -45.0f), m_heightNormalizer,
- m_selectionMode, m_labelShader,
- m_labelObj, false, false, LabelBelow);
- }
-
- glDisable(GL_TEXTURE_2D);
- if (m_labelTransparency > TransparencyNone)
- glDisable(GL_BLEND);
- glEnable(GL_DEPTH_TEST);
-
- // Release label shader
- m_labelShader->release();
-}
-
-void Bars3dShared::drawScene()
-{
- GLint startBar = 0;
- GLint stopBar = 0;
- GLint stepBar = 0;
-
- GLint startRow = 0;
- GLint stopRow = 0;
- GLint stepRow = 0;
-
- GLfloat backgroundRotation = 0;
-
- GLfloat barPos = 0;
- GLfloat rowPos = 0;
-
- static QVector3D selection = skipColor;
-
- // Specify viewport
- glViewport(m_sceneViewPort.x(), m_sceneViewPort.y(),
- m_sceneViewPort.width(), m_sceneViewPort.height());
-
- // Set up projection matrix
- QMatrix4x4 projectionMatrix;
- projectionMatrix.perspective(45.0f, (GLfloat)m_sceneViewPort.width()
- / (GLfloat)m_sceneViewPort.height(), 0.1f, 100.0f);
-
- // Calculate view matrix
- QMatrix4x4 viewMatrix = CameraHelper::calculateViewMatrix(m_mousePos,
- m_zoomLevel
- * m_zoomAdjustment,
- m_sceneViewPort.width(),
- m_sceneViewPort.height(),
- m_negativeValues);
-
- // Calculate drawing order
- // Draw order is reversed to optimize amount of drawing (ie. draw front objects first, depth test handles not needing to draw objects behind them)
- if (viewMatrix.row(0).x() > 0) {
- startRow = 0;
- stopRow = m_sampleCount.second;
- stepRow = 1;
- m_zFlipped = false;
- } else {
- startRow = m_sampleCount.second - 1;
- stopRow = -1;
- stepRow = -1;
- m_zFlipped = true;
- }
- if (viewMatrix.row(0).z() <= 0) {
- startBar = 0;
- stopBar = m_sampleCount.first;
- stepBar = 1;
- m_xFlipped = false;
- } else {
- startBar = m_sampleCount.first - 1;
- stopBar = -1;
- stepBar = -1;
- m_xFlipped = true;
- }
-
- // Check if we're viewing the scene from below
- if (viewMatrix.row(2).y() < 0)
- m_yFlipped = true;
- else
- m_yFlipped = false;
-
- // calculate background rotation based on view matrix rotation
- if (viewMatrix.row(0).x() > 0 && viewMatrix.row(0).z() <= 0)
- backgroundRotation = 270.0f;
- else if (viewMatrix.row(0).x() > 0 && viewMatrix.row(0).z() > 0)
- backgroundRotation = 180.0f;
- else if (viewMatrix.row(0).x() <= 0 && viewMatrix.row(0).z() > 0)
- backgroundRotation = 90.0f;
- else if (viewMatrix.row(0).x() <= 0 && viewMatrix.row(0).z() <= 0)
- backgroundRotation = 0.0f;
-
- // Get light position (rotate light with camera, a bit above it (as set in defaultLightPos))
- QVector3D lightPos = CameraHelper::calculateLightPosition(defaultLightPos);
- //lightPos = QVector3D(0.0f, 4.0f, zComp); // center of bars, 4.0f above - for testing
-
- // Skip depth rendering if we're in zoom mode
- // TODO: Fix this, causes problems if depth rendering is off in zoom mode
- // Introduce regardless of shadow quality to simplify logic
- QMatrix4x4 depthViewMatrix;
- QMatrix4x4 depthProjectionMatrix;
-
-#if !defined(QT_OPENGL_ES_2)
- if (m_shadowQuality > ShadowNone/*!m_zoomActivated*/) {
- // Render scene into a depth texture for using with shadow mapping
- // Bind depth shader
- m_depthShader->bind();
-
- // Set viewport for depth map rendering. Must match texture size. Larger values give smoother shadows.
- glViewport(m_sceneViewPort.x(), m_sceneViewPort.y(),
- m_sceneViewPort.width() * m_shadowQuality,
- m_sceneViewPort.height() * m_shadowQuality);
-
- // Enable drawing to framebuffer
- glBindFramebuffer(GL_FRAMEBUFFER, m_depthFrameBuffer);
- glClear(GL_DEPTH_BUFFER_BIT);
-
- // Get the depth view matrix
- // It may be possible to hack lightPos here if we want to make some tweaks to shadow
- depthViewMatrix.lookAt(lightPos, QVector3D(0.0f, -m_yAdjustment, zComp),
- QVector3D(0.0f, 1.0f, 0.0f));
- // TODO: Why does depthViewMatrix.column(3).y() goes to zero when we're directly above? That causes the scene to be not drawn from above -> must be fixed
- //qDebug() << lightPos << depthViewMatrix << depthViewMatrix.column(3);
- // Set the depth projection matrix
-#ifdef USE_WIDER_SHADOWS
- // Use this for a bit exaggerated shadows
- depthProjectionMatrix.perspective(20.0f, (GLfloat)m_sceneViewPort.width()
- / (GLfloat)m_sceneViewPort.height(), 3.0f, 100.0f);
-#else
- // Use these for normal shadows, with the light further away
- depthProjectionMatrix = projectionMatrix;
-#endif
- // Draw bars to depth buffer
- for (int row = startRow; row != stopRow; row += stepRow) {
- for (int bar = startBar; bar != stopBar; bar += stepBar) {
- if (!m_dataSet->d_ptr->getRow(row))
- continue;
- QDataItem *item = m_dataSet->d_ptr->getRow(row)->d_ptr->getItem(bar);
- if (!item)
- continue;
-
- GLfloat barHeight = item->d_ptr->value() / m_heightNormalizer;
-
- // skip shadows for 0 -height bars
- if (barHeight == 0)
- continue;
-
- // Set front face culling for positive valued bars and back face culling for
- // negative valued bars to reduce self-shadowing issues
- if (barHeight < 0)
- glCullFace(GL_BACK);
- else
- glCullFace(GL_FRONT);
-
- QMatrix4x4 modelMatrix;
- QMatrix4x4 MVPMatrix;
-
- barPos = (bar + 1) * (m_barSpacing.width());
- rowPos = (row + 1) * (m_barSpacing.height());
-
- modelMatrix.translate((m_rowWidth - barPos) / m_scaleFactor,
- barHeight - m_yAdjustment,
- (m_columnDepth - rowPos) / m_scaleFactor
- + zComp);
- modelMatrix.scale(QVector3D(m_scaleX, barHeight, m_scaleZ));
-
- MVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
-
- m_depthShader->setUniformValue(m_depthShader->MVP(), MVPMatrix);
-
- // 1st attribute buffer : vertices
- glEnableVertexAttribArray(m_depthShader->posAtt());
- glBindBuffer(GL_ARRAY_BUFFER, m_barObj->vertexBuf());
- glVertexAttribPointer(m_depthShader->posAtt(), 3, GL_FLOAT, GL_FALSE, 0,
- (void *)0);
-
- // Index buffer
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_barObj->elementBuf());
-
- // Draw the triangles
- glDrawElements(GL_TRIANGLES, m_barObj->indexCount(), GL_UNSIGNED_SHORT,
- (void *)0);
-
- // Free buffers
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
-
- glDisableVertexAttribArray(m_depthShader->posAtt());
- }
- }
-
- // Disable drawing to framebuffer (= enable drawing to screen)
- glBindFramebuffer(GL_FRAMEBUFFER, m_fbohandle);
-
- // Release depth shader
- m_depthShader->release();
-
-#if 0 // Use this if you want to see what is being drawn to the framebuffer
- // You'll also have to comment out GL_COMPARE_R_TO_TEXTURE -line in texturehelper (if using it)
- m_labelShader->bind();
- glCullFace(GL_BACK);
- glEnable(GL_TEXTURE_2D);
- QMatrix4x4 modelMatrix;
- QMatrix4x4 viewmatrix;
- viewmatrix.lookAt(QVector3D(0.0f, 0.0f, 2.5f + zComp),
- QVector3D(0.0f, 0.0f, zComp),
- QVector3D(0.0f, 1.0f, 0.0f));
- modelMatrix.translate(0.0, 0.0, zComp);
- QMatrix4x4 MVPMatrix = projectionMatrix * viewmatrix * modelMatrix;
- m_labelShader->setUniformValue(m_labelShader->MVP(), MVPMatrix);
- m_drawer->drawObject(m_labelShader, m_labelObj,
- m_depthTexture);
- glDisable(GL_TEXTURE_2D);
- m_labelShader->release();
-#endif
- // Reset culling to normal
- glCullFace(GL_BACK);
-
- // Revert to original viewport
- glViewport(m_sceneViewPort.x(), m_sceneViewPort.y(),
- m_sceneViewPort.width(), m_sceneViewPort.height());
- }
-#endif
-
- // Skip selection mode drawing if we're zoomed or have no selection mode
- if (!m_zoomActivated && m_selectionMode > ModeNone) {
- // Bind selection shader
- m_selectionShader->bind();
-
- // Draw bars to selection buffer
-#ifndef USE_HAX0R_SELECTION
- glBindFramebuffer(GL_FRAMEBUFFER, m_selectionFrameBuffer);
- glEnable(GL_DEPTH_TEST); // Needed, otherwise the depth render buffer is not used
- glClearColor(skipColor.x() / 255, skipColor.y() / 255, skipColor.z() / 255, 1.0f); // Set clear color to white (= skipColor)
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Needed for clearing the frame buffer
-#endif
- glDisable(GL_DITHER); // disable dithering, it may affect colors if enabled
- for (int row = startRow; row != stopRow; row += stepRow) {
- for (int bar = startBar; bar != stopBar; bar += stepBar) {
- if (!m_dataSet->d_ptr->getRow(row))
- continue;
- QDataItem *item = m_dataSet->d_ptr->getRow(row)->d_ptr->getItem(bar);
- if (!item)
- continue;
-
- GLfloat barHeight = item->d_ptr->value() / m_heightNormalizer;
-
- if (barHeight < 0)
- glCullFace(GL_FRONT);
- else
- glCullFace(GL_BACK);
-
- QMatrix4x4 modelMatrix;
- QMatrix4x4 MVPMatrix;
-
- barPos = (bar + 1) * (m_barSpacing.width());
- rowPos = (row + 1) * (m_barSpacing.height());
-
- modelMatrix.translate((m_rowWidth - barPos) / m_scaleFactor,
- barHeight - m_yAdjustment,
- (m_columnDepth - rowPos) / m_scaleFactor
- + zComp);
- modelMatrix.scale(QVector3D(m_scaleX, barHeight, m_scaleZ));
-
- MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
-
- // TODO: Save position to qdataitem, so that we don't need to calculate it each time?
-
- //#if !defined(QT_OPENGL_ES_2)
- // QVector3D barColor = QVector3D((GLdouble)row / 32767.0,
- // (GLdouble)bar / 32767.0,
- // 0.0);
- //#else
- QVector3D barColor = QVector3D((GLdouble)row / 255.0,
- (GLdouble)bar / 255.0,
- 0.0);
- //#endif
-
- m_selectionShader->setUniformValue(m_selectionShader->MVP(),
- MVPMatrix);
- m_selectionShader->setUniformValue(m_selectionShader->color(),
- barColor);
-
-#ifdef USE_HAX0R_SELECTION
- // 1st attribute buffer : vertices
- glEnableVertexAttribArray(m_selectionShader->posAtt());
- glBindBuffer(GL_ARRAY_BUFFER, m_barObj->vertexBuf());
- glVertexAttribPointer(m_selectionShader->posAtt(),
- 3, GL_FLOAT, GL_FALSE, 0, (void *)0);
-
- // Index buffer
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_barObj->elementBuf());
-
- // Draw the triangles
- glDrawElements(GL_TRIANGLES, m_barObj->indexCount(),
- GL_UNSIGNED_SHORT, (void *)0);
-
- // Free buffers
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-
- glDisableVertexAttribArray(m_selectionShader->posAtt());
-#else
- // 1st attribute buffer : vertices
- glEnableVertexAttribArray(m_selectionShader->posAtt());
- glBindBuffer(GL_ARRAY_BUFFER, m_barObj->vertexBuf());
- glVertexAttribPointer(m_selectionShader->posAtt(),
- 3, GL_FLOAT, GL_FALSE, 0, (void *)0);
-
- // Index buffer
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_barObj->elementBuf());
-
- // Draw the triangles
- glDrawElements(GL_TRIANGLES, m_barObj->indexCount(), GL_UNSIGNED_SHORT,
- (void *)0);
-
- // Free buffers
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
-
- glDisableVertexAttribArray(m_selectionShader->posAtt());
-#endif
- }
- }
- glEnable(GL_DITHER);
-
- // Read color under cursor
- if (Bars3dShared::MouseOnScene == m_mousePressed)
- selection = Utils::getSelection(m_mousePos, height());
-
-#ifndef USE_HAX0R_SELECTION
- glBindFramebuffer(GL_FRAMEBUFFER, m_fbohandle);
-#endif
-
- // Release selection shader
- m_selectionShader->release();
-
-#if 0 // Use this if you want to see what is being drawn to the framebuffer
- glCullFace(GL_BACK);
- m_labelShader->bind();
- glDisable(GL_DEPTH_TEST);
- glEnable(GL_TEXTURE_2D);
- QMatrix4x4 modelMatrix;
- QMatrix4x4 viewmatrix;
- viewmatrix.lookAt(QVector3D(0.0f, 0.0f, 2.0f + zComp),
- QVector3D(0.0f, 0.0f, zComp),
- QVector3D(0.0f, 1.0f, 0.0f));
- modelMatrix.translate(0.0, 0.0, zComp);
- QMatrix4x4 MVPMatrix = projectionMatrix * viewmatrix * modelMatrix;
- m_labelShader->setUniformValue(m_labelShader->MVP(), MVPMatrix);
- m_drawer->drawObject(m_labelShader, m_labelObj,
- m_selectionTexture);
- glDisable(GL_TEXTURE_2D);
- m_labelShader->release();
-#endif
-
-#ifdef USE_HAX0R_SELECTION
- // Set clear color
- QVector3D clearColor = Utils::vectorFromColor(m_theme->m_windowColor);
- glClearColor(clearColor.x(), clearColor.y(), clearColor.z(), 1.0f);
- // Clear after selection
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-#endif
- }
-
- // Bind bar shader
- m_barShader->bind();
-
- // Enable texturing
- glEnable(GL_TEXTURE_2D);
-
- // Draw bars
- if (!m_zoomActivated && m_zoomSelection)
- m_zoomSelection->d_ptr->clear();
- bool barSelectionFound = false;
- for (int row = startRow; row != stopRow; row += stepRow) {
- for (int bar = startBar; bar != stopBar; bar += stepBar) {
- if (!m_dataSet->d_ptr->getRow(row))
- continue;
- QDataItem *item = m_dataSet->d_ptr->getRow(row)->d_ptr->getItem(bar);
- if (!item)
- continue;
-
- GLfloat barHeight = item->d_ptr->value() / m_heightNormalizer;
-
- if (barHeight < 0)
- glCullFace(GL_FRONT);
- else
- glCullFace(GL_BACK);
-
- QMatrix4x4 modelMatrix;
- QMatrix4x4 itModelMatrix;
- QMatrix4x4 MVPMatrix;
- QMatrix4x4 depthMVPMatrix;
-
- barPos = (bar + 1) * (m_barSpacing.width());
- rowPos = (row + 1) * (m_barSpacing.height());
- modelMatrix.translate((m_rowWidth - barPos) / m_scaleFactor,
- barHeight - m_yAdjustment,
- (m_columnDepth - rowPos) / m_scaleFactor + zComp);
- modelMatrix.scale(QVector3D(m_scaleX, barHeight, m_scaleZ));
- itModelMatrix.scale(QVector3D(m_scaleX, barHeight, m_scaleZ));
-#ifdef SHOW_DEPTH_TEXTURE_SCENE
- MVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
-#else
- MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
-#endif
- depthMVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
-
- QVector3D baseColor = Utils::vectorFromColor(m_theme->m_baseColor);
- QVector3D heightColor = Utils::vectorFromColor(m_theme->m_heightColor)
- * barHeight;
- QVector3D depthColor = Utils::vectorFromColor(m_theme->m_depthColor)
- * (float(row) / GLfloat(m_sampleCount.second));
-
- QVector3D barColor = baseColor + heightColor + depthColor;
-
- GLfloat lightStrength = m_theme->m_lightStrength;
- if (m_selectionMode > ModeNone) {
- Bars3dShared::SelectionType selectionType = isSelected(row, bar,
- selection);
- switch (selectionType) {
- case Bars3dShared::SelectionBar: {
- barColor = Utils::vectorFromColor(m_theme->m_highlightBarColor);
- lightStrength = m_theme->m_highlightLightStrength;
- // Insert data to QDataItem. We have no ownership, don't delete the previous one
- if (!m_zoomActivated) {
- m_selectedBar = item;
- if (m_dataSet->d_ptr->rowLabelItems().size() > row
- && m_dataSet->d_ptr->columnLabelItems().size() > bar) {
- m_selectedBar->setPosition(
- QPoint(m_dataSet->d_ptr->rowLabelItems().size()
- - row - 1,
- m_dataSet->d_ptr->columnLabelItems().size()
- - bar - 1));
- }
- item->d_ptr->setTranslation(modelMatrix.column(3).toVector3D());
- barSelectionFound = true;
- if (m_selectionMode >= ModeZoomRow) {
- item->d_ptr->setTranslation(modelMatrix.column(3).toVector3D());
- m_zoomSelection->addItem(item);
- }
- }
- break;
- }
- case Bars3dShared::SelectionRow: {
- // Current bar is on the same row as the selected bar
- barColor = Utils::vectorFromColor(m_theme->m_highlightRowColor);
- lightStrength = m_theme->m_highlightLightStrength;
- if (!m_zoomActivated && ModeZoomRow == m_selectionMode) {
- item->d_ptr->setTranslation(modelMatrix.column(3).toVector3D());
- m_zoomSelection->addItem(item);
- if (m_dataSet->d_ptr->rowLabelItems().size() > row) {
- m_zoomSelection->d_ptr->setLabelItem(
- m_dataSet->d_ptr->rowLabelItems().at(
- m_dataSet->d_ptr->rowLabelItems().size()
- - row - 1));
- }
- }
- break;
- }
- case Bars3dShared::SelectionColumn: {
- // Current bar is on the same column as the selected bar
- barColor = Utils::vectorFromColor(m_theme->m_highlightColumnColor);
- lightStrength = m_theme->m_highlightLightStrength;
- if (!m_zoomActivated && ModeZoomColumn == m_selectionMode) {
- item->d_ptr->setTranslation(modelMatrix.column(3).toVector3D());
- m_zoomSelection->addItem(item);
- if (m_dataSet->d_ptr->columnLabelItems().size() > bar) {
- m_zoomSelection->d_ptr->setLabelItem(
- m_dataSet->d_ptr->columnLabelItems().at(
- m_dataSet->d_ptr->columnLabelItems().size()
- - bar - 1));
- }
- }
- break;
- }
- case Bars3dShared::SelectionNone: {
- // Current bar is not selected, nor on a row or column
- // do nothing
- break;
- }
- }
- }
-
- if (barHeight != 0) {
- // Set shader bindings
- m_barShader->setUniformValue(m_barShader->lightP(), lightPos);
- m_barShader->setUniformValue(m_barShader->view(), viewMatrix);
- m_barShader->setUniformValue(m_barShader->model(), modelMatrix);
- m_barShader->setUniformValue(m_barShader->nModel(),
- itModelMatrix.transposed().inverted());
- m_barShader->setUniformValue(m_barShader->MVP(), MVPMatrix);
- m_barShader->setUniformValue(m_barShader->color(), barColor);
- m_barShader->setUniformValue(m_barShader->ambientS(),
- m_theme->m_ambientStrength);
-
-#if !defined(QT_OPENGL_ES_2)
- if (m_shadowQuality > ShadowNone) {
- // Set shadow shader bindings
- m_barShader->setUniformValue(m_barShader->shadowQ(),
- m_shadowQualityToShader);
- m_barShader->setUniformValue(m_barShader->depth(),
- depthMVPMatrix);
- m_barShader->setUniformValue(m_barShader->lightS(),
- lightStrength / 10.0f);
-
- // Draw the object
- m_drawer->drawObject(m_barShader, m_barObj,
- 0, m_depthTexture);
- } else
-#endif
- {
- // Set shadowless shader bindings
- m_barShader->setUniformValue(m_barShader->lightS(),
- lightStrength);
-
- // Draw the object
- m_drawer->drawObject(m_barShader, m_barObj);
- }
- }
- }
- }
-
- // Release bar shader
- m_barShader->release();
-
- // Bind background shader
- m_backgroundShader->bind();
-
- if (m_negativeValues)
- glDisable(GL_CULL_FACE);
- else
- glCullFace(GL_BACK);
-
- // Draw background
- if (m_bgrEnabled && m_backgroundObj) {
- QMatrix4x4 modelMatrix;
- QMatrix4x4 MVPMatrix;
- QMatrix4x4 depthMVPMatrix;
- QMatrix4x4 itModelMatrix;
-
- modelMatrix.translate(0.0f, 1.0f - m_yAdjustment, zComp);
- modelMatrix.scale(QVector3D(m_rowWidth / m_scaleFactor,
- 1.0f,
- m_columnDepth / m_scaleFactor));
- modelMatrix.rotate(backgroundRotation, 0.0f, 1.0f, 0.0f);
- itModelMatrix.scale(QVector3D(m_rowWidth / m_scaleFactor,
- 1.0f,
- m_columnDepth / m_scaleFactor));
-
-#ifdef SHOW_DEPTH_TEXTURE_SCENE
- MVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
-#else
- MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
-#endif
- depthMVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
-
- QVector3D backgroundColor = Utils::vectorFromColor(m_theme->m_backgroundColor);
-
- // Set shader bindings
- m_backgroundShader->setUniformValue(m_backgroundShader->lightP(),
- lightPos);
- m_backgroundShader->setUniformValue(m_backgroundShader->view(),
- viewMatrix);
- m_backgroundShader->setUniformValue(m_backgroundShader->model(),
- modelMatrix);
- m_backgroundShader->setUniformValue(m_backgroundShader->nModel(),
- itModelMatrix.inverted().transposed());
- m_backgroundShader->setUniformValue(m_backgroundShader->MVP(),
- MVPMatrix);
- m_backgroundShader->setUniformValue(m_backgroundShader->color(),
- backgroundColor);
- m_backgroundShader->setUniformValue(m_backgroundShader->ambientS(),
- m_theme->m_ambientStrength * 2.0f);
-
-#if !defined(QT_OPENGL_ES_2)
- if (m_shadowQuality > ShadowNone) {
- // Set shadow shader bindings
- m_backgroundShader->setUniformValue(m_backgroundShader->shadowQ(),
- m_shadowQualityToShader);
- m_backgroundShader->setUniformValue(m_backgroundShader->depth(),
- depthMVPMatrix);
- m_backgroundShader->setUniformValue(m_backgroundShader->lightS(),
- m_theme->m_lightStrength / 10.0f);
-
- // Draw the object
- m_drawer->drawObject(m_backgroundShader, m_backgroundObj,
- 0, m_depthTexture);
- } else
-#endif
- {
- // Set shadowless shader bindings
- m_backgroundShader->setUniformValue(m_backgroundShader->lightS(),
- m_theme->m_lightStrength);
-
- // Draw the object
- m_drawer->drawObject(m_backgroundShader, m_backgroundObj);
- }
- }
-
- // Disable textures
- glDisable(GL_TEXTURE_2D);
-
- // Release background shader
- m_backgroundShader->release();
-
- // Reset culling
- if (m_negativeValues) {
- glEnable(GL_CULL_FACE);
- glCullFace(GL_BACK);
- }
-
- // Draw grid lines
- if (m_gridEnabled && m_heightNormalizer) {
- // Bind bar shader
- m_barShader->bind();
-
- // Set unchanging shader bindings
- QVector3D barColor = Utils::vectorFromColor(m_theme->m_gridLine);
- m_barShader->setUniformValue(m_barShader->lightP(), lightPos);
- m_barShader->setUniformValue(m_barShader->view(), viewMatrix);
- m_barShader->setUniformValue(m_barShader->color(), barColor);
- m_barShader->setUniformValue(m_barShader->ambientS(),
- m_theme->m_ambientStrength);
-
- // Floor lines: rows
- for (GLfloat row = 0.0f; row <= m_sampleCount.second; row++) {
- QMatrix4x4 modelMatrix;
- QMatrix4x4 MVPMatrix;
- QMatrix4x4 depthMVPMatrix;
- QMatrix4x4 itModelMatrix;
-
- rowPos = (row + 0.5f) * (m_barSpacing.height());
- modelMatrix.translate(0.0f, -m_yAdjustment,
- (m_columnDepth - rowPos) / m_scaleFactor + zComp);
- modelMatrix.scale(QVector3D(m_rowWidth / m_scaleFactor, gridLineWidth,
- gridLineWidth));
- itModelMatrix.scale(QVector3D(m_rowWidth / m_scaleFactor, gridLineWidth,
- gridLineWidth));
- // If we're viewing from below, grid line object must be flipped
- if (m_yFlipped)
- modelMatrix.rotate(180.0f, 1.0, 0.0, 0.0);
-
- MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
- depthMVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
-
- // Set the rest of the shader bindings
- m_barShader->setUniformValue(m_barShader->model(), modelMatrix);
- m_barShader->setUniformValue(m_barShader->nModel(),
- itModelMatrix.inverted().transposed());
- m_barShader->setUniformValue(m_barShader->MVP(), MVPMatrix);
-
-#if !defined(QT_OPENGL_ES_2)
- if (m_shadowQuality > ShadowNone) {
- // Set shadow shader bindings
- m_barShader->setUniformValue(m_barShader->shadowQ(),
- m_shadowQualityToShader);
- m_barShader->setUniformValue(m_barShader->depth(),
- depthMVPMatrix);
- m_barShader->setUniformValue(m_barShader->lightS(),
- m_theme->m_lightStrength / 10.0f);
-
- // Draw the object
- m_drawer->drawObject(m_barShader, m_gridLineObj,
- 0, m_depthTexture);
- } else
-#endif
- {
- // Set shadowless shader bindings
- m_barShader->setUniformValue(m_barShader->lightS(),
- m_theme->m_lightStrength);
-
- // Draw the object
- m_drawer->drawObject(m_barShader, m_gridLineObj);
- }
- }
-
- // Floor lines: columns
- for (GLfloat bar = 0.0f; bar <= m_sampleCount.first; bar++) {
- QMatrix4x4 modelMatrix;
- QMatrix4x4 MVPMatrix;
- QMatrix4x4 depthMVPMatrix;
- QMatrix4x4 itModelMatrix;
-
- barPos = (bar + 0.5f) * (m_barSpacing.width());
- modelMatrix.translate((m_rowWidth - barPos) / m_scaleFactor,
- -m_yAdjustment, zComp);
- modelMatrix.scale(QVector3D(gridLineWidth, gridLineWidth,
- m_columnDepth / m_scaleFactor));
- itModelMatrix.scale(QVector3D(gridLineWidth, gridLineWidth,
- m_columnDepth / m_scaleFactor));
-
- // If we're viewing from below, grid line object must be flipped
- if (m_yFlipped)
- modelMatrix.rotate(180.0f, 1.0, 0.0, 0.0);
-
- MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
- depthMVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
-
- // Set the rest of the shader bindings
- m_barShader->setUniformValue(m_barShader->model(), modelMatrix);
- m_barShader->setUniformValue(m_barShader->nModel(),
- itModelMatrix.inverted().transposed());
- m_barShader->setUniformValue(m_barShader->MVP(), MVPMatrix);
-
-#if !defined(QT_OPENGL_ES_2)
- if (m_shadowQuality > ShadowNone) {
- // Set shadow shader bindings
- m_barShader->setUniformValue(m_barShader->shadowQ(),
- m_shadowQualityToShader);
- m_barShader->setUniformValue(m_barShader->depth(),
- depthMVPMatrix);
- m_barShader->setUniformValue(m_barShader->lightS(),
- m_theme->m_lightStrength / 10.0f);
-
- // Draw the object
- m_drawer->drawObject(m_barShader, m_gridLineObj,
- 0, m_depthTexture);
- } else
-#endif
- {
- // Set shadowless shader bindings
- m_barShader->setUniformValue(m_barShader->lightS(),
- m_theme->m_lightStrength);
-
- // Draw the object
- m_drawer->drawObject(m_barShader, m_gridLineObj);
- }
- }
-
- // Wall lines: back wall
- GLfloat heightStep = m_heightNormalizer / 5.0f; // default to 5 lines
- GLfloat startLine;
-
- if (m_tickCount > 0)
- heightStep = m_tickStep;
-
- if (m_negativeValues)
- startLine = -m_heightNormalizer;
- else
- startLine = heightStep;
-
- for (GLfloat lineHeight = startLine; lineHeight <= m_heightNormalizer;
- lineHeight += heightStep) {
- QMatrix4x4 modelMatrix;
- QMatrix4x4 MVPMatrix;
- QMatrix4x4 depthMVPMatrix;
- QMatrix4x4 itModelMatrix;
-
- if (m_zFlipped) {
- modelMatrix.translate(0.0f,
- 2.0f * lineHeight / m_heightNormalizer
- - m_yAdjustment,
- m_columnDepth / m_scaleFactor + zComp);
- } else {
- modelMatrix.translate(0.0f,
- 2.0f * lineHeight / m_heightNormalizer
- - m_yAdjustment,
- -m_columnDepth / m_scaleFactor + zComp);
- }
- modelMatrix.scale(QVector3D(m_rowWidth / m_scaleFactor, gridLineWidth,
- gridLineWidth));
- itModelMatrix.scale(QVector3D(m_rowWidth / m_scaleFactor, gridLineWidth,
- gridLineWidth));
-
- MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
- depthMVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
-
- // Set the rest of the shader bindings
- m_barShader->setUniformValue(m_barShader->model(), modelMatrix);
- m_barShader->setUniformValue(m_barShader->nModel(),
- itModelMatrix.inverted().transposed());
- m_barShader->setUniformValue(m_barShader->MVP(), MVPMatrix);
-
-#if !defined(QT_OPENGL_ES_2)
- if (m_shadowQuality > ShadowNone) {
- // Set shadow shader bindings
- m_barShader->setUniformValue(m_barShader->shadowQ(),
- m_shadowQualityToShader);
- m_barShader->setUniformValue(m_barShader->depth(),
- depthMVPMatrix);
- m_barShader->setUniformValue(m_barShader->lightS(),
- m_theme->m_lightStrength / 10.0f);
-
- // Draw the object
- m_drawer->drawObject(m_barShader, m_gridLineObj,
- 0, m_depthTexture);
- } else
-#endif
- {
- // Set shadowless shader bindings
- m_barShader->setUniformValue(m_barShader->lightS(),
- m_theme->m_lightStrength);
-
- // Draw the object
- m_drawer->drawObject(m_barShader, m_gridLineObj);
- }
- }
-
- // Wall lines: side wall
- for (GLfloat lineHeight = startLine; lineHeight <= m_heightNormalizer;
- lineHeight += heightStep) {
- QMatrix4x4 modelMatrix;
- QMatrix4x4 MVPMatrix;
- QMatrix4x4 depthMVPMatrix;
- QMatrix4x4 itModelMatrix;
-
- if (m_xFlipped) {
- modelMatrix.translate(m_rowWidth / m_scaleFactor,
- 2.0f * lineHeight / m_heightNormalizer
- - m_yAdjustment,
- zComp);
- } else {
- modelMatrix.translate(-m_rowWidth / m_scaleFactor,
- 2.0f * lineHeight / m_heightNormalizer
- - m_yAdjustment,
- zComp);
- }
- modelMatrix.scale(QVector3D(gridLineWidth, gridLineWidth,
- m_columnDepth / m_scaleFactor));
- itModelMatrix.scale(QVector3D(gridLineWidth, gridLineWidth,
- m_columnDepth / m_scaleFactor));
-
- MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
- depthMVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
-
- // Set the rest of the shader bindings
- m_barShader->setUniformValue(m_barShader->model(), modelMatrix);
- m_barShader->setUniformValue(m_barShader->nModel(),
- itModelMatrix.inverted().transposed());
- m_barShader->setUniformValue(m_barShader->MVP(), MVPMatrix);
-
-#if !defined(QT_OPENGL_ES_2)
- if (m_shadowQuality > ShadowNone) {
- // Set shadow shader bindings
- m_barShader->setUniformValue(m_barShader->shadowQ(),
- m_shadowQualityToShader);
- m_barShader->setUniformValue(m_barShader->depth(),
- depthMVPMatrix);
- m_barShader->setUniformValue(m_barShader->lightS(),
- m_theme->m_lightStrength / 10.0f);
-
- // Draw the object
- m_drawer->drawObject(m_barShader, m_gridLineObj,
- 0, m_depthTexture);
- } else
-#endif
- {
- // Set shadowless shader bindings
- m_barShader->setUniformValue(m_barShader->lightS(),
- m_theme->m_lightStrength);
-
- // Draw the object
- m_drawer->drawObject(m_barShader, m_gridLineObj);
- }
- }
-
- // Release bar shader
- m_barShader->release();
- }
-
- // TODO: Draw y labels
-
- // Generate label textures for zoom selection if m_updateLabels is set
- if (m_zoomActivated && m_updateLabels) {
- // Create label textures
- for (int col = 0; col < m_zoomSelection->d_ptr->row().size(); col++) {
- QDataItem *item = m_zoomSelection->d_ptr->getItem(col);
- m_drawer->generateLabelTexture(item);
- }
- }
-
- // Handle zoom activation and label drawing
- if (!barSelectionFound) {
- // We have no ownership, don't delete. Just NULL the pointer.
- m_selectedBar = NULL;
- if (m_zoomActivated && Bars3dShared::MouseOnOverview == m_mousePressed) {
- m_sceneViewPort = QRect(0, 0, width(), height());
- m_zoomActivated = false;
- }
- } else if (m_selectionMode >= ModeZoomRow
- && Bars3dShared::MouseOnScene == m_mousePressed) {
- // Activate zoom mode
- m_zoomActivated = true;
- m_sceneViewPort = QRect(0, height() - height() / 5, width() / 5, height() / 5);
-
- // Create label textures
- for (int col = 0; col < m_zoomSelection->d_ptr->row().size(); col++) {
- QDataItem *item = m_zoomSelection->d_ptr->getItem(col);
- m_drawer->generateLabelTexture(item);
- }
- } else {
- // Print value of selected bar
- static QDataItem *prevItem = m_selectedBar;
- m_labelShader->bind();
- glDisable(GL_DEPTH_TEST);
- glEnable(GL_TEXTURE_2D);
- if (m_labelTransparency > TransparencyNone) {
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- }
-#ifndef DISPLAY_FULL_DATA_ON_SELECTION
- // Draw just the value string of the selected bar
- if (prevItem != m_selectedBar || m_updateLabels) {
- m_drawer->generateLabelTexture(m_selectedBar);
- prevItem = m_selectedBar;
- }
-
- m_drawer->drawLabel(*m_selectedBar, m_selectedBar->label(),
- viewMatrix, projectionMatrix,
- QVector3D(0.0f, m_yAdjustment, zComp),
- QVector3D(0.0f, 0.0f, 0.0f), m_heightNormalizer,
- m_selectionMode, m_labelShader,
- m_labelObj, true);
-#else
- static bool firstSelection = true;
- // Draw the value string followed by row label and column label
- LabelItem labelItem = m_selectedBar->d_ptr->selectionLabel();
- if (firstSelection || prevItem != m_selectedBar || m_updateLabels) {
- QString labelText = m_selectedBar->d_ptr->valueStr();
- if ((m_dataSet->d_ptr->columnLabels().size()
- > m_selectedBar->position().y())
- && (m_dataSet->d_ptr->rowLabels().size()
- > m_selectedBar->position().x())) {
- labelText.append(QStringLiteral(" ("));
- labelText.append(m_dataSet->d_ptr->rowLabels().at(
- m_selectedBar->position().x()));
- labelText.append(QStringLiteral(", "));
- labelText.append(m_dataSet->d_ptr->columnLabels().at(
- m_selectedBar->position().y()));
- labelText.append(QStringLiteral(")"));
- //qDebug() << labelText;
- }
- m_drawer->generateLabelItem(&labelItem, labelText);
- m_selectedBar->d_ptr->setSelectionLabel(labelItem);
- prevItem = m_selectedBar;
- firstSelection = false;
- }
-
- m_drawer->drawLabel(*m_selectedBar, labelItem, viewMatrix, projectionMatrix,
- QVector3D(0.0f, m_yAdjustment, zComp),
- QVector3D(0.0f, 0.0f, 0.0f), m_heightNormalizer,
- m_selectionMode, m_labelShader,
- m_labelObj, true, false);
-#endif
- glDisable(GL_TEXTURE_2D);
- if (m_labelTransparency > TransparencyNone)
- glDisable(GL_BLEND);
- glEnable(GL_DEPTH_TEST);
-
- // Release label shader
- m_labelShader->release();
-
- // Reset label update flag; they should have been updated when we get here
- m_updateLabels = false;
- }
-
- // TODO: Calculations done temporarily here. When optimizing, move to after data set addition? Keep drawing of the labels here.
- // Bind label shader
- m_labelShader->bind();
-
- glEnable(GL_TEXTURE_2D);
- if (m_labelTransparency > TransparencyNone) {
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- }
-
- // Calculate the positions for row and column labels and store them into QDataItems (and QDataRows?)
- for (int row = 0; row != m_sampleCount.second; row += 1) {
- // Go through all rows and get position of max+1 or min-1 column, depending on x flip
- // We need only positions for them, labels have already been generated at QDataSet. Just add LabelItems
- rowPos = (row + 1) * (m_barSpacing.height());
- barPos = 0;
- GLfloat rotLabelX = -90.0f;
- GLfloat rotLabelY = 0.0f;
- GLfloat rotLabelZ = 0.0f;
- Qt::AlignmentFlag alignment = Qt::AlignRight;
- if (m_zFlipped)
- rotLabelY = 180.0f;
- if (m_xFlipped) {
- barPos = (m_sampleCount.first + 1) * (m_barSpacing.width());
- alignment = Qt::AlignLeft;
- }
- if (m_yFlipped) {
- if (m_zFlipped)
- rotLabelY = 0.0f;
- else
- rotLabelY = 180.0f;
- rotLabelZ = 180.0f;
- }
- QVector3D labelPos = QVector3D((m_rowWidth - barPos) / m_scaleFactor,
- -m_yAdjustment + 0.005f, // raise a bit over background to avoid depth "glimmering"
- (m_columnDepth - rowPos) / m_scaleFactor
- + zComp);
-
- // TODO: Try it; draw the label here
-
- // Create a data item
- QDataItem *label = new QDataItem();
- label->d_ptr->setTranslation(labelPos);
- if (m_dataSet->d_ptr->rowLabelItems().size() > row) {
- label->d_ptr->setLabel(m_dataSet->d_ptr->rowLabelItems().at(
- m_dataSet->d_ptr->rowLabelItems().size() - row - 1));
- }
-
- //qDebug() << "labelPos, row" << row + 1 << ":" << labelPos << m_dataSet->d_ptr->rowLabels().at(row);
-
- m_drawer->drawLabel(*label, label->d_ptr->label(), viewMatrix, projectionMatrix,
- QVector3D(0.0f, m_yAdjustment, zComp),
- QVector3D(rotLabelX, rotLabelY, rotLabelZ),
- m_heightNormalizer, m_selectionMode,
- m_labelShader, m_labelObj, true, true, LabelMid,
- alignment);
-
- delete label;
- }
- for (int bar = 0; bar != m_sampleCount.first; bar += 1) {
- // Go through all columns and get position of max+1 or min-1 row, depending on z flip
- // We need only positions for them, labels have already been generated at QDataSet. Just add LabelItems
- barPos = (bar + 1) * (m_barSpacing.width());
- rowPos = 0;
- GLfloat rotLabelX = -90.0f;
- GLfloat rotLabelY = 90.0f;
- GLfloat rotLabelZ = 0.0f;
- Qt::AlignmentFlag alignment = Qt::AlignLeft;
- if (m_xFlipped)
- rotLabelY = -90.0f;
- if (m_zFlipped) {
- rowPos = (m_sampleCount.second + 1) * (m_barSpacing.height());
- alignment = Qt::AlignRight;
- }
- if (m_yFlipped) {
- if (m_xFlipped)
- rotLabelY = -90.0f;
- else
- rotLabelY = 90.0f;
- rotLabelZ = 180.0f;
- }
- QVector3D labelPos = QVector3D((m_rowWidth - barPos) / m_scaleFactor,
- -m_yAdjustment + 0.005f, // raise a bit over background to avoid depth "glimmering"
- (m_columnDepth - rowPos) / m_scaleFactor
- + zComp);
-
- // TODO: Try it; draw the label here
-
- // Create a data item
- QDataItem *label = new QDataItem();
- label->d_ptr->setTranslation(labelPos);
- if (m_dataSet->d_ptr->columnLabelItems().size() > bar) {
- label->d_ptr->setLabel(m_dataSet->d_ptr->columnLabelItems().at(
- m_dataSet->d_ptr->columnLabelItems().size()
- - bar - 1));
- }
-
- //qDebug() << "labelPos, col" << bar + 1 << ":" << labelPos << m_dataSet->d_ptr->columnLabels().at(bar);
-
- m_drawer->drawLabel(*label, label->d_ptr->label(), viewMatrix, projectionMatrix,
- QVector3D(0.0f, m_yAdjustment, zComp),
- QVector3D(rotLabelX, rotLabelY, rotLabelZ),
- m_heightNormalizer, m_selectionMode,
- m_labelShader, m_labelObj, true, true, LabelMid,
- alignment);
-
- delete label;
- }
- glDisable(GL_TEXTURE_2D);
- if (m_labelTransparency > TransparencyNone)
- glDisable(GL_BLEND);
-
- // Release label shader
- m_labelShader->release();
-}
-
-#if defined(Q_OS_ANDROID)
-void Bars3dShared::mouseDoubleClickEvent(QMouseEvent *event)
-{
- if (!m_zoomActivated) {
- m_mousePressed = Bars3dShared::MouseOnScene;
- // update mouse positions to prevent jumping when releasing or repressing a button
- m_mousePos = event->pos();
- }
-}
-
-void Bars3dShared::touchEvent(QTouchEvent *event)
-{
- static int prevDistance = 0;
-
- QList<QTouchEvent::TouchPoint> points;
- points = event->touchPoints();
-
- if (points.count() == 2) {
- m_mousePressed = Bars3dShared::MouseOnPinch;
-
- QPointF distance = points.at(0).pos() - points.at(1).pos();
- int newDistance = distance.manhattanLength();
- int zoomRate = 1;
- if (m_zoomLevel > 100)
- zoomRate = 5;
- if (newDistance > prevDistance)
- m_zoomLevel += zoomRate;
- else
- m_zoomLevel -= zoomRate;
- if (m_zoomLevel > 500)
- m_zoomLevel = 500;
- else if (m_zoomLevel < 10)
- m_zoomLevel = 10;
- prevDistance = newDistance;
- //qDebug() << "distance" << distance.manhattanLength();
- }
-}
-#endif
-
-void Bars3dShared::mousePressEvent(QMouseEvent *event)
-{
- if (Qt::LeftButton == event->button()) {
- if (m_zoomActivated) {
- if (event->pos().x() <= m_sceneViewPort.width()
- && event->pos().y() <= m_sceneViewPort.height()) {
- m_mousePressed = Bars3dShared::MouseOnOverview;
- //qDebug() << "Mouse pressed on overview";
- } else {
- m_mousePressed = Bars3dShared::MouseOnZoom;
- //qDebug() << "Mouse pressed on zoom";
- }
- } else {
-#if !defined(Q_OS_ANDROID)
- m_mousePressed = Bars3dShared::MouseOnScene;
-#else
- m_mousePressed = Bars3dShared::MouseRotating;
-#endif
- // update mouse positions to prevent jumping when releasing or repressing a button
- m_mousePos = event->pos();
- //qDebug() << "Mouse pressed on scene";
- }
- } else if (Qt::MiddleButton == event->button()) {
- // reset rotations
- m_mousePos = QPoint(0, 0);
- } else if (Qt::RightButton == event->button()) {
-#if !defined(Q_OS_ANDROID)
- m_mousePressed = Bars3dShared::MouseRotating;
-#else
- m_mousePressed = Bars3dShared::MouseOnScene;
-#endif
- // update mouse positions to prevent jumping when releasing or repressing a button
- m_mousePos = event->pos();
- }
- CameraHelper::updateMousePos(m_mousePos);
-}
-
-void Bars3dShared::mouseReleaseEvent(QMouseEvent *event)
-{
- if (Bars3dShared::MouseRotating == m_mousePressed) {
- // update mouse positions to prevent jumping when releasing or repressing a button
- m_mousePos = event->pos();
- CameraHelper::updateMousePos(event->pos());
- }
- m_mousePressed = Bars3dShared::MouseNone;
-}
-
-void Bars3dShared::mouseMoveEvent(QMouseEvent *event)
-{
- if (Bars3dShared::MouseRotating == m_mousePressed)
- m_mousePos = event->pos();
-}
-
-void Bars3dShared::wheelEvent(QWheelEvent *event)
-{
- if (m_zoomLevel > 100)
- m_zoomLevel += event->angleDelta().y() / 12;
- else if (m_zoomLevel > 50)
- m_zoomLevel += event->angleDelta().y() / 60;
- else
- m_zoomLevel += event->angleDelta().y() / 120;
- if (m_zoomLevel > 500)
- m_zoomLevel = 500;
- else if (m_zoomLevel < 10)
- m_zoomLevel = 10;
-}
-
-void Bars3dShared::resizeNotify()
-{
- qDebug() << "Bars3dShared::resizeEvent " << width() << "x" <<height();
-
- // Set view port
- if (m_zoomActivated)
- m_sceneViewPort = QRect(0, height() - height() / 5, width() / 5, height() / 5);
- else
- m_sceneViewPort = QRect(0, 0, width(), height());
- m_zoomViewPort = QRect(0, 0, width(), height());
-
- // Calculate zoom level based on aspect ratio
- GLfloat div;
- GLfloat zoomAdjustment;
- div = qMin(width(), height());
- zoomAdjustment = defaultRatio * ((width() / div) / (height() / div));
- //qDebug() << "zoom adjustment" << zoomAdjustment;
- m_zoomAdjustment = qMin(zoomAdjustment, 1.0f); // clamp to 1.0f
-
- // Re-init selection buffer
- initSelectionBuffer();
-
-#if !defined(QT_OPENGL_ES_2)
- // Re-init depth buffer
- if (m_isInitialized && m_shadowQuality > ShadowNone)
- initDepthBuffer();
-#endif
-}
-
-void Bars3dShared::setBarSpecs(QSizeF thickness, QSizeF spacing, bool relative)
-{
- m_barThickness = thickness;
- if (relative) {
- m_barSpacing.setWidth((thickness.width() * 2) * (spacing.width() + 1.0f));
- m_barSpacing.setHeight((thickness.height() * 2) * (spacing.height() + 1.0f));
- } else {
- m_barSpacing = thickness * 2 + spacing * 2;
- }
- // Calculate here and at setting sample space
- calculateSceneScalingFactors();
-}
-
-void Bars3dShared::setBarType(BarStyle style, bool smooth)
-{
- if (style == Bars) {
- if (smooth)
- m_objFile = QStringLiteral(":/defaultMeshes/barSmooth");
- else
- m_objFile = QStringLiteral(":/defaultMeshes/bar");
- } else if (style == Pyramids) {
- if (smooth)
- m_objFile = QStringLiteral(":/defaultMeshes/pyramidSmooth");
- else
- m_objFile = QStringLiteral(":/defaultMeshes/pyramid");
- } else if (style == Cones) {
- if (smooth)
- m_objFile = QStringLiteral(":/defaultMeshes/coneSmooth");
- else
- m_objFile = QStringLiteral(":/defaultMeshes/cone");
- } else if (style == Cylinders) {
- if (smooth)
- m_objFile = QStringLiteral(":/defaultMeshes/cylinderSmooth");
- else
- m_objFile = QStringLiteral(":/defaultMeshes/cylinder");
- } else if (style == BevelBars) {
- if (smooth)
- m_objFile = QStringLiteral(":/defaultMeshes/bevelbarSmooth");
- else
- m_objFile = QStringLiteral(":/defaultMeshes/bevelbar");
- }
- // Reload mesh data
- if (m_isInitialized)
- loadBarMesh();
-}
-
-void Bars3dShared::setMeshFileName(const QString &objFileName)
-{
- m_objFile = objFileName;
-}
-
-void Bars3dShared::setupSampleSpace(int samplesRow, int samplesColumn, const QString &labelRow,
- const QString &labelColumn, const QString &labelHeight)
-{
- // Disable zoom mode if we're in it (causes crash if not, as zoom selection is deleted)
- closeZoomMode();
- // Delete previous data set
- delete m_dataSet;
- m_dataSet = new QDataSet();
- m_sampleCount = qMakePair(samplesRow, samplesColumn);
- m_dataSet->setLabels(labelRow, labelColumn, labelHeight);
- // TODO: Invent "idiotproof" max scene size formula..
- // This seems to work ok if spacing is not negative (and row/column or column/row ratio is not too high)
- m_maxSceneSize = 2 * qSqrt(samplesRow * samplesColumn);
- //qDebug() << "maxSceneSize" << m_maxSceneSize;
- // Calculate here and at setting bar specs
- calculateSceneScalingFactors();
- m_axisLabelX = labelRow;
- m_axisLabelZ = labelColumn;
- m_axisLabelY = labelHeight;
-}
-
-void Bars3dShared::setCameraPreset(CameraPreset preset)
-{
- CameraHelper::setCameraPreset(preset);
-}
-
-void Bars3dShared::setCameraPosition(GLfloat horizontal, GLfloat vertical, GLint distance)
-{
- m_horizontalRotation = qBound(-180.0f, horizontal, 180.0f);
- m_verticalRotation = qBound(0.0f, vertical, 90.0f);
- m_zoomLevel = qBound(10, distance, 500);
- CameraHelper::setCameraRotation(QPointF(m_horizontalRotation,
- m_verticalRotation));
- //qDebug() << "camera rotation set to" << m_horizontalRotation << m_verticalRotation;
-}
-
-void Bars3dShared::setTheme(ColorTheme theme)
-{
- m_theme->useTheme(theme);
- m_drawer->setTheme(*m_theme);
- // Re-initialize shaders
-#if !defined(QT_OPENGL_ES_2)
- if (m_shadowQuality > ShadowNone) {
- if (!m_theme->m_uniformColor) {
- initShaders(QStringLiteral(":/shaders/vertexShadow"),
- QStringLiteral(":/shaders/fragmentShadowNoTexColorOnY"));
- } else {
- initShaders(QStringLiteral(":/shaders/vertexShadow"),
- QStringLiteral(":/shaders/fragmentShadowNoTex"));
- }
- } else {
- if (!m_theme->m_uniformColor) {
- initShaders(QStringLiteral(":/shaders/vertex"),
- QStringLiteral(":/shaders/fragmentColorOnY"));
- } else {
- initShaders(QStringLiteral(":/shaders/vertex"),
- QStringLiteral(":/shaders/fragment"));
- }
- }
-#else
- if (!m_theme->m_uniformColor) {
- initShaders(QStringLiteral(":/shaders/vertexES2"),
- QStringLiteral(":/shaders/fragmentColorOnYES2"));
- } else {
- initShaders(QStringLiteral(":/shaders/vertexES2"),
- QStringLiteral(":/shaders/fragmentES2"));
- }
-#endif
-}
-
-void Bars3dShared::setBarColor(QColor baseColor, QColor heightColor, QColor depthColor,
- bool uniform)
-{
- m_theme->m_baseColor = baseColor;
- m_theme->m_heightColor = heightColor;
- m_theme->m_depthColor = depthColor;
- //qDebug() << "colors:" << m_baseColor << m_heightColor << m_depthColor;
- if (m_theme->m_uniformColor != uniform) {
-#if !defined(QT_OPENGL_ES_2)
- if (m_shadowQuality > ShadowNone) {
- if (!m_theme->m_uniformColor) {
- initShaders(QStringLiteral(":/shaders/vertexShadow"),
- QStringLiteral(":/shaders/fragmentShadowNoTexColorOnY"));
- } else {
- initShaders(QStringLiteral(":/shaders/vertexShadow"),
- QStringLiteral(":/shaders/fragmentShadowNoTex"));
- }
- } else {
- if (!m_theme->m_uniformColor) {
- initShaders(QStringLiteral(":/shaders/vertex"),
- QStringLiteral(":/shaders/fragmentColorOnY"));
- } else {
- initShaders(QStringLiteral(":/shaders/vertex"),
- QStringLiteral(":/shaders/fragment"));
- }
- }
-#else
- if (!m_theme->m_uniformColor) {
- initShaders(QStringLiteral(":/shaders/vertexES2"),
- QStringLiteral(":/shaders/fragmentColorOnYES2"));
- } else {
- initShaders(QStringLiteral(":/shaders/vertexES2"),
- QStringLiteral(":/shaders/fragmentES2"));
- }
-#endif
- }
- m_theme->m_uniformColor = uniform;
-}
-
-void Bars3dShared::setSelectionMode(SelectionMode mode)
-{
- m_selectionMode = mode;
- // Disable zoom if selection mode changes
- closeZoomMode();
- // Create zoom selection if there isn't one
- if (mode >= ModeZoomRow && !m_zoomSelection)
- m_zoomSelection = new QDataRow();
-}
-
-SelectionMode Bars3dShared::selectionMode()
-{
- return m_selectionMode;
-}
-
-void Bars3dShared::setFontSize(float fontsize)
-{
- m_font.setPointSizeF(fontsize);
- m_drawer->setFont(m_font);
-}
-
-float Bars3dShared::fontSize()
-{
- return m_font.pointSizeF();
-}
-
-void Bars3dShared::setFont(const QFont &font)
-{
- m_font = font;
- m_drawer->setFont(font);
-}
-
-QFont Bars3dShared::font()
-{
- return m_font;
-}
-
-void Bars3dShared::setLabelTransparency(LabelTransparency transparency)
-{
- m_labelTransparency = transparency;
- m_drawer->setTransparency(transparency);
-}
-
-LabelTransparency Bars3dShared::labelTransparency()
-{
- return m_labelTransparency;
-}
-
-void Bars3dShared::setGridEnabled(bool enable)
-{
- m_gridEnabled = enable;
-}
-
-bool Bars3dShared::gridEnabled()
-{
- return m_gridEnabled;
-}
-
-void Bars3dShared::setBackgroundEnabled(bool enable)
-{
- if (m_bgrEnabled != enable) {
- m_bgrEnabled = enable;
- // Load changed bar type
- loadBarMesh();
- }
-}
-
-bool Bars3dShared::backgroundEnabled()
-{
- return m_bgrEnabled;
-}
-
-void Bars3dShared::setShadowQuality(ShadowQuality quality)
-{
- m_shadowQuality = quality;
- switch (quality) {
- case ShadowLow:
- m_shadowQualityToShader = 33.3f;
- break;
- case ShadowMedium:
- m_shadowQualityToShader = 100.0f;
- break;
- case ShadowHigh:
- m_shadowQualityToShader = 200.0f;
- break;
- default:
- m_shadowQualityToShader = 0.0f;
- break;
- }
- if (m_isInitialized) {
-#if !defined(QT_OPENGL_ES_2)
- if (m_shadowQuality > ShadowNone) {
- // Re-init depth buffer
- initDepthBuffer();
- // Re-init shaders
- if (!m_theme->m_uniformColor) {
- initShaders(QStringLiteral(":/shaders/vertexShadow"),
- QStringLiteral(":/shaders/fragmentShadowNoTexColorOnY"));
- } else {
- initShaders(QStringLiteral(":/shaders/vertexShadow"),
- QStringLiteral(":/shaders/fragmentShadowNoTex"));
- }
- initBackgroundShaders(QStringLiteral(":/shaders/vertexShadow"),
- QStringLiteral(":/shaders/fragmentShadowNoTex"));
- } else {
- // Re-init shaders
- if (!m_theme->m_uniformColor) {
- initShaders(QStringLiteral(":/shaders/vertex"),
- QStringLiteral(":/shaders/fragmentColorOnY"));
- } else {
- initShaders(QStringLiteral(":/shaders/vertex"),
- QStringLiteral(":/shaders/fragment"));
- }
- initBackgroundShaders(QStringLiteral(":/shaders/vertex"),
- QStringLiteral(":/shaders/fragment"));
- }
-#else
- if (!m_theme->m_uniformColor) {
- initShaders(QStringLiteral(":/shaders/vertexES2"),
- QStringLiteral(":/shaders/fragmentColorOnYES2"));
- } else {
- initShaders(QStringLiteral(":/shaders/vertexES2"),
- QStringLiteral(":/shaders/fragmentES2"));
- }
- initBackgroundShaders(QStringLiteral(":/shaders/vertexES2"),
- QStringLiteral(":/shaders/fragmentES2"));
-#endif
- }
-}
-
-ShadowQuality Bars3dShared::shadowQuality()
-{
- return m_shadowQuality;
-}
-
-void Bars3dShared::setTickCount(GLint tickCount, GLfloat step, GLfloat minimum)
-{
- m_tickCount = tickCount;
- m_tickStep = step;
- if (tickCount > 0 && step > 0) {
- m_heightNormalizer = tickCount * step;
- calculateHeightAdjustment(QPair<float, float>(minimum, m_heightNormalizer));
- }
-}
-
-void Bars3dShared::addDataRow(const QVector<float> &dataRow, const QString &labelRow,
- const QVector<QString> &labelsColumn)
-{
- // Convert to QDataRow and add to QDataSet
- QDataRow *row = new QDataRow(labelRow);
- for (int i = 0; i < dataRow.size(); i++)
- row->addItem(new QDataItem(dataRow.at(i)));
- row->d_ptr->verifySize(m_sampleCount.first);
- m_dataSet->addRow(row);
- handleLimitChange();
- m_dataSet->setLabels(m_axisLabelX, m_axisLabelZ, m_axisLabelY,
- QVector<QString>(), labelsColumn);
- m_dataSet->d_ptr->verifySize(m_sampleCount.second);
-}
-
-void Bars3dShared::addDataRow(const QVector<QDataItem*> &dataRow, const QString &labelRow,
- const QVector<QString> &labelsColumn)
-{
- // Convert to QDataRow and add to QDataSet
- QDataRow *row = new QDataRow(labelRow);
- for (int i = 0; i < dataRow.size(); i++)
- row->addItem(dataRow.at(i));
- row->d_ptr->verifySize(m_sampleCount.first);
- m_dataSet->addRow(row);
- handleLimitChange();
- m_dataSet->setLabels(m_axisLabelX, m_axisLabelZ, m_axisLabelY,
- QVector<QString>(), labelsColumn);
- m_dataSet->d_ptr->verifySize(m_sampleCount.second);
-}
-
-void Bars3dShared::addDataRow(QDataRow *dataRow)
-{
- QDataRow *row = dataRow;
- // Check that the input data fits into sample space, and resize if it doesn't
- row->d_ptr->verifySize(m_sampleCount.first);
- // With each new row, the previous data row must be moved back
- // ie. we need as many vectors as we have rows in the sample space
- m_dataSet->addRow(row);
- // if the added data pushed us over sample space, remove the oldest data set
- m_dataSet->d_ptr->verifySize(m_sampleCount.second);
- handleLimitChange();
-}
-
-void Bars3dShared::addDataSet(const QVector< QVector<float> > &data,
- const QVector<QString> &labelsRow,
- const QVector<QString> &labelsColumn)
-{
- // Copy axis labels
- QString xAxis;
- QString zAxis;
- QString yAxis;
- m_dataSet->d_ptr->axisLabels(&xAxis, &zAxis, &yAxis);
- // Disable zoom mode if we're in it (causes crash if not, as zoom selection is deleted)
- closeZoomMode();
- // Delete old data set
- delete m_dataSet;
- m_dataSet = new QDataSet();
- // Give drawer to data set
- m_dataSet->d_ptr->setDrawer(m_drawer);
- // Convert to QDataRow and add to QDataSet
- QDataRow *row;
- for (int rowNr = 0; rowNr < data.size(); rowNr++) {
- if (labelsRow.size() >= (rowNr + 1))
- row = new QDataRow(labelsRow.at(rowNr));
- else
- row = new QDataRow();
- for (int colNr = 0; colNr < data.at(rowNr).size(); colNr++)
- row->addItem(new QDataItem(data.at(rowNr).at(colNr)));
- row->d_ptr->verifySize(m_sampleCount.first);
- m_dataSet->addRow(row);
- row++;
- }
- handleLimitChange();
- m_dataSet->setLabels(xAxis, zAxis, yAxis, labelsRow, labelsColumn);
- m_dataSet->d_ptr->verifySize(m_sampleCount.second);
-}
-
-void Bars3dShared::addDataSet(const QVector< QVector<QDataItem*> > &data,
- const QVector<QString> &labelsRow,
- const QVector<QString> &labelsColumn)
-{
- // Copy axis labels
- QString xAxis;
- QString zAxis;
- QString yAxis;
- m_dataSet->d_ptr->axisLabels(&xAxis, &zAxis, &yAxis);
- // Disable zoom mode if we're in it (causes crash if not, as zoom selection is deleted)
- closeZoomMode();
- // Delete old data set
- delete m_dataSet;
- m_dataSet = new QDataSet();
- // Give drawer to data set
- m_dataSet->d_ptr->setDrawer(m_drawer);
- // Convert to QDataRow and add to QDataSet
- QDataRow *row;
- for (int rowNr = 0; rowNr < data.size(); rowNr++) {
- if (labelsRow.size() >= (rowNr + 1))
- row = new QDataRow(labelsRow.at(rowNr));
- else
- row = new QDataRow();
- for (int colNr = 0; colNr < data.at(rowNr).size(); colNr++)
- row->addItem(data.at(rowNr).at(colNr));
- row->d_ptr->verifySize(m_sampleCount.first);
- m_dataSet->addRow(row);
- row++;
- }
- handleLimitChange();
- m_dataSet->setLabels(xAxis, zAxis, yAxis, labelsRow, labelsColumn);
- m_dataSet->d_ptr->verifySize(m_sampleCount.second);
-}
-
-void Bars3dShared::addDataSet(QDataSet* dataSet)
-{
- // Disable zoom mode if we're in it (causes crash if not, as zoom selection is deleted)
- closeZoomMode();
- // Delete old data set
- delete m_dataSet;
- // Check sizes
- dataSet->d_ptr->verifySize(m_sampleCount.second, m_sampleCount.first);
- // Take ownership of given set
- m_dataSet = dataSet;
- handleLimitChange();
- // Give drawer to data set
- m_dataSet->d_ptr->setDrawer(m_drawer);
-}
-
-const QSize Bars3dShared::size()
-{
- return m_boundingRect.size();;
-}
-
-const QRect Bars3dShared::boundingRect()
-{
- return m_boundingRect;
-}
-
-void Bars3dShared::setBoundingRect(const QRect boundingRect)
-{
- m_boundingRect = boundingRect;
-}
-
-void Bars3dShared::setWidth(const int width)
-{
- m_boundingRect.setWidth(width);
-}
-
-int Bars3dShared::width()
-{
- return m_boundingRect.width();
-}
-
-void Bars3dShared::setHeight(const int height)
-{
- m_boundingRect.setHeight(height);
-}
-
-int Bars3dShared::height()
-{
- return m_boundingRect.height();
-}
-
-void Bars3dShared::setX(const int x)
-{
- m_boundingRect.setX(x);
-}
-
-int Bars3dShared::x()
-{
- return m_boundingRect.x();
-}
-
-void Bars3dShared::setY(const int y)
-{
- m_boundingRect.setY(y);
-}
-
-int Bars3dShared::y()
-{
- return m_boundingRect.y();
-}
-
-void Bars3dShared::loadBarMesh()
-{
- QString objectFileName = m_objFile;
- if (m_barObj)
- delete m_barObj;
- // If background is disabled, load full version of bar mesh
- if (!m_bgrEnabled)
- objectFileName.append(QStringLiteral("Full"));
- m_barObj = new ObjectHelper(objectFileName);
- m_barObj->load();
-}
-
-void Bars3dShared::loadBackgroundMesh()
-{
- if (!m_isInitialized)
- return;
-
- if (m_backgroundObj)
- delete m_backgroundObj;
- if (m_negativeValues)
- m_backgroundObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/negativeBackground"));
- else
- m_backgroundObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/background"));
- m_backgroundObj->load();
-}
-
-void Bars3dShared::loadGridLineMesh()
-{
- if (m_gridLineObj)
- delete m_gridLineObj;
- m_gridLineObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/bar"));
- m_gridLineObj->load();
-}
-
-void Bars3dShared::loadLabelMesh()
-{
- if (m_labelObj)
- delete m_labelObj;
- m_labelObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/label"));
- m_labelObj->load();
-}
-
-void Bars3dShared::initShaders(const QString &vertexShader, const QString &fragmentShader)
-{
- if (m_barShader)
- delete m_barShader;
- m_barShader = new ShaderHelper(this, vertexShader, fragmentShader);
- m_barShader->initialize();
-}
-
-void Bars3dShared::initSelectionShader()
-{
- if (m_selectionShader)
- delete m_selectionShader;
- m_selectionShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexSelection"),
- QStringLiteral(":/shaders/fragmentSelection"));
- m_selectionShader->initialize();
-}
-
-void Bars3dShared::initSelectionBuffer()
-{
-#ifndef USE_HAX0R_SELECTION
- if (m_selectionTexture) {
- glDeleteFramebuffers(1, &m_selectionFrameBuffer);
- glDeleteRenderbuffers(1, &m_selectionDepthBuffer);
- m_textureHelper->deleteTexture(&m_selectionTexture);
- }
- m_selectionTexture = m_textureHelper->createSelectionTexture(this->size(),
- m_selectionFrameBuffer,
- m_selectionDepthBuffer);
-#endif
-}
-
-#if !defined(QT_OPENGL_ES_2)
-void Bars3dShared::initDepthShader()
-{
- if (m_depthShader)
- delete m_depthShader;
- m_depthShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexDepth"),
- QStringLiteral(":/shaders/fragmentDepth"));
- m_depthShader->initialize();
-}
-
-void Bars3dShared::initDepthBuffer()
-{
- if (m_depthTexture) {
- glDeleteFramebuffers(1, &m_depthFrameBuffer);
- m_textureHelper->deleteTexture(&m_depthTexture);
- }
- m_depthTexture = m_textureHelper->createDepthTexture(this->size(), m_depthFrameBuffer,
- m_shadowQuality);
-}
-#endif
-
-void Bars3dShared::initBackgroundShaders(const QString &vertexShader,
- const QString &fragmentShader)
-{
- if (m_backgroundShader)
- delete m_backgroundShader;
- m_backgroundShader = new ShaderHelper(this, vertexShader, fragmentShader);
- m_backgroundShader->initialize();
-}
-
-void Bars3dShared::initLabelShaders(const QString &vertexShader, const QString &fragmentShader)
-{
- if (m_labelShader)
- delete m_labelShader;
- m_labelShader = new ShaderHelper(this, vertexShader, fragmentShader);
- m_labelShader->initialize();
-}
-
-void Bars3dShared::updateTextures()
-{
- // Drawer has changed; this flag needs to be checked when checking if we need to update labels
- m_updateLabels = true;
-}
-
-void Bars3dShared::calculateSceneScalingFactors()
-{
- // Calculate scene scaling and translation factors
- m_rowWidth = ((m_sampleCount.first + 1) * m_barSpacing.width()) / 2.0f;
- m_columnDepth = ((m_sampleCount.second + 1) * m_barSpacing.height()) / 2.0f;
- m_maxDimension = qMax(m_rowWidth, m_columnDepth);
- m_scaleFactor = qMin((m_sampleCount.first * (m_maxDimension / m_maxSceneSize)),
- (m_sampleCount.second * (m_maxDimension / m_maxSceneSize)));
- m_scaleX = m_barThickness.width() / m_scaleFactor;
- m_scaleZ = m_barThickness.height() / m_scaleFactor;
- //qDebug() << "m_scaleX" << m_scaleX << "m_scaleFactor" << m_scaleFactor;
- //qDebug() << "m_scaleZ" << m_scaleZ << "m_scaleFactor" << m_scaleFactor;
- //qDebug() << "m_rowWidth:" << m_rowWidth << "m_columnDepth:" << m_columnDepth << "m_maxDimension:" << m_maxDimension;
-}
-
-void Bars3dShared::calculateHeightAdjustment(const QPair<GLfloat, GLfloat> &limits)
-{
- // 2.0f = max difference between minimum and maximum value after scaling with m_heightNormalizer
- m_yAdjustment = 2.0f - ((limits.second - limits.first) / m_heightNormalizer);
- //qDebug() << m_yAdjustment;
-}
-
-Bars3dShared::SelectionType Bars3dShared::isSelected(GLint row, GLint bar,
- const QVector3D &selection)
-{
- //static QVector3D prevSel = selection; // TODO: For debugging
- SelectionType isSelectedType = SelectionNone;
-#ifdef USE_HAX0R_SELECTION
- if (selection == Utils::vectorFromColor(m_theme->m_windowColor))
-#else
- if (selection == skipColor)
-#endif
- return isSelectedType; // skip window
-
- //#if !defined(QT_OPENGL_ES_2)
- // QVector3D current = QVector3D((GLuint)row, (GLuint)bar, 0);
- //#else
- QVector3D current = QVector3D((GLubyte)row, (GLubyte)bar, 0);
- //#endif
-
- // TODO: For debugging
- //if (selection != prevSel) {
- // qDebug() << "current" << current.x() << current .y() << current.z();
- // qDebug() << "selection" << selection.x() << selection .y() << selection.z();
- // prevSel = selection;
- //}
- if (current == selection)
- isSelectedType = SelectionBar;
- else if (current.y() == selection.y() && (m_selectionMode == ModeBarAndColumn
- || m_selectionMode == ModeBarRowAndColumn
- || m_selectionMode == ModeZoomColumn))
- isSelectedType = SelectionColumn;
- else if (current.x() == selection.x() && (m_selectionMode == ModeBarAndRow
- || m_selectionMode == ModeBarRowAndColumn
- || m_selectionMode == ModeZoomRow))
- isSelectedType = SelectionRow;
- return isSelectedType;
-}
-
-void Bars3dShared::handleLimitChange()
-{
- // Get the limits
- QPair<GLfloat, GLfloat> limits = m_dataSet->d_ptr->limitValues();
-
- // TODO: What if we have only negative values?
-
- // Check if we have negative values
- if (limits.first < 0 && !m_negativeValues) {
- m_negativeValues = true;
- // Reload background
- loadBackgroundMesh();
- } else if (limits.first >= 0 && m_negativeValues) {
- m_negativeValues = false;
- // Reload background
- loadBackgroundMesh();
- }
-
- // Don't auto-adjust height if tick count is set
- if (m_tickCount == 0) {
- m_heightNormalizer = (GLfloat)qMax(qFabs(limits.second), qFabs(limits.first));
- calculateHeightAdjustment(limits);
- }
-}
-
-void Bars3dShared::closeZoomMode()
-{
- m_zoomActivated = false;
- m_sceneViewPort = QRect(0, 0, this->width(), this->height());
-}
-
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/engine/bars3dshared_p.h b/src/datavis3d/engine/bars3dshared_p.h
deleted file mode 100644
index 2250b7c4..00000000
--- a/src/datavis3d/engine/bars3dshared_p.h
+++ /dev/null
@@ -1,326 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtDataVis3D module.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** 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 Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-
-#ifndef Q3DBARSSHARED_p_H
-#define Q3DBARSSHARED_p_H
-
-#include "QtDataVis3D/qdatavis3dglobal.h"
-#include "QtDataVis3D/qdatavis3namespace.h"
-
-#include <QtCore/QSize>
-#include <QtCore/QObject>
-#include <QtGui/QOpenGLFunctions>
-#include <QtGui/QFont>
-
-#include <QWindow>
-
-class QOpenGLPaintDevice;
-class QPoint;
-class QSizeF;
-class QOpenGLShaderProgram;
-
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
-
-class QDataItem;
-class QDataRow;
-class QDataSet;
-class ShaderHelper;
-class ObjectHelper;
-class TextureHelper;
-class Theme;
-class Drawer;
-class LabelItem;
-class Bars3dSharedPrivate;
-
-class QTENTERPRISE_DATAVIS3D_EXPORT Bars3dShared : public QObject, public QOpenGLFunctions
-{
- Q_OBJECT
-
-public:
- enum SelectionType {
- SelectionNone = 0,
- SelectionBar,
- SelectionRow,
- SelectionColumn
- };
-
- enum MousePressType {
- MouseNone = 0,
- MouseOnScene,
- MouseOnOverview,
- MouseOnZoom,
- MouseRotating,
- MouseOnPinch
- };
-
- QRect m_boundingRect;
- QOpenGLPaintDevice *m_paintDevice;
- ShaderHelper *m_barShader;
- ShaderHelper *m_depthShader;
- ShaderHelper *m_selectionShader;
- ShaderHelper *m_backgroundShader;
- ShaderHelper *m_labelShader;
- ObjectHelper *m_barObj;
- ObjectHelper *m_backgroundObj;
- ObjectHelper *m_gridLineObj;
- ObjectHelper *m_labelObj;
- QPair<int, int> m_sampleCount;
- QString m_objFile;
- MousePressType m_mousePressed;
- QPoint m_mousePos;
- GLint m_zoomLevel;
- GLfloat m_zoomAdjustment;
- GLfloat m_horizontalRotation;
- GLfloat m_verticalRotation;
- QSizeF m_barThickness;
- QSizeF m_barSpacing;
- GLfloat m_heightNormalizer;
- GLfloat m_yAdjustment;
- GLfloat m_rowWidth;
- GLfloat m_columnDepth;
- GLfloat m_maxDimension;
- GLfloat m_scaleX;
- GLfloat m_scaleZ;
- GLfloat m_scaleFactor;
- GLfloat m_maxSceneSize;
- Theme *m_theme;
- bool m_isInitialized;
- SelectionMode m_selectionMode;
- QDataItem *m_selectedBar;
- QDataRow *m_zoomSelection;
- QDataSet *m_dataSet;
- QString m_axisLabelX;
- QString m_axisLabelZ;
- QString m_axisLabelY;
- QRect m_sceneViewPort;
- QRect m_zoomViewPort;
- bool m_zoomActivated;
- TextureHelper *m_textureHelper;
- LabelTransparency m_labelTransparency;
- QFont m_font;
- Drawer *m_drawer;
- bool m_xFlipped;
- bool m_zFlipped;
- bool m_yFlipped;
- GLuint m_bgrTexture;
- GLuint m_depthTexture;
- GLuint m_selectionTexture;
- GLuint m_depthFrameBuffer;
- GLuint m_selectionFrameBuffer;
- GLuint m_selectionDepthBuffer;
- bool m_updateLabels;
- bool m_gridEnabled;
- bool m_bgrEnabled;
- ShadowQuality m_shadowQuality;
- GLfloat m_shadowQualityToShader;
- GLint m_tickCount;
- GLfloat m_tickStep;
- bool m_negativeValues;
- GLuint m_fbohandle;
- QSize m_size;
-
-public:
- explicit Bars3dShared(QRect rect, GLuint fbohandle=0);
- ~Bars3dShared();
-
- void initializeOpenGL();
- void render();
-
- // Add a row of data. Each new row is added to the front of the sample space, moving previous
- // rows back (if sample space is more than one row deep)
- void addDataRow(const QVector<GLfloat> &dataRow,
- const QString &labelRow = QString(),
- const QVector<QString> &labelsColumn = QVector<QString>());
- // ownership of dataItems is transferred
- void addDataRow(const QVector<QDataItem*> &dataRow,
- const QString &labelRow = QString(),
- const QVector<QString> &labelsColumn = QVector<QString>());
- // ownership of dataRow is transferred
- void addDataRow(QDataRow *dataRow);
-
- // Add complete data set at a time, as a vector of data rows
- void addDataSet(const QVector< QVector<GLfloat> > &data,
- const QVector<QString> &labelsRow = QVector<QString>(),
- const QVector<QString> &labelsColumn = QVector<QString>());
-
- // ownership of dataItems is transferred
- void addDataSet(const QVector< QVector<QDataItem*> > &data,
- const QVector<QString> &labelsRow = QVector<QString>(),
- const QVector<QString> &labelsColumn = QVector<QString>());
- // ownership of dataSet is transferred
- void addDataSet(QDataSet* dataSet);
-
- // bar thickness, spacing between bars, and is spacing relative to thickness or absolute
- // y -component sets the thickness/spacing of z -direction
- // With relative 0.0f means side-to-side, 1.0f = one thickness in between
- void setBarSpecs(QSizeF thickness = QSizeF(1.0f, 1.0f),
- QSizeF spacing = QSizeF(1.0f, 1.0f),
- bool relative = true);
-
- // bar type; bars (=cubes), pyramids, cones, cylinders, etc.
- void setBarType(BarStyle style, bool smooth = false);
-
- // override bar type with own mesh
- void setMeshFileName(const QString &objFileName);
-
- // how many samples per row and column, and names for axes
- void setupSampleSpace(int samplesRow, int samplesColumn,
- const QString &labelRow = QString(),
- const QString &labelColumn = QString(),
- const QString &labelHeight = QString());
-
- // Select preset camera placement
- void setCameraPreset(CameraPreset preset);
-
- // Set camera rotation if you don't want to use the presets (in horizontal (-180...180) and
- // vertical (0...90) (or (-90...90) if there are negative values) angles and distance in
- // percentage (10...500))
- void setCameraPosition(GLfloat horizontal, GLfloat vertical, GLint distance = 100);
-
- // Set theme (bar colors, shaders, window color, background colors, light intensity and text
- // colors are affected)
- void setTheme(ColorTheme theme);
-
- // Set color if you don't want to use themes. Set uniform to false if you want the (height)
- // color to change from bottom to top
- void setBarColor(QColor baseColor, QColor heightColor, QColor depthColor,
- bool uniform = true);
-
- // Set tick count and step. Note; tickCount * step should be the maximum possible value of data
- // set. Minimum is the absolute minimum possible value a bar can have. This is especially
- // important to set if values can be negative.
- void setTickCount(GLint tickCount, GLfloat step, GLfloat minimum = 0.0f);
-
- // TODO: light placement API
-
- // Size
- const QSize size();
- const QRect boundingRect();
- void setBoundingRect(const QRect boundingRect);
- void setWidth(const int width);
- int width();
- void setHeight(const int height);
- int height();
- void setX(const int x);
- int x();
- void setY(const int y);
- int y();
-
- // Change selection mode; single bar, bar and row, bar and column, or all
- void setSelectionMode(SelectionMode mode);
- SelectionMode selectionMode();
-
- // Font size adjustment
- void setFontSize(float fontsize);
- float fontSize();
-
- // Set font
- void setFont(const QFont &font);
- QFont font();
-
- // Label transparency adjustment
- void setLabelTransparency(LabelTransparency transparency);
- LabelTransparency labelTransparency();
-
- // Enable or disable background grid
- void setGridEnabled(bool enable);
- bool gridEnabled();
-
- // Enable or disable background mesh
- void setBackgroundEnabled(bool enable);
- bool backgroundEnabled();
-
- // Adjust shadow quality
- void setShadowQuality(ShadowQuality quality);
- ShadowQuality shadowQuality();
-
-#if defined(Q_OS_ANDROID)
- void mouseDoubleClickEvent(QMouseEvent *event);
- void touchEvent(QTouchEvent *event);
-#endif
- void mousePressEvent(QMouseEvent *event);
- void mouseReleaseEvent(QMouseEvent *event);
- void mouseMoveEvent(QMouseEvent *event);
- void wheelEvent(QWheelEvent *event);
- void resizeNotify();
-
- void loadBarMesh();
- void loadBackgroundMesh();
- void loadGridLineMesh();
- void loadLabelMesh();
- void initShaders(const QString &vertexShader, const QString &fragmentShader);
- void initSelectionShader();
- void initBackgroundShaders(const QString &vertexShader, const QString &fragmentShader);
- void initLabelShaders(const QString &vertexShader, const QString &fragmentShader);
- void initSelectionBuffer();
-#if !defined(QT_OPENGL_ES_2)
- void initDepthShader();
- void initDepthBuffer();
-#endif
- void updateTextures();
- void calculateSceneScalingFactors();
- void calculateHeightAdjustment(const QPair<GLfloat, GLfloat> &limits);
- SelectionType isSelected(GLint row, GLint bar, const QVector3D &selection);
- void handleLimitChange();
- void closeZoomMode();
-
-private:
- void drawZoomScene();
- void drawScene();
- Q_DISABLE_COPY(Bars3dShared)
-
- friend class DeclarativeBars;
- friend class DeclarativeBarsRenderer;
-};
-
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
-
-#endif
diff --git a/src/datavis3d/engine/drawer.cpp b/src/datavis3d/engine/drawer.cpp
index 3c4d30cf..5d524963 100644
--- a/src/datavis3d/engine/drawer.cpp
+++ b/src/datavis3d/engine/drawer.cpp
@@ -1,51 +1,28 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
-#include "qdatavis3namespace.h"
+#include "qdatavis3denums.h"
#include "drawer_p.h"
#include "shaderhelper_p.h"
#include "objecthelper_p.h"
+#include "abstractobjecthelper_p.h"
+#include "surfaceobject_p.h"
#include "camerahelper_p.h"
-#include "qdataitem.h"
-#include "qdataitem_p.h"
#include "utils_p.h"
#include "texturehelper_p.h"
#include <QMatrix4x4>
@@ -62,9 +39,9 @@ public:
};
StaticLibInitializer staticLibInitializer;
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVIS3D_BEGIN_NAMESPACE
-Drawer::Drawer(const Theme &theme, const QFont &font, LabelTransparency transparency)
+Drawer::Drawer(const Theme &theme, const QFont &font, QDataVis::LabelTransparency transparency)
: m_theme(theme),
m_font(font),
m_transparency(transparency),
@@ -96,15 +73,21 @@ void Drawer::setFont(const QFont &font)
emit drawerChanged();
}
-void Drawer::setTransparency(LabelTransparency transparency)
+void Drawer::setTransparency(QDataVis::LabelTransparency transparency)
{
m_transparency = transparency;
emit drawerChanged();
}
-void Drawer::drawObject(ShaderHelper *shader, ObjectHelper *object, GLuint textureId,
+void Drawer::drawObject(ShaderHelper *shader, AbstractObjectHelper *object, GLuint textureId,
GLuint depthTextureId)
{
+ // Store the GL state before changing
+ GLint oldActiveTex[1];
+ glGetIntegerv(GL_ACTIVE_TEXTURE, oldActiveTex);
+ GLint oldTexId[1];
+ glGetIntegerv(GL_TEXTURE_BINDING_2D, oldTexId);
+
if (textureId) {
// Activate texture
glActiveTexture(GL_TEXTURE0);
@@ -140,29 +123,63 @@ void Drawer::drawObject(ShaderHelper *shader, ObjectHelper *object, GLuint textu
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, object->elementBuf());
// Draw the triangles
- glDrawElements(GL_TRIANGLES, object->indexCount(), GL_UNSIGNED_SHORT, (void*)0);
+ glDrawElements(GL_TRIANGLES, object->indexCount(), object->indicesType(), (void*)0);
// Free buffers
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- if (textureId || depthTextureId) {
- glBindTexture(GL_TEXTURE_2D, 0);
+ if (textureId || depthTextureId)
glDisableVertexAttribArray(shader->uvAtt());
- }
+
glDisableVertexAttribArray(shader->normalAtt());
glDisableVertexAttribArray(shader->posAtt());
+
+ // Restore the GL state
+ glActiveTexture(*oldActiveTex);
+ glBindTexture(GL_TEXTURE_2D, *oldTexId);
}
-void Drawer::drawLabel(const QDataItem &item, const LabelItem &label,
+void Drawer::drawSurfaceGrid(ShaderHelper *shader, SurfaceObject *object)
+{
+ // Store the GL state before changing
+ GLint oldActiveTex[1];
+ glGetIntegerv(GL_ACTIVE_TEXTURE, oldActiveTex);
+ GLint oldTexId[1];
+ glGetIntegerv(GL_TEXTURE_BINDING_2D, oldTexId);
+
+ // 1st attribute buffer : vertices
+ glEnableVertexAttribArray(shader->posAtt());
+ glBindBuffer(GL_ARRAY_BUFFER, object->vertexBuf());
+ glVertexAttribPointer(shader->posAtt(), 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
+
+ // Index buffer
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, object->gridElementBuf());
+
+ // Draw the lines
+ glDrawElements(GL_LINES, object->gridIndexCount(), object->indicesType(), (void*)0);
+
+ // Free buffers
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+ glDisableVertexAttribArray(shader->posAtt());
+
+ // Restore the GL state
+ glActiveTexture(*oldActiveTex);
+ glBindTexture(GL_TEXTURE_2D, *oldTexId);
+}
+
+void Drawer::drawLabel(const AbstractRenderItem &item, const LabelItem &labelItem,
const QMatrix4x4 &viewmatrix, const QMatrix4x4 &projectionmatrix,
const QVector3D &positionComp, const QVector3D &rotation,
- GLfloat maxHeight, SelectionMode mode,
- ShaderHelper *shader, ObjectHelper *object, bool useDepth, bool rotateAlong,
+ GLfloat itemHeight, QDataVis::SelectionMode mode,
+ ShaderHelper *shader, ObjectHelper *object,
+ CameraHelper *camera,
+ bool useDepth, bool rotateAlong,
LabelPosition position, Qt::AlignmentFlag alignment)
{
// Draw label
- LabelItem labelItem = label;
if (!labelItem.textureId())
return; // No texture, skip
@@ -184,20 +201,20 @@ void Drawer::drawLabel(const QDataItem &item, const LabelItem &label,
}
case LabelMid: {
// Use this for positioning with absolute item y position value
- yPosition = item.d_ptr->translation().y();
+ yPosition = item.translation().y();
break;
}
case LabelHigh: {
// TODO: Fix this. Can't seem to get it right (if ok with positive-only bars, doesn't look good on +- and vice versa)
- yPosition = item.d_ptr->translation().y() + (item.d_ptr->value() / maxHeight) / 2.0f;
+ yPosition = item.translation().y() + itemHeight / 2.0f;
break;
}
case LabelOver: {
float mod = 0.1f;
- if (item.d_ptr->value() < 0)
+ if (itemHeight < 0)
mod = -0.1f;
- yPosition = item.d_ptr->translation().y() - (positionComp.y() / 2.0f - 0.2f)
- + (item.d_ptr->value() / maxHeight) + mod;
+ yPosition = item.translation().y() - (positionComp.y() / 2.0f - 0.2f)
+ + itemHeight + mod;
break;
}
case LabelBottom: {
@@ -232,16 +249,16 @@ void Drawer::drawLabel(const QDataItem &item, const LabelItem &label,
switch (alignment) {
case Qt::AlignLeft: {
xAlignment = (-(GLfloat)textureSize.width() * scaleFactor)
- * qFabs(cos(rotation.y() * m_pi / 180.0f));
+ * qFabs(qCos(qDegreesToRadians(rotation.y())));
zAlignment = ((GLfloat)textureSize.width() * scaleFactor)
- * qFabs(sin(rotation.y() * m_pi / 180.0f));
+ * qFabs(qSin(qDegreesToRadians(rotation.y())));
break;
}
case Qt::AlignRight: {
xAlignment = ((GLfloat)textureSize.width() * scaleFactor)
- * qFabs(cos(rotation.y() * m_pi / 180.0f));
+ * qFabs(qCos(qDegreesToRadians(rotation.y())));
zAlignment = (-(GLfloat)textureSize.width() * scaleFactor)
- * qFabs(sin(rotation.y() * m_pi / 180.0f));
+ * qFabs(qSin(qDegreesToRadians(rotation.y())));
break;
}
default: {
@@ -250,24 +267,30 @@ void Drawer::drawLabel(const QDataItem &item, const LabelItem &label,
}
if (position < LabelBottom) {
- xPosition = item.d_ptr->translation().x();
+ xPosition = item.translation().x();
if (useDepth)
- zPosition = item.d_ptr->translation().z();
- else if (ModeZoomColumn == mode)
- xPosition = -(item.d_ptr->translation().z()) + positionComp.z(); // flip first to left
+ zPosition = item.translation().z();
+ else if (QDataVis::ModeZoomColumn == mode)
+ xPosition = -(item.translation().z()) + positionComp.z(); // flip first to left
}
// Position label
modelMatrix.translate(xPosition + xAlignment, yPosition, zPosition + zAlignment);
// Rotate
- modelMatrix.rotate(rotation.z(), 0.0f, 0.0f, 1.0f);
+ // TODO: We should convert rotations to use quaternions to avoid rotation order problems
+ //QQuaternion rotQuatX = QQuaternion::fromAxisAndAngle(1.0f, 0.0f, 0.0f, rotation.x());
+ //QQuaternion rotQuatY = QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, rotation.y());
+ //QQuaternion rotQuatZ = QQuaternion::fromAxisAndAngle(0.0f, 0.0f, 1.0f, rotation.z());
+ //QQuaternion rotQuaternion = rotQuatX + rotQuatY + rotQuatZ;
+ //modelMatrix.rotate(rotQuaternion);
modelMatrix.rotate(rotation.y(), 0.0f, 1.0f, 0.0f);
+ modelMatrix.rotate(rotation.z(), 0.0f, 0.0f, 1.0f);
modelMatrix.rotate(rotation.x(), 1.0f, 0.0f, 0.0f);
if (useDepth && !rotateAlong) {
// Apply negative camera rotations to keep labels facing camera
- QPointF camRotations = CameraHelper::getCameraRotations();
+ QPointF camRotations = camera->getCameraRotations();
modelMatrix.rotate(-camRotations.x(), 0.0f, 1.0f, 0.0f);
modelMatrix.rotate(-camRotations.y(), 1.0f, 0.0f, 0.0f);
}
@@ -286,21 +309,17 @@ void Drawer::drawLabel(const QDataItem &item, const LabelItem &label,
drawObject(shader, object, labelItem.textureId());
}
-void Drawer::generateLabelTexture(QDataItem *item)
+void Drawer::generateLabelTexture(AbstractRenderItem *item)
{
- LabelItem labelItem = item->d_ptr->label();
- generateLabelItem(&labelItem, item->d_ptr->valueStr());
- item->d_ptr->setLabel(labelItem);
+ LabelItem &labelItem = item->labelItem();
+ generateLabelItem(labelItem, item->label());
}
-void Drawer::generateLabelItem(LabelItem *item, const QString &text)
+void Drawer::generateLabelItem(LabelItem &item, const QString &text)
{
initializeOpenGL();
- // Delete previous texture, if there is one
- GLuint labelTexture = item->textureId();
- if (labelTexture)
- glDeleteTextures(1, &labelTexture);
+ item.clear();
// Create labels
// Print label into a QImage using QPainter
@@ -311,9 +330,9 @@ void Drawer::generateLabelItem(LabelItem *item, const QString &text)
m_transparency);
// Set label size
- item->setSize(label.size());
- // Insert text texture into label
- item->setTextureId(m_textureHelper->create2DTexture(label, true, true));
+ item.setSize(label.size());
+ // Insert text texture into label (also deletes the old texture)
+ item.setTextureId(m_textureHelper->create2DTexture(label, true, true));
}
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/engine/drawer_p.h b/src/datavis3d/engine/drawer_p.h
index e31ab0cb..3139fbe0 100644
--- a/src/datavis3d/engine/drawer_p.h
+++ b/src/datavis3d/engine/drawer_p.h
@@ -1,41 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
@@ -43,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the Qt API. It exists purely as an
+// This file is not part of the QtDataVis3D API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -52,46 +29,63 @@
#ifndef DRAWER_P_H
#define DRAWER_P_H
-#include "QtDataVis3D/qdatavis3dglobal.h"
-#include "QtDataVis3D/qdatavis3namespace.h"
+#include "datavis3dglobal_p.h"
#include "q3dbars.h"
#include "theme_p.h"
#include "labelitem_p.h"
+#include "abstractrenderitem_p.h"
#include <QFont>
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVIS3D_BEGIN_NAMESPACE
-class QDataItem;
class ShaderHelper;
class ObjectHelper;
+class AbstractObjectHelper;
+class SurfaceObject;
class TextureHelper;
+class CameraHelper;
class Drawer : public QObject, public QOpenGLFunctions
{
Q_OBJECT
public:
- explicit Drawer(const Theme &theme, const QFont &font, LabelTransparency transparency);
+ enum LabelPosition {
+ LabelBelow = 0,
+ LabelLow,
+ LabelMid,
+ LabelHigh,
+ LabelOver,
+ LabelBottom, // Absolute positions from here onward, used for axes (QDataItem is ignored)
+ LabelTop,
+ LabelLeft,
+ LabelRight
+ };
+
+public:
+ explicit Drawer(const Theme &theme, const QFont &font, QDataVis::LabelTransparency transparency);
~Drawer();
void initializeOpenGL();
void setTheme(const Theme &theme);
void setFont(const QFont &font);
- void setTransparency(LabelTransparency transparency);
+ void setTransparency(QDataVis::LabelTransparency transparency);
- void drawObject(ShaderHelper *shader, ObjectHelper *object, GLuint textureId = 0,
+ void drawObject(ShaderHelper *shader, AbstractObjectHelper *object, GLuint textureId = 0,
GLuint depthTextureId = 0);
- void drawLabel(const QDataItem &item, const LabelItem &label,
+ void drawSurfaceGrid(ShaderHelper *shader, SurfaceObject *object);
+ void drawLabel(const AbstractRenderItem &item, const LabelItem &labelItem,
const QMatrix4x4 &viewmatrix, const QMatrix4x4 &projectionmatrix,
- const QVector3D &positionComp, const QVector3D &rotation, GLfloat maxHeight,
- SelectionMode mode, ShaderHelper *shader, ObjectHelper *object,
+ const QVector3D &positionComp, const QVector3D &rotation, GLfloat itemHeight,
+ QDataVis::SelectionMode mode, ShaderHelper *shader, ObjectHelper *object,
+ CameraHelper *camera,
bool useDepth = false, bool rotateAlong = false,
LabelPosition position = LabelOver,
Qt::AlignmentFlag alignment = Qt::AlignCenter);
- void generateLabelTexture(QDataItem *item);
- void generateLabelItem(LabelItem *item, const QString &text);
+ void generateLabelTexture(AbstractRenderItem *item);
+ void generateLabelItem(LabelItem &item, const QString &text);
Q_SIGNALS:
void drawerChanged();
@@ -99,10 +93,10 @@ Q_SIGNALS:
private:
Theme m_theme;
QFont m_font;
- LabelTransparency m_transparency;
+ QDataVis::LabelTransparency m_transparency;
TextureHelper *m_textureHelper;
};
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
+QT_DATAVIS3D_END_NAMESPACE
#endif
diff --git a/src/datavis3d/engine/engine.pri b/src/datavis3d/engine/engine.pri
index b220120f..5dc415e1 100644
--- a/src/datavis3d/engine/engine.pri
+++ b/src/datavis3d/engine/engine.pri
@@ -1,29 +1,44 @@
-SOURCES += $$PWD/q3dwindow.cpp \
- $$PWD/q3dbars.cpp \
- $$PWD/q3dmaps.cpp \
- $$PWD/qdataitem.cpp \
- $$PWD/qdatarow.cpp \
- $$PWD/qdataset.cpp \
- $$PWD/theme.cpp \
- $$PWD/drawer.cpp \
- $$PWD/labelitem.cpp \
- $$PWD/bars3dshared.cpp
-
HEADERS += $$PWD/q3dwindow_p.h \
$$PWD/q3dwindow.h \
$$PWD/q3dbars.h \
$$PWD/q3dbars_p.h \
$$PWD/q3dmaps.h \
$$PWD/q3dmaps_p.h \
- $$PWD/qdataitem.h \
- $$PWD/qdataitem_p.h \
- $$PWD/qdatarow.h \
- $$PWD/qdatarow_p.h \
- $$PWD/qdataset.h \
- $$PWD/qdataset_p.h \
$$PWD/theme_p.h \
$$PWD/drawer_p.h \
- $$PWD/labelitem_p.h \
- $$PWD/bars3dshared_p.h
+ $$PWD/bars3dcontroller_p.h \
+ $$PWD/bars3drenderer_p.h \
+ $$PWD/maps3dcontroller_p.h \
+ $$PWD/maps3drenderer_p.h \
+ $$PWD/q3dsurface.h \
+ $$PWD/q3dsurface_p.h \
+ $$PWD/surface3dcontroller_p.h \
+ $$PWD/surface3drenderer_p.h \
+ $$PWD/abstract3dcontroller_p.h \
+ $$PWD/q3dscatter.h \
+ $$PWD/q3dscatter_p.h \
+ $$PWD/scatter3dcontroller_p.h \
+ $$PWD/scatter3drenderer_p.h \
+ $$PWD/axisrendercache_p.h \
+ $$PWD/abstract3drenderer_p.h
+
+SOURCES += $$PWD/q3dwindow.cpp \
+ $$PWD/q3dbars.cpp \
+ $$PWD/q3dmaps.cpp \
+ $$PWD/theme.cpp \
+ $$PWD/drawer.cpp \
+ $$PWD/bars3dcontroller.cpp \
+ $$PWD/bars3drenderer.cpp \
+ $$PWD/maps3dcontroller.cpp \
+ $$PWD/maps3drenderer.cpp \
+ $$PWD/q3dsurface.cpp \
+ $$PWD/surface3drenderer.cpp \
+ $$PWD/surface3dcontroller.cpp \
+ $$PWD/abstract3dcontroller.cpp \
+ $$PWD/q3dscatter.cpp \
+ $$PWD/scatter3dcontroller.cpp \
+ $$PWD/scatter3drenderer.cpp \
+ $$PWD/axisrendercache.cpp \
+ $$PWD/abstract3drenderer.cpp
RESOURCES += engine/engine.qrc
diff --git a/src/datavis3d/engine/engine.qrc b/src/datavis3d/engine/engine.qrc
index 2588197a..af6e899d 100644
--- a/src/datavis3d/engine/engine.qrc
+++ b/src/datavis3d/engine/engine.qrc
@@ -26,6 +26,8 @@
<file alias="bevelbarSmoothFull">meshes/barFilledSmooth.obj</file>
<file alias="barFull">meshes/cubeFilledFlat.obj</file>
<file alias="barSmoothFull">meshes/cubeFilledSmooth.obj</file>
+ <file alias="dotSmooth">meshes/scatterdot.obj</file>
+ <file alias="dot">meshes/scatterdotFlat.obj</file>
</qresource>
<qresource prefix="/shaders">
<file alias="fragment">shaders/default.frag</file>
@@ -48,6 +50,12 @@
<file alias="fragmentES2">shaders/default_ES2.frag</file>
<file alias="vertexES2">shaders/default_ES2.vert</file>
<file alias="fragmentTextureES2">shaders/texture_ES2.frag</file>
+ <file alias="fragmentSurface">shaders/surface.frag</file>
+ <file alias="vertexSurface">shaders/surface.vert</file>
+ <file alias="fragmentSurfaceGrid">shaders/surfaceGrid.frag</file>
+ <file alias="vertexSurfaceGrid">shaders/surfaceGrid.vert</file>
+ <file alias="vertexSurfaceFlat">shaders/surfaceFlat.vert</file>
+ <file alias="fragmentSurfaceFlat">shaders/surfaceFlat.frag</file>
</qresource>
<qresource prefix="/textures"/>
</RCC>
diff --git a/src/datavis3d/engine/labelitem.cpp b/src/datavis3d/engine/labelitem.cpp
deleted file mode 100644
index 19051dd7..00000000
--- a/src/datavis3d/engine/labelitem.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtDataVis3D module.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** 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 Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "labelitem_p.h"
-
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
-
-LabelItem::LabelItem()
- : m_size(QSize(0, 0)),
- m_textureId(0)
-{
-}
-
-LabelItem::~LabelItem()
-{
-}
-
-void LabelItem::setSize(const QSize &size)
-{
- m_size = size;
-}
-
-QSize LabelItem::size()
-{
- return m_size;
-}
-
-void LabelItem::setTextureId(GLuint textureId)
-{
- m_textureId = textureId;
-}
-
-GLuint LabelItem::textureId()
-{
- return m_textureId;
-}
-
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/engine/labelitem_p.h b/src/datavis3d/engine/labelitem_p.h
deleted file mode 100644
index 47e480b2..00000000
--- a/src/datavis3d/engine/labelitem_p.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtDataVis3D module.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** 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 Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-
-#ifndef LABELITEM_P_H
-#define LABELITEM_P_H
-
-#include "qdatavis3dglobal.h"
-#include <QOpenGLFunctions>
-#include <QSize>
-
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
-
-class LabelItem
-{
-public:
- explicit LabelItem();
- ~LabelItem();
-
- void setSize(const QSize &size);
- QSize size();
- void setTextureId(GLuint textureId);
- GLuint textureId();
-
-private:
- QSize m_size;
- GLuint m_textureId;
-};
-
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
-
-#endif
diff --git a/src/datavis3d/engine/maps3dcontroller.cpp b/src/datavis3d/engine/maps3dcontroller.cpp
new file mode 100644
index 00000000..e86bdfa2
--- /dev/null
+++ b/src/datavis3d/engine/maps3dcontroller.cpp
@@ -0,0 +1,1763 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "maps3dcontroller_p.h"
+#include "maps3drenderer_p.h"
+#include "camerahelper_p.h"
+#include "shaderhelper_p.h"
+#include "objecthelper_p.h"
+#include "texturehelper_p.h"
+#include "theme_p.h"
+#include "utils_p.h"
+#include "drawer_p.h"
+#include "maprenderitem_p.h"
+#include "qmapdataproxy_p.h"
+
+#include <QOpenGLFunctions>
+#include <QMatrix4x4>
+#include <QMouseEvent>
+#include <qmath.h>
+
+#include <QDebug>
+
+//#define DISPLAY_RENDER_SPEED
+
+// Commenting this draws the shadow map with perspective projection. Otherwise it's drawn in
+// orthographic projection.
+//#define USE_WIDER_SHADOWS
+
+// You can verify that depth buffer drawing works correctly by uncommenting this.
+// You should see the scene from where the light is
+//#define SHOW_DEPTH_TEXTURE_SCENE
+
+#ifdef DISPLAY_RENDER_SPEED
+#include <QTime>
+#endif
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+//#define DISPLAY_FULL_DATA_ON_SELECTION // Append selection value text with row and column labels
+
+const GLfloat gridLineWidth = 0.005f;
+GLfloat distanceMod = 0.0f;
+static QVector3D skipColor = QVector3D(255, 255, 255); // Selection texture's background color
+
+Maps3DController::Maps3DController(const QRect &rect)
+ : m_camera(new CameraHelper()),
+ m_barShader(0),
+ m_depthShader(0),
+ m_selectionShader(0),
+ m_backgroundShader(0),
+ m_labelShader(0),
+ m_barObj(0),
+ m_backgroundObj(0),
+ m_gridLineObj(0),
+ m_labelObj(0),
+ m_objFile(QStringLiteral(":/defaultMeshes/bar")),
+ m_mousePressed(MouseNone),
+ m_mousePos(QPoint(0, 0)),
+ m_zoomLevel(100),
+ m_autoScaleAdjustment(1.0f),
+ m_horizontalRotation(0.0f),
+ m_verticalRotation(45.0f),
+ m_barThickness(QVector3D(1.0f, 1.0f, 1.0f)),
+ m_heightNormalizer(0.0f),
+ m_yAdjustment(0.0f),
+ m_scaleFactor(1.0f),
+ m_theme(new Theme()),
+ m_isInitialized(false),
+ m_selectionMode(QDataVis::ModeItem),
+ m_selectedBar(0),
+ m_previouslySelectedBar(0),
+ m_axisLabelX(QStringLiteral("X")),
+ m_axisLabelZ(QStringLiteral("Z")),
+ m_axisLabelY(QStringLiteral("Y")),
+ m_sceneViewPort(rect.x(), rect.y(), rect.width(), rect.height()),
+ m_zoomViewPort(rect.x(), rect.y(), rect.width(), rect.height()),
+ m_zoomActivated(false),
+ m_textureHelper(new TextureHelper()),
+ m_labelTransparency(QDataVis::TransparencyFromTheme),
+ m_font(QFont(QStringLiteral("Arial"))),
+ m_drawer(new Drawer(*m_theme, m_font, m_labelTransparency)),
+ m_areaSize(QSizeF(1.0f, 1.0f)),
+ m_bgrTexture(0),
+ m_depthTexture(0),
+ m_selectionTexture(0),
+ m_depthFrameBuffer(0),
+ m_selectionFrameBuffer(0),
+ m_selectionDepthBuffer(0),
+ m_updateLabels(true),
+ m_adjustDirection(Q3DMaps::AdjustHeight),
+ m_shadowQuality(QDataVis::ShadowLow),
+ m_shadowQualityToShader(33.3f),
+ m_bgrHasAlpha(false),
+ m_boundingRect(rect.x(), rect.y(), rect.width(), rect.height()),
+ m_data(0),
+ m_valuesDirty(false)
+{
+ //m_data->setDrawer(m_drawer);
+ //QObject::connect(m_drawer, &Drawer::drawerChanged, this, &Maps3DController::updateTextures);
+}
+
+Maps3DController::~Maps3DController()
+{
+ m_textureHelper->glDeleteFramebuffers(1, &m_depthFrameBuffer);
+ m_textureHelper->glDeleteFramebuffers(1, &m_selectionFrameBuffer);
+ m_textureHelper->glDeleteRenderbuffers(1, &m_selectionDepthBuffer);
+ m_textureHelper->deleteTexture(&m_selectionTexture);
+ m_textureHelper->deleteTexture(&m_bgrTexture);
+ delete m_barShader;
+ delete m_selectionShader;
+ delete m_backgroundShader;
+ delete m_barObj;
+ delete m_backgroundObj;
+ delete m_gridLineObj;
+ delete m_textureHelper;
+ delete m_drawer;
+ delete m_camera;
+}
+
+void Maps3DController::initializeOpenGL()
+{
+ // Initialization is called multiple times when Qt Quick components are used
+ if (m_isInitialized)
+ return;
+
+ m_renderer = new Maps3DRenderer(this);
+ initializeOpenGLFunctions();
+
+ m_textureHelper = new TextureHelper();
+ m_drawer->initializeOpenGL();
+
+ // Initialize shaders
+#if !defined(QT_OPENGL_ES_2)
+ if (m_shadowQuality > QDataVis::ShadowNone) {
+ if (!m_theme->m_uniformColor) {
+ initShaders(QStringLiteral(":/shaders/vertexShadow"),
+ QStringLiteral(":/shaders/fragmentShadowNoTexColorOnY"));
+ } else {
+ initShaders(QStringLiteral(":/shaders/vertexShadow"),
+ QStringLiteral(":/shaders/fragmentShadowNoTex"));
+ }
+ initBackgroundShaders(QStringLiteral(":/shaders/vertexShadow"),
+ QStringLiteral(":/shaders/fragmentShadow"));
+ } else {
+ if (!m_theme->m_uniformColor) {
+ initShaders(QStringLiteral(":/shaders/vertex"),
+ QStringLiteral(":/shaders/fragmentColorOnY"));
+ } else {
+ initShaders(QStringLiteral(":/shaders/vertex"),
+ QStringLiteral(":/shaders/fragment"));
+ }
+ initBackgroundShaders(QStringLiteral(":/shaders/vertexTexture"),
+ QStringLiteral(":/shaders/fragmentTexture"));
+ }
+#else
+ if (!m_theme->m_uniformColor) {
+ initShaders(QStringLiteral(":/shaders/vertexES2"),
+ QStringLiteral(":/shaders/fragmentColorOnYES2"));
+ } else {
+ initShaders(QStringLiteral(":/shaders/vertexES2"),
+ QStringLiteral(":/shaders/fragmentES2"));
+ }
+ initBackgroundShaders(QStringLiteral(":/shaders/vertexTexture"), // Same vertex shader ok for ES2
+ QStringLiteral(":/shaders/fragmentTextureES2"));
+#endif
+ initLabelShaders(QStringLiteral(":/shaders/vertexLabel"),
+ QStringLiteral(":/shaders/fragmentLabel"));
+
+#if !defined(QT_OPENGL_ES_2)
+ // Init depth shader (for shadows). Init in any case, easier to handle shadow activation if done via api.
+ initDepthShader();
+#endif
+
+ // Init selection shader
+ initSelectionShader();
+
+ // Load default mesh
+ loadBarMesh();
+
+ // Load grid line mesh
+ loadGridLineMesh();
+
+ // Load label mesh
+ loadLabelMesh();
+
+ // Set OpenGL features
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_LESS);
+ glEnable(GL_CULL_FACE);
+ glCullFace(GL_BACK);
+
+#if !defined(QT_OPENGL_ES_2)
+ glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
+ glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
+ glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
+#endif
+
+ // Set initial camera position
+ // X must be 0 for rotation to work - we can use "setCameraRotation" for setting it later
+ m_camera->setDefaultCameraOrientation(QVector3D(0.0f, 0.0f, 1.0f + 2.9f * zComp),
+ QVector3D(0.0f, 0.0f, zComp),
+ QVector3D(0.0f, 1.0f, 0.0f));
+
+ // Adjust to default rotation
+ setCameraPosition(m_horizontalRotation, m_verticalRotation, m_zoomLevel);
+
+ // Set view port
+ glViewport(0, 0, width(), height());
+
+ // Set initialized -flag
+ m_isInitialized = true;
+
+ // Resize in case we've missed resize events
+ // Resize calls initSelectionBuffer and initDepthBuffer, so they don't need to be called here
+ resizeNotify();
+
+ // Load background mesh (we need to be initialized first)
+ loadBackgroundMesh();
+
+ // Update default light position
+#ifndef USE_WIDER_SHADOWS
+ distanceMod = 5.0f;
+#endif
+}
+
+void Maps3DController::synchDataToRenderer()
+{
+ // TODO: Implement!
+}
+
+
+/*!
+ * \internal
+ */
+void Maps3DController::render(const GLuint defaultFboHandle)
+{
+ if (!m_isInitialized)
+ return;
+
+#ifdef DISPLAY_RENDER_SPEED
+ // For speed computation
+ static bool firstRender = true;
+ static QTime lastTime;
+ static GLint nbFrames = 0;
+ if (firstRender) {
+ lastTime.start();
+ firstRender = false;
+ }
+
+ // Measure speed (as milliseconds per frame)
+ nbFrames++;
+ if (lastTime.elapsed() >= 1000) { // print only if last measurement was more than 1s ago
+ qDebug() << qreal(lastTime.elapsed()) / qreal(nbFrames) << "ms/frame (=" << qreal(nbFrames) << "fps)";
+ nbFrames = 0;
+ lastTime.restart();
+ }
+#endif
+
+ // Update cached values
+ if (m_valuesDirty) {
+ const QMapDataArray &dataArray = *m_data->array();
+ int dataSize = dataArray.size();
+ m_renderItemArray.resize(dataSize);
+ for (int i = 0; i < dataSize ; i++) {
+ qreal value = dataArray.at(i).value();
+ m_renderItemArray[i].setValue(value);
+ m_renderItemArray[i].setMapPosition(dataArray.at(i).mapPosition());
+ m_renderItemArray[i].setHeight(value / m_heightNormalizer);
+ m_renderItemArray[i].setItemLabel(dataArray.at(i).label());
+ calculateTranslation(m_renderItemArray[i]);
+ m_renderItemArray[i].setRenderer(this);
+ }
+ m_valuesDirty = false;
+ }
+
+ if (defaultFboHandle) {
+ glDepthMask(true);
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_LESS);
+ glEnable(GL_CULL_FACE);
+ glCullFace(GL_BACK);
+ }
+
+ // Draw scene
+ drawScene(defaultFboHandle);
+}
+
+/*!
+ * \internal
+ */
+void Maps3DController::drawScene(const GLuint defaultFboHandle)
+{
+ // Set clear color
+ QVector3D clearColor = Utils::vectorFromColor(m_theme->m_windowColor);
+ glClearColor(clearColor.x(), clearColor.y(), clearColor.z(), 1.0f);
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ static QVector3D selection = skipColor;
+
+ // Specify viewport
+ glViewport(m_sceneViewPort.x(), m_sceneViewPort.y(),
+ m_sceneViewPort.width(), m_sceneViewPort.height());
+
+ // Set up projection matrix
+ QMatrix4x4 projectionMatrix;
+ projectionMatrix.perspective(45.0f, (GLfloat)m_sceneViewPort.width()
+ / (GLfloat)m_sceneViewPort.height(), 0.1f, 100.0f);
+
+ // Calculate view matrix
+ QMatrix4x4 viewMatrix = m_camera->calculateViewMatrix(m_mousePos,
+ m_zoomLevel * m_autoScaleAdjustment,
+ m_sceneViewPort.width(),
+ m_sceneViewPort.height());
+
+ // Get light position (rotate light with camera, a bit above it (as set in defaultLightPos))
+ QVector3D lightPos = m_camera->calculateLightPosition(defaultLightPos, 0.0f, distanceMod);
+
+ // Map adjustment direction to model matrix scaling
+ GLfloat heightMultiplier = 0.0f;
+ GLfloat widthMultiplier = 0.0f;
+ GLfloat depthMultiplier = 0.0f;
+ GLfloat heightScaler = 0.0f;
+ GLfloat widthScaler = 0.0f;
+ GLfloat depthScaler = 0.0f;
+ switch (m_adjustDirection) {
+ case Q3DMaps::AdjustHeight:
+ widthMultiplier = 0.0f;
+ heightMultiplier = 1.0f;
+ depthMultiplier = 0.0f;
+ widthScaler = m_barThickness.x() / m_scaleFactor;
+ heightScaler = 0.0f;
+ depthScaler = m_barThickness.z() / m_scaleFactor;
+ break;
+ case Q3DMaps::AdjustWidth:
+ widthMultiplier = 1.0f;
+ heightMultiplier = 0.0f;
+ depthMultiplier = 0.0f;
+ widthScaler = 0.0f;
+ heightScaler = m_barThickness.y() / m_scaleFactor;
+ depthScaler = m_barThickness.z() / m_scaleFactor;
+ break;
+ case Q3DMaps::AdjustDepth:
+ widthMultiplier = 0.0f;
+ heightMultiplier = 0.0f;
+ depthMultiplier = 1.0f;
+ widthScaler = m_barThickness.x() / m_scaleFactor;
+ heightScaler = m_barThickness.y() / m_scaleFactor;
+ depthScaler = 0.0f;
+ break;
+ case Q3DMaps::AdjustRadius:
+ widthMultiplier = 1.0f;
+ heightMultiplier = 0.0f;
+ depthMultiplier = 1.0f;
+ widthScaler = 0.0f;
+ heightScaler = m_barThickness.y() / m_scaleFactor;
+ depthScaler = 0.0f;
+ break;
+ case Q3DMaps::AdjustAll:
+ widthMultiplier = 1.0f;
+ heightMultiplier = 1.0f;
+ depthMultiplier = 1.0f;
+ widthScaler = 0.0f;
+ heightScaler = 0.0f;
+ depthScaler = 0.0f;
+ break;
+ }
+
+ // Introduce regardless of shadow quality to simplify logic
+ QMatrix4x4 depthViewMatrix;
+ QMatrix4x4 depthProjectionMatrix;
+
+#if !defined(QT_OPENGL_ES_2)
+ if (m_shadowQuality > QDataVis::ShadowNone) {
+ // Render scene into a depth texture for using with shadow mapping
+ // Bind depth shader
+ m_depthShader->bind();
+
+ // Set viewport for depth map rendering. Must match texture size. Larger values give smoother shadows.
+ glViewport(m_sceneViewPort.x(), m_sceneViewPort.y(),
+ m_sceneViewPort.width() * m_shadowQuality,
+ m_sceneViewPort.height() * m_shadowQuality);
+
+ // Enable drawing to framebuffer
+ glBindFramebuffer(GL_FRAMEBUFFER, m_depthFrameBuffer);
+ glClear(GL_DEPTH_BUFFER_BIT);
+
+ // Set front face culling to reduce self-shadowing issues
+ glCullFace(GL_FRONT);
+
+ // Get the depth view matrix
+ // It may be possible to hack lightPos here if we want to make some tweaks to shadow
+ QVector3D depthLightPos = m_camera->calculateLightPosition(
+ defaultLightPos, 0.0f, (distanceMod + 1.5f) / m_autoScaleAdjustment);
+ depthViewMatrix.lookAt(depthLightPos, QVector3D(0.0f, -m_yAdjustment, zComp),
+ QVector3D(0.0f, 1.0f, 0.0f));
+ // TODO: Why does depthViewMatrix.column(3).y() goes to zero when we're directly above? That causes the scene to be not drawn from above -> must be fixed
+ //qDebug() << lightPos << depthViewMatrix << depthViewMatrix.column(3);
+ // Set the depth projection matrix
+#ifndef USE_WIDER_SHADOWS
+ // Use this for perspective shadows
+ depthProjectionMatrix.perspective(15.0f, (GLfloat)m_sceneViewPort.width()
+ / (GLfloat)m_sceneViewPort.height(), 3.0f, 200.0f);
+#else
+ // Use these for orthographic shadows
+ //qDebug() << m_areaSize.width() / m_scaleFactor << m_yAdjustment;
+ GLfloat testAspectRatio = (GLfloat)m_sceneViewPort.width() / (GLfloat)m_sceneViewPort.height();
+ depthProjectionMatrix.ortho(-(2.0f * m_areaSize.width()) / m_scaleFactor,
+ (2.0f * m_areaSize.width()) / m_scaleFactor,
+ -m_yAdjustment * 4.0f * testAspectRatio,
+ m_yAdjustment * 4.0f * testAspectRatio,
+ 0.0f, 100.0f);
+#endif
+#if 0
+ // Draw background to depth buffer (You don't want to do this, except maybe for debugging purposes)
+ if (m_backgroundObj) {
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+
+ modelMatrix.translate(0.0f, -m_yAdjustment, zComp);
+ modelMatrix.scale(QVector3D(m_areaSize.width() / m_scaleFactor,
+ 1.0f,
+ m_areaSize.height() / m_scaleFactor));
+ modelMatrix.rotate(-90.0f, 1.0f, 0.0f, 0.0f);
+
+ MVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
+
+ m_depthShader->setUniformValue(m_depthShader->MVP(), MVPMatrix);
+
+ // 1st attribute buffer : vertices
+ glEnableVertexAttribArray(m_depthShader->posAtt());
+ glBindBuffer(GL_ARRAY_BUFFER, m_backgroundObj->vertexBuf());
+ glVertexAttribPointer(m_depthShader->posAtt(), 3, GL_FLOAT, GL_FALSE, 0, (void *)0);
+
+ // Index buffer
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_backgroundObj->elementBuf());
+
+ // Draw the triangles
+ glDrawElements(GL_TRIANGLES, m_backgroundObj->indexCount(), GL_UNSIGNED_SHORT,
+ (void *)0);
+
+ // Free buffers
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ glDisableVertexAttribArray(m_depthShader->posAtt());
+ }
+#endif
+ // Draw bars to depth buffer
+ for (int bar = 0; bar < m_renderItemArray.size(); bar++) {
+ const MapRenderItem &item = m_renderItemArray.at(bar);
+ if (!item.value())
+ continue;
+
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+
+ modelMatrix.translate(item.translation().x(),
+ heightMultiplier * item.height() + heightScaler - m_yAdjustment,
+ item.translation().z());
+ modelMatrix.scale(QVector3D(widthMultiplier * item.height() + widthScaler,
+ heightMultiplier * item.height() + heightScaler,
+ depthMultiplier * item.height() + depthScaler));
+
+ MVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
+
+ m_depthShader->setUniformValue(m_depthShader->MVP(), MVPMatrix);
+
+ // 1st attribute buffer : vertices
+ glEnableVertexAttribArray(m_depthShader->posAtt());
+ glBindBuffer(GL_ARRAY_BUFFER, m_barObj->vertexBuf());
+ glVertexAttribPointer(m_depthShader->posAtt(), 3, GL_FLOAT, GL_FALSE, 0, (void *)0);
+
+ // Index buffer
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_barObj->elementBuf());
+
+ // Draw the triangles
+ glDrawElements(GL_TRIANGLES, m_barObj->indexCount(), GL_UNSIGNED_SHORT, (void *)0);
+
+ // Free buffers
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ glDisableVertexAttribArray(m_depthShader->posAtt());
+ }
+
+ // Disable drawing to framebuffer (= enable drawing to screen)
+ glBindFramebuffer(GL_FRAMEBUFFER, defaultFboHandle);
+
+ // Reset culling to normal
+ glCullFace(GL_BACK);
+
+ // Release depth shader
+ m_depthShader->release();
+
+ // Revert to original viewport
+ glViewport(m_sceneViewPort.x(), m_sceneViewPort.y(),
+ m_sceneViewPort.width(), m_sceneViewPort.height());
+
+#if 0 // Use this if you want to see what is being drawn to the framebuffer
+ // You'll also have to comment out GL_COMPARE_R_TO_TEXTURE -line in texturehelper (if using it)
+ m_labelShader->bind();
+ glEnable(GL_TEXTURE_2D);
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 viewmatrix;
+ viewmatrix.lookAt(QVector3D(0.0f, 0.0f, 2.5f + zComp),
+ QVector3D(0.0f, 0.0f, zComp),
+ QVector3D(0.0f, 1.0f, 0.0f));
+ modelMatrix.translate(0.0, 0.0, zComp);
+ QMatrix4x4 MVPMatrix = projectionMatrix * viewmatrix * modelMatrix;
+ m_labelShader->setUniformValue(m_labelShader->MVP(), MVPMatrix);
+ m_drawer->drawObject(m_labelShader, m_labelObj,
+ m_depthTexture);
+ glDisable(GL_TEXTURE_2D);
+ m_labelShader->release();
+#endif
+ }
+#endif
+
+#if 1
+ // Skip selection mode drawing if we're zoomed or have no selection mode
+ if (!m_zoomActivated && m_selectionMode > QDataVis::ModeNone) {
+ // Bind selection shader
+ m_selectionShader->bind();
+
+ // Draw bars to selection buffer
+ glBindFramebuffer(GL_FRAMEBUFFER, m_selectionFrameBuffer);
+ glEnable(GL_DEPTH_TEST); // Needed, otherwise the depth render buffer is not used
+ glClearColor(skipColor.x() / 255, skipColor.y() / 255, skipColor.z() / 255, 1.0f); // Set clear color to white (= skipColor)
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Needed for clearing the frame buffer
+ glDisable(GL_DITHER); // disable dithering, it may affect colors if enabled
+ GLint barIdxRed = 0;
+ GLint barIdxGreen = 0;
+ GLint barIdxBlue = 0;
+ for (int bar = 0; bar < m_renderItemArray.size(); bar++, barIdxRed++) {
+ const MapRenderItem &item = m_renderItemArray.at(bar);
+ if (!item.value())
+ continue;
+
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+
+ modelMatrix.translate(item.translation().x(),
+ heightMultiplier * item.height() + heightScaler - m_yAdjustment,
+ item.translation().z());
+ modelMatrix.scale(QVector3D(widthMultiplier * item.height() + widthScaler,
+ heightMultiplier * item.height() + heightScaler,
+ depthMultiplier * item.height() + depthScaler));
+
+ MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
+
+ if (barIdxRed > 0 && barIdxRed % 256 == 0) {
+ barIdxRed = 0;
+ barIdxGreen++;
+ }
+ if (barIdxGreen > 0 && barIdxGreen % 256 == 0) {
+ barIdxGreen = 0;
+ barIdxBlue++;
+ }
+ if (barIdxBlue > 255)
+ qFatal("Too many objects");
+
+ QVector3D barColor = QVector3D((GLfloat)barIdxRed / 255.0f,
+ (GLfloat)barIdxGreen / 255.0f,
+ (GLfloat)barIdxBlue / 255.0f);
+
+ m_selectionShader->setUniformValue(m_selectionShader->MVP(), MVPMatrix);
+ m_selectionShader->setUniformValue(m_selectionShader->color(), barColor);
+
+ // 1st attribute buffer : vertices
+ glEnableVertexAttribArray(m_selectionShader->posAtt());
+ glBindBuffer(GL_ARRAY_BUFFER, m_barObj->vertexBuf());
+ glVertexAttribPointer(m_selectionShader->posAtt(), 3, GL_FLOAT, GL_FALSE, 0, (void *)0);
+
+ // Index buffer
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_barObj->elementBuf());
+
+ // Draw the triangles
+ glDrawElements(GL_TRIANGLES, m_barObj->indexCount(), GL_UNSIGNED_SHORT, (void *)0);
+
+ // Free buffers
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ glDisableVertexAttribArray(m_selectionShader->posAtt());
+ }
+ glEnable(GL_DITHER);
+
+ // Read color under cursor
+ if (Maps3DController::MouseOnScene == m_mousePressed)
+ selection = Utils::getSelection(m_mousePos, height());
+
+ glBindFramebuffer(GL_FRAMEBUFFER, defaultFboHandle);
+
+ // Release selection shader
+ m_selectionShader->release();
+
+#if 0 // Use this if you want to see what is being drawn to the framebuffer
+ m_labelShader->bind();
+ glDisable(GL_DEPTH_TEST);
+ glEnable(GL_TEXTURE_2D);
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 viewmatrix;
+ viewmatrix.lookAt(QVector3D(0.0f, 0.0f, 2.0f + zComp),
+ QVector3D(0.0f, 0.0f, zComp),
+ QVector3D(0.0f, 1.0f, 0.0f));
+ modelMatrix.translate(0.0, 0.0, zComp);
+ QMatrix4x4 MVPMatrix = projectionMatrix * viewmatrix * modelMatrix;
+ m_labelShader->setUniformValue(m_labelShader->MVP(), MVPMatrix);
+ m_drawer->drawObject(m_labelShader, m_labelObj,
+ m_selectionTexture);
+ glDisable(GL_TEXTURE_2D);
+ m_labelShader->release();
+#endif
+ }
+#if 1
+ // Bind bar shader
+ m_barShader->bind();
+
+ // Enable texture
+ glEnable(GL_TEXTURE_2D);
+
+ // Draw bars
+ // TODO: Handle zoom by camera transformations
+ //if (!m_zoomActivated)
+
+ bool barSelectionFound = false;
+ for (int bar = 0; bar < m_renderItemArray.size(); bar++) {
+ MapRenderItem &item = m_renderItemArray[bar];
+ if (!item.value())
+ continue;
+
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+ QMatrix4x4 depthMVPMatrix;
+ QMatrix4x4 itModelMatrix;
+
+ modelMatrix.translate(item.translation().x(),
+ heightMultiplier * item.height() + heightScaler - m_yAdjustment,
+ item.translation().z());
+ modelMatrix.scale(QVector3D(widthMultiplier * item.height() + widthScaler,
+ heightMultiplier * item.height() + heightScaler,
+ depthMultiplier * item.height() + depthScaler));
+ itModelMatrix.scale(QVector3D(widthMultiplier * item.height() + widthScaler,
+ heightMultiplier * item.height() + heightScaler,
+ depthMultiplier * item.height() + depthScaler));
+
+#ifdef SHOW_DEPTH_TEXTURE_SCENE
+ MVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
+#else
+ MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
+#endif
+ depthMVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
+
+ QVector3D baseColor = Utils::vectorFromColor(m_theme->m_baseColor);
+ QVector3D heightColor = Utils::vectorFromColor(m_theme->m_heightColor) * item.height();
+
+ QVector3D barColor = baseColor + heightColor;
+
+ GLfloat lightStrength = m_theme->m_lightStrength;
+ if (m_selectionMode > QDataVis::ModeNone) {
+ Maps3DController::SelectionType selectionType = isSelected(bar, selection);
+ switch (selectionType) {
+ case Maps3DController::SelectionBar: {
+ barColor = Utils::vectorFromColor(m_theme->m_highlightBarColor);
+ lightStrength = m_theme->m_highlightLightStrength;
+ // Insert data to QDataItem. We have no ownership, don't delete the previous one
+ if (!m_zoomActivated) {
+ m_selectedBar = &item;
+ barSelectionFound = true;
+ }
+ break;
+ }
+ case Maps3DController::SelectionNone: {
+ // Current bar is not selected, nor on a row or column
+ // do nothing
+ break;
+ }
+ default: {
+ // Unsupported selection mode
+ // do nothing
+ break;
+ }
+ }
+ }
+
+ if (item.height() != 0) {
+ // Set shader bindings
+ m_barShader->setUniformValue(m_barShader->lightP(), lightPos);
+ m_barShader->setUniformValue(m_barShader->view(), viewMatrix);
+ m_barShader->setUniformValue(m_barShader->model(), modelMatrix);
+ m_barShader->setUniformValue(m_barShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ m_barShader->setUniformValue(m_barShader->MVP(), MVPMatrix);
+ m_barShader->setUniformValue(m_barShader->color(), barColor);
+ m_barShader->setUniformValue(m_barShader->ambientS(), m_theme->m_ambientStrength);
+
+#if !defined(QT_OPENGL_ES_2)
+ if (m_shadowQuality > QDataVis::ShadowNone) {
+ // Set shadow shader bindings
+ m_barShader->setUniformValue(m_barShader->shadowQ(), m_shadowQualityToShader);
+ m_barShader->setUniformValue(m_barShader->depth(), depthMVPMatrix);
+ m_barShader->setUniformValue(m_barShader->lightS(), lightStrength / 10.0f);
+
+ // Draw the object
+ m_drawer->drawObject(m_barShader, m_barObj, 0, m_depthTexture);
+ } else
+#endif
+ {
+ // Set shadowless shader bindings
+ m_barShader->setUniformValue(m_barShader->lightS(), lightStrength);
+
+ // Draw the object
+ m_drawer->drawObject(m_barShader, m_barObj);
+ }
+ }
+ }
+
+ // Release bar shader
+ m_barShader->release();
+#if 1
+ // Bind background shader
+ m_backgroundShader->bind();
+ if (m_bgrHasAlpha) {
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ }
+
+ // Draw background
+ if (m_backgroundObj) {
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+ QMatrix4x4 depthMVPMatrix;
+ QMatrix4x4 itModelMatrix;
+
+ modelMatrix.translate(0.0f, -m_yAdjustment, zComp);
+ modelMatrix.scale(QVector3D(m_areaSize.width() / m_scaleFactor,
+ 1.0f,
+ m_areaSize.height() / m_scaleFactor));
+ modelMatrix.rotate(-90.0f, 1.0f, 0.0f, 0.0f);
+ itModelMatrix.scale(QVector3D(m_areaSize.width() / m_scaleFactor,
+ 1.0f,
+ m_areaSize.height() / m_scaleFactor));
+
+#ifdef SHOW_DEPTH_TEXTURE_SCENE
+ MVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
+#else
+ MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
+#endif
+ depthMVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
+
+ // Set shader bindings
+ m_backgroundShader->setUniformValue(m_backgroundShader->lightP(), lightPos);
+ m_backgroundShader->setUniformValue(m_backgroundShader->view(), viewMatrix);
+ m_backgroundShader->setUniformValue(m_backgroundShader->model(), modelMatrix);
+ m_backgroundShader->setUniformValue(m_backgroundShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ m_backgroundShader->setUniformValue(m_backgroundShader->MVP(), MVPMatrix);
+ m_backgroundShader->setUniformValue(m_backgroundShader->ambientS(),
+ m_theme->m_ambientStrength * 3.0f);
+
+#if !defined(QT_OPENGL_ES_2)
+ if (m_shadowQuality > QDataVis::ShadowNone) {
+ // Set shadow shader bindings
+ m_backgroundShader->setUniformValue(m_backgroundShader->shadowQ(),
+ m_shadowQualityToShader);
+ m_backgroundShader->setUniformValue(m_backgroundShader->depth(),
+ depthMVPMatrix);
+ m_backgroundShader->setUniformValue(m_backgroundShader->lightS(),
+ m_theme->m_lightStrength / 25.0f);
+
+ // Draw the object
+ m_drawer->drawObject(m_backgroundShader, m_backgroundObj, m_bgrTexture, m_depthTexture);
+ } else
+#endif
+ {
+ // Set shadowless shader bindings
+ m_backgroundShader->setUniformValue(m_backgroundShader->lightS(),
+ m_theme->m_lightStrength);
+
+ // Draw the object
+ m_drawer->drawObject(m_backgroundShader, m_backgroundObj, m_bgrTexture);
+ }
+ }
+
+ // Disable textures
+ glDisable(GL_TEXTURE_2D);
+ if (m_bgrHasAlpha)
+ glDisable(GL_BLEND);
+
+ // Release background shader
+ m_backgroundShader->release();
+#endif
+
+ // Handle zoom activation and label drawing
+ if (!barSelectionFound) {
+ // We have no ownership, don't delete. Just NULL the pointer.
+ m_selectedBar = NULL;
+ //if (m_zoomActivated && Maps3DController::MouseOnOverview == m_mousePressed) {
+ //m_sceneViewPort = QRect(0, 0, width(), height());
+ //m_zoomActivated = false;
+ //}
+ } /*else if (m_selectionMode >= ModeZoomRow
+ && Maps3DController::MouseOnScene == m_mousePressed) {
+ // Activate zoom mode
+ m_zoomActivated = true;
+ m_sceneViewPort = QRect(0, height() - height() / 5, width() / 5, height() / 5);
+
+ // Create label textures
+ for (int col = 0; col < m_zoomSelection->row().size(); col++) {
+ QDataItem *item = m_zoomSelection->getItem(col);
+ m_drawer->generateLabelTexture(item);
+ }
+ }*/ else {
+ // Print value of selected bar
+ m_labelShader->bind();
+ glDisable(GL_DEPTH_TEST);
+ glEnable(GL_TEXTURE_2D);
+ if (m_labelTransparency > QDataVis::TransparencyNone) {
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ }
+#ifndef DISPLAY_FULL_DATA_ON_SELECTION
+ // Draw just the value string of the selected bar
+ if (m_previouslySelectedBar != m_selectedBar || m_updateLabels) {
+ m_drawer->generateLabelTexture(m_selectedBar);
+ m_previouslySelectedBar = m_selectedBar;
+ }
+
+ m_drawer->drawLabel(*m_selectedBar, m_selectedBar->labelItem(),
+ viewMatrix, projectionMatrix,
+ QVector3D(0.0f, m_yAdjustment, zComp),
+ QVector3D(0.0f, 0.0f, 0.0f), m_selectedBar->height(),
+ m_selectionMode, m_labelShader,
+ m_labelObj, m_camera, true);
+#else
+ // Draw the value string followed by row label and column label
+ LabelItem &labelItem = m_selectedBar->selectionLabel();
+ if (m_previouslySelectedBar != m_selectedBar || m_updateLabels || !labelItem.textureId()) {
+ QString labelText = m_selectedBar->label();
+ // TODO More elaborate label?
+ m_drawer->generateLabelItem(&labelItem, labelText);
+ m_previouslySelectedBar = m_selectedBar;
+ }
+
+ m_drawer->drawLabel(*m_selectedBar, labelItem, viewMatrix, projectionMatrix,
+ QVector3D(0.0f, m_yAdjustment, zComp),
+ QVector3D(0.0f, 0.0f, 0.0f), m_selectedBar->height(),
+ m_selectionMode, m_labelShader,
+ m_labelObj, true, false);
+#endif
+ glDisable(GL_TEXTURE_2D);
+ if (m_labelTransparency > QDataVis::TransparencyNone)
+ glDisable(GL_BLEND);
+ glEnable(GL_DEPTH_TEST);
+
+ // Release label shader
+ m_labelShader->release();
+
+ // Reset label update flag; they should have been updated when we get here
+ m_updateLabels = false;
+ }
+#if 0
+ // TODO: Calculations done temporarily here. When optimizing, move to after data set addition? Keep drawing of the labels here.
+ // Bind label shader
+ m_labelShader->bind();
+
+ glEnable(GL_TEXTURE_2D);
+ if (m_labelTransparency > TransparencyNone) {
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ }
+
+ // Calculate the positions for row and column labels and store them into QDataItems (and QDataRows?)
+ for (int row = 0; row != m_sampleCount.second; row += 1) {
+ // Go through all rows and get position of max+1 or min-1 column, depending on x flip
+ // We need only positions for them, labels have already been generated at QDataSet. Just add LabelItems
+ rowPos = (row + 1) * (m_barSpacing.height());
+ barPos = 0;
+ GLfloat rotLabelX = -90.0f;
+ GLfloat rotLabelY = 0.0f;
+ Qt::AlignmentFlag alignment = Qt::AlignRight;
+ if (m_zFlipped)
+ rotLabelY = 180.0f;
+ if (m_xFlipped) {
+ barPos = (m_sampleCount.first + 1) * (m_barSpacing.width());
+ alignment = Qt::AlignLeft;
+ }
+ QVector3D labelPos = QVector3D((m_rowWidth - barPos) / m_scaleFactor,
+ -m_yAdjustment + 0.005f, // raise a bit over background to avoid depth "glimmering"
+ (m_columnDepth - rowPos) / m_scaleFactor + zComp);
+
+ // TODO: Try it; draw the label here
+
+ // Create a data item
+ QDataItem *label = new QDataItem();
+ label->setTranslation(labelPos);
+ if (m_data->d_ptr->rowLabelItems().size() > row) {
+ label->setLabel(m_data->d_ptr->rowLabelItems().at(m_data->d_ptr->rowLabelItems().size()
+ - row - 1));
+ }
+
+ //qDebug() << "labelPos, row" << row + 1 << ":" << labelPos << m_dataSet->rowLabels().at(row);
+
+ m_drawer->drawLabel(*label, label->label(), viewMatrix, projectionMatrix,
+ QVector3D(0.0f, m_yAdjustment, zComp),
+ QVector3D(rotLabelX, rotLabelY, 0.0f), m_heightNormalizer,
+ m_selectionMode, m_labelShader,
+ m_labelObj, true, true, Drawer::LabelMid, alignment);
+
+ delete label;
+ }
+ for (int bar = 0; bar != m_sampleCount.first; bar += 1) {
+ // Go through all columns and get position of max+1 or min-1 row, depending on z flip
+ // We need only positions for them, labels have already been generated at QDataSet. Just add LabelItems
+ barPos = (bar + 1) * (m_barSpacing.width());
+ rowPos = 0;
+ GLfloat rotLabelX = -90.0f;
+ GLfloat rotLabelY = 90.0f;
+ Qt::AlignmentFlag alignment = Qt::AlignLeft;
+ if (m_xFlipped)
+ rotLabelY = -90.0f;
+ if (m_zFlipped) {
+ rowPos = (m_sampleCount.second + 1) * (m_barSpacing.height());
+ alignment = Qt::AlignRight;
+ }
+ QVector3D labelPos = QVector3D((m_rowWidth - barPos) / m_scaleFactor,
+ -m_yAdjustment + 0.005f, // raise a bit over background to avoid depth "glimmering"
+ (m_columnDepth - rowPos) / m_scaleFactor + zComp);
+
+ // TODO: Try it; draw the label here
+
+ // Create a data item
+ QDataItem *label = new QDataItem();
+ label->setTranslation(labelPos);
+ if (m_data->d_ptr->columnLabelItems().size() > bar) {
+ label->setLabel(m_data->d_ptr->columnLabelItems().at(
+ m_data->d_ptr->columnLabelItems().size() - bar - 1));
+ }
+
+ //qDebug() << "labelPos, col" << bar + 1 << ":" << labelPos << m_dataSet->columnLabels().at(bar);
+
+ m_drawer->drawLabel(*label, label->label(), viewMatrix, projectionMatrix,
+ QVector3D(0.0f, m_yAdjustment, zComp),
+ QVector3D(rotLabelX, rotLabelY, 0.0f), m_heightNormalizer,
+ m_selectionMode, m_labelShader,
+ m_labelObj, true, true, Drawer::LabelMid, alignment);
+
+ delete label;
+ }
+ glDisable(GL_TEXTURE_2D);
+ if (m_labelTransparency > TransparencyNone)
+ glDisable(GL_BLEND);
+
+ // Release label shader
+ m_labelShader->release();
+#endif
+#endif
+#endif
+}
+
+#if defined(Q_OS_ANDROID)
+/*!
+ * \internal
+ */
+void Maps3DController::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ if (!m_zoomActivated) {
+ m_mousePressed = Maps3DController::MouseOnScene;
+ // update mouse positions to prevent jumping when releasing or repressing a button
+ m_mousePos = event->pos();
+ }
+}
+
+/*!
+ * \internal
+ */
+void Maps3DController::touchEvent(QTouchEvent *event)
+{
+ static int prevDistance = 0;
+
+ QList<QTouchEvent::TouchPoint> points;
+ points = event->touchPoints();
+
+ if (points.count() == 2) {
+ m_mousePressed = Maps3DController::MouseOnPinch;
+
+ QPointF distance = points.at(0).pos() - points.at(1).pos();
+ int newDistance = distance.manhattanLength();
+ int zoomRate = 1;
+ if (m_zoomLevel > 100)
+ zoomRate = 5;
+ if (newDistance > prevDistance)
+ m_zoomLevel += zoomRate;
+ else
+ m_zoomLevel -= zoomRate;
+ if (m_zoomLevel > 500)
+ m_zoomLevel = 500;
+ else if (m_zoomLevel < 10)
+ m_zoomLevel = 10;
+ prevDistance = newDistance;
+ //qDebug() << "distance" << distance.manhattanLength();
+ }
+}
+#endif
+
+/*!
+ * \internal
+ */
+void Maps3DController::mousePressEvent(QMouseEvent *event, const QPoint &mousePos)
+{
+ if (Qt::LeftButton == event->button()) {
+ if (m_zoomActivated) {
+ //qDebug() << event->pos().x() << event->pos().y() << m_sceneViewPort << m_zoomViewPort;
+ if (mousePos.x() <= m_sceneViewPort.width()
+ && mousePos.y() <= m_sceneViewPort.height()) {
+ m_mousePressed = Maps3DController::MouseOnOverview;
+ //qDebug() << "Mouse pressed on overview";
+ } else {
+ m_mousePressed = Maps3DController::MouseOnZoom;
+ //qDebug() << "Mouse pressed on zoom";
+ }
+ } else {
+#if !defined(Q_OS_ANDROID)
+ m_mousePressed = Maps3DController::MouseOnScene;
+#else
+ m_mousePressed = Maps3DController::MouseRotating;
+#endif
+ // update mouse positions to prevent jumping when releasing or repressing a button
+ m_mousePos = mousePos;
+ //qDebug() << "Mouse pressed on scene";
+ }
+ } else if (Qt::MiddleButton == event->button()) {
+ // reset rotations
+ m_mousePos = QPoint(0, 0);
+ } else if (Qt::RightButton == event->button()) {
+#if !defined(Q_OS_ANDROID)
+ m_mousePressed = Maps3DController::MouseRotating;
+#else
+ m_mousePressed = Maps3DController::MouseOnScene;
+#endif
+ // update mouse positions to prevent jumping when releasing or repressing a button
+ m_mousePos = mousePos;
+ }
+ m_camera->updateMousePos(m_mousePos);
+}
+
+/*!
+ * \internal
+ */
+void Maps3DController::mouseReleaseEvent(QMouseEvent *event, const QPoint &mousePos)
+{
+ Q_UNUSED(event);
+ //qDebug() << "mouse button released" << event->button();
+ if (Maps3DController::MouseRotating == m_mousePressed) {
+ // update mouse positions to prevent jumping when releasing or repressing a button
+ m_mousePos = mousePos;
+ m_camera->updateMousePos(mousePos);
+ }
+ m_mousePressed = Maps3DController::MouseNone;
+}
+
+/*!
+ * \internal
+ */
+void Maps3DController::mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos)
+{
+ Q_UNUSED(event);
+ if (Maps3DController::MouseRotating == m_mousePressed) {
+ //qDebug() << "mouse moved while pressed" << event->pos();
+ m_mousePos = mousePos;
+ }
+#if 0
+ // TODO: Testi - laske kursorin sijainti scenessä
+ QPointF mouse3D((2.0f * event->pos().x() - width()) / height(),
+ 1.0f - (2.0f * event->pos().y()) / height());
+ //qDebug() << "mouse position in scene" << mouse3D;
+
+ // TODO: Testi laske focal point
+ GLfloat focalPoint = tan(45.0f / 2.0f);
+
+ // TODO: Testi - laske viewmatriisin kerroin
+ QVector3D worldRay = QVector3D(0.0f, 0.0f, 0.0f) - QVector3D(mouse3D.x(), mouse3D.y(),
+ -focalPoint);
+ //qDebug() << "worldRay" << worldRay;
+ // multiply viewmatrix with this to get something?
+#endif
+}
+
+/*!
+ * \internal
+ */
+void Maps3DController::wheelEvent(QWheelEvent *event)
+{
+ if (m_zoomLevel > 100)
+ m_zoomLevel += event->angleDelta().y() / 12;
+ else if (m_zoomLevel > 50)
+ m_zoomLevel += event->angleDelta().y() / 60;
+ else
+ m_zoomLevel += event->angleDelta().y() / 120;
+ if (m_zoomLevel > 500)
+ m_zoomLevel = 500;
+ else if (m_zoomLevel < 10)
+ m_zoomLevel = 10;
+}
+
+/*!
+ * \internal
+ */
+void Maps3DController::resizeNotify()
+{
+ if (!m_isInitialized)
+ return;
+
+ // Set view port
+ if (m_zoomActivated)
+ m_sceneViewPort = QRect(0, height() - height() / 5, width() / 5, height() / 5);
+ else
+ m_sceneViewPort = QRect(0, 0, width(), height());
+ m_zoomViewPort = QRect(0, 0, width(), height());
+
+ // Calculate zoom level based on aspect ratio
+ GLfloat div;
+ GLfloat zoomAdjustment;
+ div = qMin(width(), height());
+ zoomAdjustment = defaultRatio * ((width() / div) / (height() / div));
+ //qDebug() << "zoom adjustment" << zoomAdjustment;
+ m_autoScaleAdjustment = qMin(zoomAdjustment, 1.0f); // clamp to 1.0f
+
+ // Re-init selection buffer
+ initSelectionBuffer();
+
+#if !defined(QT_OPENGL_ES_2)
+ // Re-init depth buffer
+ initDepthBuffer();
+#endif
+}
+
+void Maps3DController::setBarSpecs(const QVector3D &thickness,
+ Q3DMaps::AdjustmentDirection direction)
+{
+ m_barThickness = thickness;
+ m_adjustDirection = direction;
+}
+
+void Maps3DController::setBarType(QDataVis::MeshStyle style, bool smooth)
+{
+ if (style == QDataVis::Bars) {
+ if (smooth)
+ m_objFile = QStringLiteral(":/defaultMeshes/barSmooth");
+ else
+ m_objFile = QStringLiteral(":/defaultMeshes/bar");
+ } else if (style == QDataVis::Pyramids) {
+ if (smooth)
+ m_objFile = QStringLiteral(":/defaultMeshes/pyramidSmooth");
+ else
+ m_objFile = QStringLiteral(":/defaultMeshes/pyramid");
+ } else if (style == QDataVis::Cones) {
+ if (smooth)
+ m_objFile = QStringLiteral(":/defaultMeshes/coneSmooth");
+ else
+ m_objFile = QStringLiteral(":/defaultMeshes/cone");
+ } else if (style == QDataVis::Cylinders) {
+ if (smooth)
+ m_objFile = QStringLiteral(":/defaultMeshes/cylinderSmooth");
+ else
+ m_objFile = QStringLiteral(":/defaultMeshes/cylinder");
+ } else if (style == QDataVis::BevelBars) {
+ if (smooth)
+ m_objFile = QStringLiteral(":/defaultMeshes/bevelbarSmooth");
+ else
+ m_objFile = QStringLiteral(":/defaultMeshes/bevelbar");
+ } else if (style == QDataVis::Spheres) {
+ if (smooth)
+ m_objFile = QStringLiteral(":/defaultMeshes/sphereSmooth");
+ else
+ m_objFile = QStringLiteral(":/defaultMeshes/sphere");
+ }
+ // Reload mesh data
+ if (m_isInitialized)
+ loadBarMesh();
+}
+
+void Maps3DController::setMeshFileName(const QString &objFileName)
+{
+ m_objFile = objFileName;
+}
+
+void Maps3DController::setCameraPreset(QDataVis::CameraPreset preset)
+{
+ m_camera->setCameraPreset(preset);
+}
+
+void Maps3DController::setCameraPosition(GLfloat horizontal, GLfloat vertical, GLint distance)
+{
+ m_horizontalRotation = qBound(-180.0f, horizontal, 180.0f);
+ m_verticalRotation = qBound(0.0f, vertical, 90.0f);
+ m_zoomLevel = qBound(10, distance, 500);
+ m_camera->setCameraRotation(QPointF(m_horizontalRotation, m_verticalRotation));
+ //qDebug() << "camera rotation set to" << m_horizontalRotation << m_verticalRotation;
+}
+
+void Maps3DController::setTheme(QDataVis::ColorTheme colorTheme)
+{
+ m_theme->useColorTheme(colorTheme);
+ m_drawer->setTheme(*m_theme);
+#if !defined(QT_OPENGL_ES_2)
+ if (m_shadowQuality > QDataVis::ShadowNone) {
+ // Re-init shaders
+ if (!m_theme->m_uniformColor) {
+ initShaders(QStringLiteral(":/shaders/vertexShadow"),
+ QStringLiteral(":/shaders/fragmentShadowNoTexColorOnY"));
+ } else {
+ initShaders(QStringLiteral(":/shaders/vertexShadow"),
+ QStringLiteral(":/shaders/fragmentShadowNoTex"));
+ }
+ } else {
+ // Re-init shaders
+ if (!m_theme->m_uniformColor) {
+ initShaders(QStringLiteral(":/shaders/vertex"),
+ QStringLiteral(":/shaders/fragmentColorOnY"));
+ } else {
+ initShaders(QStringLiteral(":/shaders/vertex"),
+ QStringLiteral(":/shaders/fragment"));
+ }
+ }
+#else
+ if (!m_theme->m_uniformColor) {
+ initShaders(QStringLiteral(":/shaders/vertexES2"),
+ QStringLiteral(":/shaders/fragmentColorOnYES2"));
+ } else {
+ initShaders(QStringLiteral(":/shaders/vertexES2"),
+ QStringLiteral(":/shaders/fragmentES2"));
+ }
+#endif
+ m_updateLabels = true;
+}
+
+void Maps3DController::setBarColor(QColor baseColor, QColor heightColor, bool uniform)
+{
+ m_theme->m_baseColor = baseColor;
+ m_theme->m_heightColor = heightColor;
+ if (m_theme->m_uniformColor != uniform) {
+#if !defined(QT_OPENGL_ES_2)
+ if (m_shadowQuality > QDataVis::ShadowNone) {
+ // Re-init shaders
+ if (!m_theme->m_uniformColor) {
+ initShaders(QStringLiteral(":/shaders/vertexShadow"),
+ QStringLiteral(":/shaders/fragmentShadowNoTexColorOnY"));
+ } else {
+ initShaders(QStringLiteral(":/shaders/vertexShadow"),
+ QStringLiteral(":/shaders/fragmentShadowNoTex"));
+ }
+ } else {
+ // Re-init shaders
+ if (!m_theme->m_uniformColor) {
+ initShaders(QStringLiteral(":/shaders/vertex"),
+ QStringLiteral(":/shaders/fragmentColorOnY"));
+ } else {
+ initShaders(QStringLiteral(":/shaders/vertex"),
+ QStringLiteral(":/shaders/fragment"));
+ }
+ }
+#else
+ if (!m_theme->m_uniformColor) {
+ initShaders(QStringLiteral(":/shaders/vertexES2"),
+ QStringLiteral(":/shaders/fragmentColorOnYES2"));
+ } else {
+ initShaders(QStringLiteral(":/shaders/vertexES2"),
+ QStringLiteral(":/shaders/fragmentES2"));
+ }
+#endif
+ }
+ m_theme->m_uniformColor = uniform;
+}
+
+void Maps3DController::setAreaSpecs(const QRect &areaRect, const QImage &image)
+{
+ calculateSceneScalingFactors(areaRect);
+ setImage(image);
+}
+
+void Maps3DController::setImage(const QImage &image)
+{
+ m_bgrHasAlpha = image.hasAlphaChannel();
+ if (m_bgrTexture)
+ glDeleteTextures(1, &m_bgrTexture);
+ m_bgrTexture = m_textureHelper->create2DTexture(image, true, true);
+}
+
+void Maps3DController::setSelectionMode(QDataVis::SelectionMode mode)
+{
+ m_selectionMode = mode;
+ // Disable zoom if mode changes
+ //m_zoomActivated = false;
+ //m_sceneViewPort = QRect(0, 0, width(), height());
+}
+
+QDataVis::SelectionMode Maps3DController::selectionMode()
+{
+ return m_selectionMode;
+}
+
+void Maps3DController::setFontSize(float fontsize)
+{
+ m_font.setPointSizeF(fontsize);
+ m_drawer->setFont(m_font);
+ m_updateLabels = true;
+}
+
+float Maps3DController::fontSize()
+{
+ return m_font.pointSizeF();
+}
+
+void Maps3DController::setFont(const QFont &font)
+{
+ m_font = font;
+ m_drawer->setFont(font);
+ m_updateLabels = true;
+}
+
+QFont Maps3DController::font()
+{
+ return m_font;
+}
+
+void Maps3DController::setLabelTransparency(QDataVis::LabelTransparency transparency)
+{
+ m_labelTransparency = transparency;
+ m_drawer->setTransparency(transparency);
+ m_updateLabels = true;
+}
+
+QDataVis::LabelTransparency Maps3DController::labelTransparency()
+{
+ return m_labelTransparency;
+}
+
+QDataVis::ShadowQuality Maps3DController::setShadowQuality(QDataVis::ShadowQuality quality)
+{
+ m_shadowQuality = quality;
+ switch (quality) {
+ case QDataVis::ShadowLow:
+ //qDebug() << "ShadowLow";
+ m_shadowQualityToShader = 33.3f;
+ break;
+ case QDataVis::ShadowMedium:
+ //qDebug() << "ShadowMedium";
+ m_shadowQualityToShader = 100.0f;
+ break;
+ case QDataVis::ShadowHigh:
+ //qDebug() << "ShadowHigh";
+ m_shadowQualityToShader = 200.0f;
+ break;
+ default:
+ m_shadowQualityToShader = 0.0f;
+ break;
+ }
+ if (m_isInitialized) {
+#if !defined(QT_OPENGL_ES_2)
+ if (m_shadowQuality > QDataVis::ShadowNone) {
+ // Re-init shaders
+ if (!m_theme->m_uniformColor) {
+ initShaders(QStringLiteral(":/shaders/vertexShadow"),
+ QStringLiteral(":/shaders/fragmentShadowNoTexColorOnY"));
+ } else {
+ initShaders(QStringLiteral(":/shaders/vertexShadow"),
+ QStringLiteral(":/shaders/fragmentShadowNoTex"));
+ }
+ initBackgroundShaders(QStringLiteral(":/shaders/vertexShadow"),
+ QStringLiteral(":/shaders/fragmentShadow"));
+ } else {
+ // Re-init shaders
+ if (!m_theme->m_uniformColor) {
+ initShaders(QStringLiteral(":/shaders/vertex"),
+ QStringLiteral(":/shaders/fragmentColorOnY"));
+ } else {
+ initShaders(QStringLiteral(":/shaders/vertex"),
+ QStringLiteral(":/shaders/fragment"));
+ }
+ initBackgroundShaders(QStringLiteral(":/shaders/vertexTexture"),
+ QStringLiteral(":/shaders/fragmentTexture"));
+ }
+ // Re-init depth buffer
+ initDepthBuffer();
+#else
+ if (!m_theme->m_uniformColor) {
+ initShaders(QStringLiteral(":/shaders/vertexES2"),
+ QStringLiteral(":/shaders/fragmentColorOnYES2"));
+ } else {
+ initShaders(QStringLiteral(":/shaders/vertexES2"),
+ QStringLiteral(":/shaders/fragmentES2"));
+ }
+ initBackgroundShaders(QStringLiteral(":/shaders/vertexTexture"), // Same vertex shader ok for ES2
+ QStringLiteral(":/shaders/fragmentTextureES2"));
+#endif
+ }
+ return m_shadowQuality;
+}
+
+QDataVis::ShadowQuality Maps3DController::shadowQuality()
+{
+ return m_shadowQuality;
+}
+
+
+
+const QSize Maps3DController::size()
+{
+ return m_boundingRect.size();
+}
+
+const QRect Maps3DController::boundingRect()
+{
+ return m_boundingRect;
+}
+
+void Maps3DController::setBoundingRect(const QRect boundingRect)
+{
+ m_boundingRect = boundingRect;
+ resizeNotify();
+}
+
+void Maps3DController::setWidth(const int width)
+{
+ m_boundingRect.setWidth(width);
+ resizeNotify();
+}
+
+int Maps3DController::width()
+{
+ return m_boundingRect.width();
+}
+
+void Maps3DController::setHeight(const int height)
+{
+ m_boundingRect.setHeight(height);
+ resizeNotify();
+}
+
+int Maps3DController::height()
+{
+ return m_boundingRect.height();
+}
+
+void Maps3DController::setX(const int x)
+{
+ m_boundingRect.setX(x);
+}
+
+int Maps3DController::x()
+{
+ return m_boundingRect.x();
+}
+
+void Maps3DController::setY(const int y)
+{
+ m_boundingRect.setY(y);
+}
+
+int Maps3DController::y()
+{
+ return m_boundingRect.y();
+}
+
+void Maps3DController::loadBarMesh()
+{
+ if (m_barObj)
+ delete m_barObj;
+ m_barObj = new ObjectHelper(m_objFile);
+ m_barObj->load();
+}
+
+void Maps3DController::loadBackgroundMesh()
+{
+ if (m_backgroundObj)
+ delete m_backgroundObj;
+ m_backgroundObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/label"));
+ m_backgroundObj->load();
+}
+
+void Maps3DController::loadGridLineMesh()
+{
+ if (m_gridLineObj)
+ delete m_gridLineObj;
+ m_gridLineObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/bar"));
+ m_gridLineObj->load();
+}
+
+void Maps3DController::loadLabelMesh()
+{
+ if (m_labelObj)
+ delete m_labelObj;
+ m_labelObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/label"));
+ m_labelObj->load();
+}
+
+void Maps3DController::initShaders(const QString &vertexShader, const QString &fragmentShader)
+{
+ if (m_barShader)
+ delete m_barShader;
+ m_barShader = new ShaderHelper(this, vertexShader, fragmentShader);
+ m_barShader->initialize();
+}
+
+void Maps3DController::initSelectionShader()
+{
+ if (m_selectionShader)
+ delete m_selectionShader;
+ m_selectionShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexSelection"),
+ QStringLiteral(":/shaders/fragmentSelection"));
+ m_selectionShader->initialize();
+}
+
+void Maps3DController::initSelectionBuffer()
+{
+ if (m_selectionTexture)
+ m_textureHelper->deleteTexture(&m_selectionTexture);
+
+ m_selectionTexture = m_textureHelper->createSelectionTexture(this->size(),
+ m_selectionFrameBuffer,
+ m_selectionDepthBuffer);
+}
+
+#if !defined(QT_OPENGL_ES_2)
+void Maps3DController::initDepthShader()
+{
+ if (m_depthShader)
+ delete m_depthShader;
+ m_depthShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexDepth"),
+ QStringLiteral(":/shaders/fragmentDepth"));
+ m_depthShader->initialize();
+}
+
+void Maps3DController::initDepthBuffer()
+{
+ if (!m_isInitialized)
+ return;
+
+ if (m_depthTexture) {
+ m_textureHelper->deleteTexture(&m_depthTexture);
+ m_depthTexture = 0;
+ }
+
+ if (m_shadowQuality > QDataVis::ShadowNone) {
+ m_depthTexture = m_textureHelper->createDepthTexture(this->size(), m_depthFrameBuffer,
+ m_shadowQuality);
+ if (!m_depthTexture) {
+ switch (m_shadowQuality) {
+ case QDataVis::ShadowHigh:
+ qWarning("Creating high quality shadows failed. Changing to medium quality.");
+ (void)setShadowQuality(QDataVis::ShadowMedium);
+ break;
+ case QDataVis::ShadowMedium:
+ qWarning("Creating medium quality shadows failed. Changing to low quality.");
+ (void)setShadowQuality(QDataVis::ShadowLow);
+ break;
+ case QDataVis::ShadowLow:
+ qWarning("Creating low quality shadows failed. Switching shadows off.");
+ (void)setShadowQuality(QDataVis::ShadowNone);
+ break;
+ default:
+ // Cannot get here
+ break;
+ }
+ }
+ }
+}
+#endif
+
+void Maps3DController::initBackgroundShaders(const QString &vertexShader,
+ const QString &fragmentShader)
+{
+ if (m_backgroundShader)
+ delete m_backgroundShader;
+ m_backgroundShader = new ShaderHelper(this, vertexShader, fragmentShader);
+ m_backgroundShader->initialize();
+}
+
+void Maps3DController::initLabelShaders(const QString &vertexShader, const QString &fragmentShader)
+{
+ if (m_labelShader)
+ delete m_labelShader;
+ m_labelShader = new ShaderHelper(this, vertexShader, fragmentShader);
+ m_labelShader->initialize();
+}
+
+void Maps3DController::updateTextures()
+{
+ // Drawer has changed; this flag needs to be checked when checking if we need to update labels
+ m_updateLabels = true;
+}
+
+void Maps3DController::calculateSceneScalingFactors(const QRect &areaRect)
+{
+ m_areaSize = areaRect.size();
+ // Calculate scaling factor so that we can be sure the whole area fits to positive z space
+ if (zComp > 1.0f)
+ m_scaleFactor = qMax(m_areaSize.width(), m_areaSize.height()) / zComp;
+ else
+ m_scaleFactor = qMax(m_areaSize.width(), m_areaSize.height());
+ //qDebug() << "scaleFactor" << m_scaleFactor;
+}
+
+void Maps3DController::calculateHeightAdjustment(const QPair<GLfloat, GLfloat> &limits)
+{
+ // 2.0f = max difference between minimum and maximum value after scaling with m_heightNormalizer
+ m_yAdjustment = 2.0f - ((limits.second - limits.first) / m_heightNormalizer);
+ //qDebug() << m_yAdjustment;
+}
+
+void Maps3DController::calculateTranslation(MapRenderItem &item)
+{
+ // We need to convert position (which is in coordinates), to translation (which has origin in the center and is scaled)
+ // -> move pos(center, center) to trans(0, 0) and pos(0, 0) to trans(left, top)
+ GLfloat xTrans = 2.0f * (item.mapPosition().x() - (m_areaSize.width() / 2.0f))
+ / m_scaleFactor;
+ GLfloat zTrans = 2.0f * (item.mapPosition().y() - (m_areaSize.height() / 2.0f))
+ / m_scaleFactor;
+ //qDebug() << "x, y" << item.mapPosition().x() << item.mapPosition().y();
+ item.setTranslation(QVector3D(xTrans, 0.0f, zTrans + zComp));
+ //qDebug() << item.translation();
+}
+
+Maps3DController::SelectionType Maps3DController::isSelected(GLint bar, const QVector3D &selection)
+{
+ GLubyte barIdxRed = 0;
+ GLubyte barIdxGreen = 0;
+ GLubyte barIdxBlue = 0;
+ //static QVector3D prevSel = selection; // TODO: For debugging
+ SelectionType isSelectedType = SelectionNone;
+
+ if (selection == skipColor)
+ return isSelectedType; // skip window
+
+ if (bar <= 255) {
+ barIdxRed = bar;
+ } else if (bar <= 65535) {
+ barIdxGreen = bar / 256;
+ barIdxRed = bar % 256;
+ } else {
+ barIdxBlue = bar / 65535;
+ barIdxGreen = bar % 65535;
+ barIdxRed = bar % 256;
+ }
+
+ QVector3D current = QVector3D(barIdxRed, barIdxGreen, barIdxBlue);
+
+ // TODO: For debugging
+ //if (selection != prevSel) {
+ // qDebug() << selection.x() << selection .y() << selection.z();
+ // prevSel = selection;
+ //}
+
+ if (current == selection)
+ isSelectedType = SelectionBar;
+
+ return isSelectedType;
+}
+
+bool Maps3DController::isValid(const MapRenderItem &item)
+{
+ bool retval = true;
+ if (item.value() < 0) {
+ qCritical("Data item value out of range");
+ retval = false;
+ } else if (item.mapPosition().x() < 0 || item.mapPosition().x() > m_areaSize.width()) {
+ qCritical("Data item x position out of range");
+ retval = false;
+ } else if (item.mapPosition().y() < 0 || item.mapPosition().y() > m_areaSize.height()) {
+ qCritical("Data item y position out of range");
+ retval = false;
+ }
+ return retval;
+}
+
+void Maps3DController::setDataProxy(QMapDataProxy *proxy)
+{
+ delete m_data;
+ m_data = proxy;
+
+ QObject::connect(m_data, &QMapDataProxy::arrayReset, this, &Maps3DController::handleArrayReset);
+ QObject::connect(m_data, &QMapDataProxy::itemsAdded, this, &Maps3DController::handleItemsAdded);
+ QObject::connect(m_data, &QMapDataProxy::itemsChanged, this, &Maps3DController::handleItemsChanged);
+ QObject::connect(m_data, &QMapDataProxy::itemsRemoved, this, &Maps3DController::handleItemsRemoved);
+ QObject::connect(m_data, &QMapDataProxy::itemsInserted, this, &Maps3DController::handleItemsInserted);
+
+ // emit something? Renderer might be interested?
+}
+
+QMapDataProxy *Maps3DController::dataProxy()
+{
+ return m_data;
+}
+
+void Maps3DController::handleLimitChange()
+{
+ QPair<GLfloat, GLfloat> limits = m_data->dptr()->limitValues();
+ m_heightNormalizer = qMax(qAbs(limits.second), qAbs(limits.first));
+ calculateHeightAdjustment(limits);
+
+ //emit limitsChanged(limits);
+}
+
+void Maps3DController::handleArrayReset()
+{
+ handleLimitChange();
+ m_valuesDirty = true;
+}
+
+void Maps3DController::handleItemsAdded(int startIndex, int count)
+{
+ Q_UNUSED(startIndex)
+ Q_UNUSED(count)
+ // TODO should dirty only affected values?
+ handleLimitChange();
+ m_valuesDirty = true;
+}
+
+void Maps3DController::handleItemsChanged(int startIndex, int count)
+{
+ Q_UNUSED(startIndex)
+ Q_UNUSED(count)
+ // TODO should dirty only affected values?
+ handleLimitChange();
+ m_valuesDirty = true;
+}
+
+void Maps3DController::handleItemsRemoved(int startIndex, int count)
+{
+ Q_UNUSED(startIndex)
+ Q_UNUSED(count)
+ // TODO should dirty only affected values?
+ handleLimitChange();
+ m_valuesDirty = true;
+}
+
+void Maps3DController::handleItemsInserted(int startIndex, int count)
+{
+ Q_UNUSED(startIndex)
+ Q_UNUSED(count)
+ // TODO should dirty only affected values?
+ handleLimitChange();
+ m_valuesDirty = true;
+}
+
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/engine/maps3dcontroller_p.h b/src/datavis3d/engine/maps3dcontroller_p.h
new file mode 100644
index 00000000..d0c2e74e
--- /dev/null
+++ b/src/datavis3d/engine/maps3dcontroller_p.h
@@ -0,0 +1,253 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef MAPS3DCONTROLLER_P_H
+#define MAPS3DCONTROLLER_P_H
+
+#include "datavis3dglobal_p.h"
+#include "q3dmaps.h"
+#include "maprenderitem_p.h"
+#include <QOpenGLFunctions>
+#include <QFont>
+
+//#define DISPLAY_RENDER_SPEED
+
+class QPoint;
+class QSizeF;
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class ShaderHelper;
+class ObjectHelper;
+class TextureHelper;
+class Theme;
+class Drawer;
+class Maps3DRenderer;
+class CameraHelper;
+class QMapDataProxy;
+
+class QT_DATAVIS3D_EXPORT Maps3DController : public QObject, public QOpenGLFunctions
+{
+ Q_OBJECT
+public:
+ enum SelectionType {
+ SelectionNone = 0,
+ SelectionBar,
+ SelectionRow,
+ SelectionColumn
+ };
+
+ enum MousePressType {
+ MouseNone = 0,
+ MouseOnScene,
+ MouseOnOverview,
+ MouseOnZoom,
+ MouseRotating,
+ MouseOnPinch
+ };
+
+public:
+ Maps3DController(const QRect &rect);
+ ~Maps3DController();
+
+ void initializeOpenGL();
+ virtual void synchDataToRenderer();
+ void render(const GLuint defaultFboHandle = 0);
+
+ // bar specifications; base thickness in x, y and z, enum to indicate which direction is increased with value
+ // TODO: Start using thickness also in adjustment direction; use it as a relative value.
+ // For example, in AdjustAll mode setting thickness to (0.1f, 1.0f, 0.5f) would apply value to
+ // x at 10%, y at 100% and z at 50%. If a dimension is not included, given thickness states its absolute value.
+ void setBarSpecs(const QVector3D &thickness = QVector3D(1.0f, 1.0f, 1.0f),
+ Q3DMaps::AdjustmentDirection direction = Q3DMaps::AdjustHeight);
+
+ // bar type; bars (=cubes), pyramids, cones, cylinders, balls, etc.
+ void setBarType(QDataVis::MeshStyle style, bool smooth = false);
+
+ // override bar type with own mesh
+ void setMeshFileName(const QString &objFileName);
+
+ // Select preset camera placement
+ void setCameraPreset(QDataVis::CameraPreset preset);
+
+ // Set camera rotation if you don't want to use the presets (in horizontal (-180...180) and
+ // vertical (0...90) angles and distance in percentage (10...500))
+ void setCameraPosition(GLfloat horizontal, GLfloat vertical, GLint distance = 100);
+
+ // Set theme (bar colors, shaders, window color, background colors, light intensity and text colors are affected)
+ void setTheme(QDataVis::ColorTheme theme);
+
+ // Set color if you don't want to use themes. Set uniform to false if you want the (height) color to change from bottom to top
+ void setBarColor(QColor baseColor, QColor heightColor, bool uniform = true);
+
+ // Set area specs
+ void setAreaSpecs(const QRect &areaRect, const QImage &image);
+
+ // Set area image
+ void setImage(const QImage &image);
+
+ // TODO: light placement API
+
+ // Change selection mode; single bar, bar and row, bar and column, or all
+ void setSelectionMode(QDataVis::SelectionMode mode);
+ QDataVis::SelectionMode selectionMode();
+
+ // Font size adjustment
+ void setFontSize(float fontsize);
+ float fontSize();
+
+ // Set font
+ void setFont(const QFont &font);
+ QFont font();
+
+ // Label transparency adjustment
+ void setLabelTransparency(QDataVis::LabelTransparency transparency);
+ QDataVis::LabelTransparency labelTransparency();
+
+ // Adjust shadow quality
+ QDataVis::ShadowQuality setShadowQuality(QDataVis::ShadowQuality quality);
+ QDataVis::ShadowQuality shadowQuality();
+
+ // Size
+ const QSize size();
+ const QRect boundingRect();
+ void setBoundingRect(const QRect boundingRect);
+ void setWidth(const int width);
+ int width();
+ void setHeight(const int height);
+ int height();
+ void setX(const int x);
+ int x();
+ void setY(const int y);
+ int y();
+
+#if defined(Q_OS_ANDROID)
+ void mouseDoubleClickEvent(QMouseEvent *event);
+ void touchEvent(QTouchEvent *event);
+#endif
+ void mousePressEvent(QMouseEvent *event, const QPoint &mousePos);
+ void mouseReleaseEvent(QMouseEvent *event, const QPoint &mousePos);
+ void mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos);
+ void wheelEvent(QWheelEvent *event);
+ void resizeNotify();
+
+ void loadBarMesh();
+ void loadBackgroundMesh();
+ void loadGridLineMesh();
+ void loadLabelMesh();
+ void initShaders(const QString &vertexShader, const QString &fragmentShader);
+ void initSelectionShader();
+ void initBackgroundShaders(const QString &vertexShader, const QString &fragmentShader);
+ void initLabelShaders(const QString &vertexShader, const QString &fragmentShader);
+ void initSelectionBuffer();
+#if !defined(QT_OPENGL_ES_2)
+ void initDepthShader();
+ void initDepthBuffer();
+#endif
+ void updateTextures();
+ void calculateSceneScalingFactors(const QRect &areaRect);
+ void calculateHeightAdjustment(const QPair<GLfloat, GLfloat> &limits);
+ void calculateTranslation(MapRenderItem &item);
+ SelectionType isSelected(GLint bar, const QVector3D &selection);
+ bool isValid(const MapRenderItem &item);
+
+ // Sets the data proxy. Assumes ownership of the data proxy. Deletes old proxy.
+ void setDataProxy(QMapDataProxy *proxy);
+ QMapDataProxy *dataProxy();
+
+ void handleLimitChange();
+
+public slots:
+ void handleArrayReset();
+ void handleItemsAdded(int startIndex, int count);
+ void handleItemsChanged(int startIndex, int count);
+ void handleItemsRemoved(int startIndex, int count);
+ void handleItemsInserted(int startIndex, int count);
+
+private:
+ void drawScene(const GLuint defaultFboHandle);
+
+ Maps3DRenderer *m_renderer;
+ CameraHelper *m_camera;
+
+ ShaderHelper *m_barShader;
+ ShaderHelper *m_depthShader;
+ ShaderHelper *m_selectionShader;
+ ShaderHelper *m_backgroundShader;
+ ShaderHelper *m_labelShader;
+ ObjectHelper *m_barObj;
+ ObjectHelper *m_backgroundObj;
+ ObjectHelper *m_gridLineObj;
+ ObjectHelper *m_labelObj;
+ QString m_objFile;
+ MousePressType m_mousePressed;
+ QPoint m_mousePos;
+ GLint m_zoomLevel;
+ GLfloat m_autoScaleAdjustment;
+ GLfloat m_horizontalRotation;
+ GLfloat m_verticalRotation;
+ QVector3D m_barThickness;
+ GLfloat m_heightNormalizer;
+ GLfloat m_yAdjustment;
+ GLfloat m_scaleFactor;
+ Theme *m_theme;
+ bool m_isInitialized;
+ QDataVis::SelectionMode m_selectionMode;
+ BarRenderItem *m_selectedBar; // points to renderitem array
+ BarRenderItem *m_previouslySelectedBar; // points to renderitem array
+ QString m_axisLabelX;
+ QString m_axisLabelZ;
+ QString m_axisLabelY;
+ QRect m_sceneViewPort;
+ QRect m_zoomViewPort;
+ bool m_zoomActivated;
+ TextureHelper *m_textureHelper;
+ QDataVis::LabelTransparency m_labelTransparency;
+ QFont m_font;
+ Drawer *m_drawer;
+ QSizeF m_areaSize;
+ GLuint m_bgrTexture;
+ GLuint m_depthTexture;
+ GLuint m_selectionTexture;
+ GLuint m_depthFrameBuffer;
+ GLuint m_selectionFrameBuffer;
+ GLuint m_selectionDepthBuffer;
+ bool m_updateLabels;
+ Q3DMaps::AdjustmentDirection m_adjustDirection;
+ QDataVis::ShadowQuality m_shadowQuality;
+ GLfloat m_shadowQualityToShader;
+ bool m_bgrHasAlpha;
+ QRect m_boundingRect;
+ QMapDataProxy *m_data;
+ bool m_valuesDirty;
+ MapRenderItemArray m_renderItemArray;
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/engine/maps3drenderer.cpp b/src/datavis3d/engine/maps3drenderer.cpp
new file mode 100644
index 00000000..c05f2f51
--- /dev/null
+++ b/src/datavis3d/engine/maps3drenderer.cpp
@@ -0,0 +1,74 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "maps3dcontroller_p.h"
+#include "maps3drenderer_p.h"
+#include "camerahelper_p.h"
+#include "shaderhelper_p.h"
+#include "objecthelper_p.h"
+#include "texturehelper_p.h"
+#include "theme_p.h"
+#include "utils_p.h"
+#include "drawer_p.h"
+
+#include <QOpenGLFunctions>
+#include <QMatrix4x4>
+#include <QOpenGLPaintDevice>
+#include <QPainter>
+#include <QScreen>
+#include <QMouseEvent>
+
+#include <qmath.h>
+
+#include <QDebug>
+
+//#define DISPLAY_RENDER_SPEED
+
+// Uncommenting this draws the shadow map with wider FOV than scene itself, making the light
+// seem to be closer to scene than it actually is. This way shadows look slightly better (to me anyway)
+#define USE_WIDER_SHADOWS
+
+// You can verify that depth buffer drawing works correctly by uncommenting this.
+// You should see the scene from where the light is
+//#define SHOW_DEPTH_TEXTURE_SCENE
+
+#ifdef DISPLAY_RENDER_SPEED
+#include <QTime>
+#endif
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+//#define DISPLAY_FULL_DATA_ON_SELECTION // Append selection value text with row and column labels
+
+Maps3DRenderer::Maps3DRenderer(Maps3DController *controller) : QObject(controller)
+{
+}
+
+Maps3DRenderer::~Maps3DRenderer()
+{
+}
+
+void Maps3DRenderer::render(CameraHelper *camera, const GLuint defaultFboHandle)
+{
+ Q_UNUSED(camera)
+ Q_UNUSED(defaultFboHandle)
+ // TODO: Implement
+}
+
+
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/engine/maps3drenderer_p.h b/src/datavis3d/engine/maps3drenderer_p.h
new file mode 100644
index 00000000..89054e83
--- /dev/null
+++ b/src/datavis3d/engine/maps3drenderer_p.h
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef MAPS3DRENDERER_P_H
+#define MAPS3DRENDERER_P_H
+
+#include <QOpenGLFunctions>
+
+#include "datavis3dglobal_p.h"
+#include "camerahelper_p.h"
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class Maps3DController;
+
+class QT_DATAVIS3D_EXPORT Maps3DRenderer : public QObject, public QOpenGLFunctions
+{
+
+public:
+ explicit Maps3DRenderer(Maps3DController *controller);
+ ~Maps3DRenderer();
+
+ void render(CameraHelper *camera, const GLuint defaultFboHandle);
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/engine/meshes/scatterdot.obj b/src/datavis3d/engine/meshes/scatterdot.obj
new file mode 100644
index 00000000..d994a80f
--- /dev/null
+++ b/src/datavis3d/engine/meshes/scatterdot.obj
@@ -0,0 +1,28 @@
+# Blender v2.66 (sub 0) OBJ File: 'scatterdot.blend'
+# www.blender.org
+o Cone
+v 0.000000 -0.500000 -1.000000
+v 0.866025 -0.500000 0.500000
+v 0.000000 0.500000 0.000000
+v -0.866025 -0.500000 0.500000
+vt 0.999727 0.000000
+vt 1.000000 0.492691
+vt 0.522886 0.369782
+vt 0.477114 0.973202
+vt 0.000000 1.096111
+vt 0.000273 0.603420
+vt 0.523159 0.985382
+vt 0.522886 0.492691
+vt 1.000000 0.615600
+vt 0.000000 0.603420
+vt 0.000617 0.000000
+vt 0.522886 0.302245
+vn -0.833033 -0.273293 0.480941
+vn 0.000000 0.999969 0.000000
+vn 0.000000 -0.273293 -0.961913
+vn 0.833033 -0.273293 0.480941
+s 1
+f 4/1/1 3/2/2 1/3/3
+f 1/4/3 3/5/2 2/6/4
+f 2/7/4 3/8/2 4/9/1
+f 1/10/3 2/11/4 4/12/1
diff --git a/src/datavis3d/engine/meshes/scatterdotFlat.obj b/src/datavis3d/engine/meshes/scatterdotFlat.obj
new file mode 100644
index 00000000..4052738d
--- /dev/null
+++ b/src/datavis3d/engine/meshes/scatterdotFlat.obj
@@ -0,0 +1,28 @@
+# Blender v2.66 (sub 0) OBJ File: 'scatterdot.blend'
+# www.blender.org
+o Cone
+v 0.000000 -0.500000 -1.000000
+v 0.866025 -0.500000 0.500000
+v 0.000000 0.500000 0.000000
+v -0.866025 -0.500000 0.500000
+vt 0.999727 0.000000
+vt 1.000000 0.492691
+vt 0.522886 0.369782
+vt 0.477114 0.973202
+vt 0.000000 1.096111
+vt 0.000273 0.603420
+vt 0.523159 0.985382
+vt 0.522886 0.492691
+vt 1.000000 0.615600
+vt 0.000000 0.603420
+vt 0.000617 0.000000
+vt 0.522886 0.302245
+vn -0.774597 0.447214 -0.447214
+vn 0.774597 0.447214 -0.447214
+vn -0.000000 0.447214 0.894427
+vn 0.000000 -1.000000 -0.000000
+s off
+f 4/1/1 3/2/1 1/3/1
+f 1/4/2 3/5/2 2/6/2
+f 2/7/3 3/8/3 4/9/3
+f 1/10/4 2/11/4 4/12/4
diff --git a/src/datavis3d/engine/q3dbars.cpp b/src/datavis3d/engine/q3dbars.cpp
index 39750b38..e46d5d14 100644
--- a/src/datavis3d/engine/q3dbars.cpp
+++ b/src/datavis3d/engine/q3dbars.cpp
@@ -1,58 +1,31 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
#include "q3dbars.h"
#include "q3dbars_p.h"
-#include "bars3dshared_p.h"
+#include "bars3dcontroller_p.h"
+#include "qvalueaxis.h"
-#include <QOpenGLPaintDevice>
-#include <QPainter>
-#include <QScreen>
#include <QMouseEvent>
-#include <qmath.h>
-
#include <QDebug>
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVIS3D_BEGIN_NAMESPACE
/*!
* \class Q3DBars
@@ -104,138 +77,14 @@ QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
*/
/*!
- \enum BarStyle
-
- Predefined bar types.
-
- \value Bars
- Basic cubic bar.
- \value Pyramids
- Four -sided pyramid.
- \value Cones
- Basic cone.
- \value Cylinders
- Basic cylinder.
- \value BevelBars
- Slilghtly beveled (rounded) cubic bar.
- \value Spheres
- Sphere. Not usable in Q3DBars.
-*/
-
-/*!
- \enum CameraPreset
-
- Predefined positions for camera.
-
- \value PresetFrontLow
- \value PresetFront
- \value PresetFrontHigh
- \value PresetLeftLow
- \value PresetLeft
- \value PresetLeftHigh
- \value PresetRightLow
- \value PresetRight
- \value PresetRightHigh
- \value PresetBehindLow
- \value PresetBehind
- \value PresetBehindHigh
- \value PresetIsometricLeft
- \value PresetIsometricLeftHigh
- \value PresetIsometricRight
- \value PresetIsometricRightHigh
- \value PresetDirectlyAbove
- \value PresetDirectlyAboveCW45
- \value PresetDirectlyAboveCCW45
- \value PresetFrontBelow
- From PresetFrontBelow onward these only work for graphs including negative values.
- They act as Preset...Low for positive-only values.
- \value PresetLeftBelow
- \value PresetRightBelow
- \value PresetBehindBelow
- \value PresetDirectlyBelow
- Acts as PresetFrontLow for positive -only bars.
-*/
-
-/*!
- \enum ColorTheme
-
- Predefined color themes.
-
- \value ThemeSystem
- \value ThemeBlueCerulean
- \value ThemeBlueIcy
- \value ThemeBlueNcs
- \value ThemeBrownSand
- \value ThemeDark
- \value ThemeHighContrast
- \value ThemeLight
-*/
-
-/*!
- \enum SelectionMode
-
- Bar selection modes.
-
- \value ModeNone
- Selection mode disabled.
- \value ModeBar
- Selection selects a single bar.
- \value ModeBarAndRow
- Selection selects a single bar and highlights the row it is on.
- \value ModeBarAndColumn
- Selection selects a single bar and highlights the column it is on.
- \value ModeBarRowAndColumn
- Selection selects a single bar and highlights the row and the column it is on.
- \value ModeZoomRow
- Selection selects a single bar and displays the row it is on in a separate view. The
- original view is shrunk into upper left corner. Original view is restored by clicking
- on it.
- \value ModeZoomColumn
- Selection selects a single bar and displays the column it is on in a separate view. The
- original view is shrunk into upper left corner. Original view is restored by clicking
- on it.
-*/
-
-/*!
- \enum ShadowQuality
-
- Quality of shadows.
-
- \value ShadowNone
- Shadows are disabled.
- \value ShadowLow
- Shadows are rendered in low quality.
- \value ShadowMedium
- Shadows are rendered in medium quality.
- \value ShadowHigh
- Shadows are rendered in high quality.
-*/
-
-/*!
- \enum LabelTransparency
-
- Label transparencies.
-
- \value TransparencyNone
- Full solid, using colors from theme.
- \value TransparencyFromTheme
- Use colors and transparencies from theme.
- \value TransparencyNoBackground
- Draw just text on transparent background.
-*/
-
-/*!
- * \a fbohandle Handle to QML2 scene graph's framebuffer object. Developers should not need to
- * ever use this directly. Not used when using C++ API.
- *
- * \a windowsize QML2 window size Developers should not need to ever use this directly. Not
- * used when using C++ API.
- *
- * Constructs a new 3D bar window. Parameters are not used unless instantiating from Qt Quick 2.
+ * Constructs a new 3D bar window.
*/
-Q3DBars::Q3DBars(GLuint fbohandle, const QSize &windowsize)
- : d_ptr(new Q3DBarsPrivate(this, geometry(), fbohandle))
+Q3DBars::Q3DBars()
+ : d_ptr(new Q3DBarsPrivate(this, geometry()))
{
+ d_ptr->m_shared->initializeOpenGL();
+ QObject::connect(d_ptr->m_shared, &Bars3dController::shadowQualityChanged, this,
+ &Q3DBars::handleShadowQualityUpdate);
}
/*!
@@ -248,19 +97,15 @@ Q3DBars::~Q3DBars()
/*!
* \internal
*/
-void Q3DBars::initialize()
+void Q3DBars::render()
{
- d_ptr->m_shared->setWidth(width());
- d_ptr->m_shared->setHeight(height());
- d_ptr->m_shared->initializeOpenGL();
+ d_ptr->m_shared->synchDataToRenderer();
+ d_ptr->m_shared->render();
}
-/*!
- * \internal
- */
-void Q3DBars::render()
+void Q3DBars::handleShadowQualityUpdate(QDataVis::ShadowQuality quality)
{
- d_ptr->m_shared->render();
+ emit shadowQualityChanged(quality);
}
#if defined(Q_OS_ANDROID)
@@ -286,7 +131,7 @@ void Q3DBars::touchEvent(QTouchEvent *event)
*/
void Q3DBars::mousePressEvent(QMouseEvent *event)
{
- d_ptr->m_shared->mousePressEvent(event);
+ d_ptr->m_shared->mousePressEvent(event, event->pos());
}
/*!
@@ -294,7 +139,7 @@ void Q3DBars::mousePressEvent(QMouseEvent *event)
*/
void Q3DBars::mouseReleaseEvent(QMouseEvent *event)
{
- d_ptr->m_shared->mouseReleaseEvent(event);
+ d_ptr->m_shared->mouseReleaseEvent(event, event->pos());
}
/*!
@@ -302,7 +147,7 @@ void Q3DBars::mouseReleaseEvent(QMouseEvent *event)
*/
void Q3DBars::mouseMoveEvent(QMouseEvent *event)
{
- d_ptr->m_shared->mouseMoveEvent(event);
+ d_ptr->m_shared->mouseMoveEvent(event, event->pos());
}
/*!
@@ -319,10 +164,7 @@ void Q3DBars::wheelEvent(QWheelEvent *event)
void Q3DBars::resizeEvent(QResizeEvent *event)
{
Q_UNUSED(event);
- d_ptr->m_shared->setWidth(width());
- d_ptr->m_shared->setHeight(height());
- if (d_ptr->m_shared->m_isInitialized)
- d_ptr->m_shared->resizeNotify();
+ d_ptr->m_shared->setSize(width(), height());
}
// TODO: Document
@@ -358,7 +200,7 @@ void Q3DBars::setBarSpecs(QSizeF thickness, QSizeF spacing, bool relative)
}
/*!
- * \a style One of the values in \c BarStyle. \c Bars by default.
+ * \a style One of the values in \c MeshStyle. \c Bars by default.
*
* \a smooth A flag to set shading to smooth. \c false by default.
*
@@ -366,7 +208,7 @@ void Q3DBars::setBarSpecs(QSizeF thickness, QSizeF spacing, bool relative)
*
* \sa setMeshFileName()
*/
-void Q3DBars::setBarType(BarStyle style, bool smooth)
+void Q3DBars::setBarType(QDataVis::MeshStyle style, bool smooth)
{
d_ptr->m_shared->setBarType(style, smooth);
}
@@ -376,30 +218,27 @@ void Q3DBars::setBarType(BarStyle style, bool smooth)
*
* \a samplesColumn How many items there are per row.
*
- * \a labelRow QString label for the rows, ie. x -axis label.
- *
- * \a labelColumn QString label for the columns, ie. z -axis label.
- *
- * \a labelHeight QString label for height, ie. y -axis label.
- *
* Set up sample space. This must be called to initialize the sample space before adding data to the
* Q3DBars.
*
* \sa addDataRow(), addDataSet()
*/
-void Q3DBars::setupSampleSpace(int samplesRow, int samplesColumn, const QString &labelRow,
- const QString &labelColumn, const QString &labelHeight)
+void Q3DBars::setupSampleSpace(int samplesRow, int samplesColumn)
{
- d_ptr->m_shared->setupSampleSpace(samplesRow, samplesColumn, labelRow, labelColumn,
- labelHeight);
+ d_ptr->m_shared->setupSampleSpace(samplesRow, samplesColumn);
+}
+
+QSize Q3DBars::sampleSpace() const
+{
+ return QSize(d_ptr->m_shared->rowCount(), d_ptr->m_shared->columnCount());
}
/*!
- * \a preset Move camera to a predefined position from \c CameraPreset.
+ * \a preset Move camera to a predefined position from \c QDataVis::CameraPreset.
*
* Moves camera to a predefined position.
*/
-void Q3DBars::setCameraPreset(CameraPreset preset)
+void Q3DBars::setCameraPreset(QDataVis::CameraPreset preset)
{
d_ptr->m_shared->setCameraPreset(preset);
}
@@ -416,20 +255,20 @@ void Q3DBars::setCameraPreset(CameraPreset preset)
* on data values. Negative vertical angles are allowed only if there are negative bar values.
* Distance is adjustable between 10 and 500.
*/
-void Q3DBars::setCameraPosition(GLfloat horizontal, GLfloat vertical, GLint distance)
+void Q3DBars::setCameraPosition(qreal horizontal, qreal vertical, int distance)
{
- d_ptr->m_shared->setCameraPosition(horizontal, vertical, distance);
+ d_ptr->m_shared->setCameraPosition(GLfloat(horizontal), GLfloat(vertical), GLint(distance));
}
/*!
- * \a theme Apply a predefined theme from \c ColorTheme.
+ * \a theme Apply a predefined theme from \c QDataVis::ColorTheme.
*
* Sets a predefined theme. Theme affects bar colors, label colors, text color, background color,
* window color and grid color. Lighting is also adjusted by themes.
*/
-void Q3DBars::setTheme(ColorTheme theme)
+void Q3DBars::setTheme(QDataVis::ColorTheme theme)
{
- d_ptr->m_shared->setTheme(theme);
+ d_ptr->m_shared->setColorTheme(theme);
}
/*!
@@ -449,23 +288,22 @@ void Q3DBars::setTheme(ColorTheme theme)
*/
void Q3DBars::setBarColor(QColor baseColor, QColor heightColor, QColor depthColor, bool uniform)
{
- d_ptr->m_shared->setBarColor(baseColor, heightColor, depthColor, uniform);
+ d_ptr->m_shared->setObjectColor(baseColor, heightColor, depthColor, uniform);
}
/*!
- * \a mode Set bar selection mode from \c SelectionMode. \c ModeBar by default.
+ * \property Q3DBars::selectionMode
+ *
+ * \a mode Set bar selection mode from \c QDataVis::SelectionMode. \c ModeItem by default.
*
* Sets bar selection mode to be used.
*/
-void Q3DBars::setSelectionMode(SelectionMode mode)
+void Q3DBars::setSelectionMode(QDataVis::SelectionMode mode)
{
d_ptr->m_shared->setSelectionMode(mode);
}
-/*!
- * \return \c SelectionMode.
- */
-SelectionMode Q3DBars::selectionMode()
+QDataVis::SelectionMode Q3DBars::selectionMode() const
{
return d_ptr->m_shared->selectionMode();
}
@@ -482,7 +320,7 @@ void Q3DBars::setWindowTitle(const QString &title)
setTitle(title);
}
-QString Q3DBars::windowTitle()
+QString Q3DBars::windowTitle() const
{
return title();
}
@@ -527,192 +365,116 @@ void Q3DBars::setFont(const QFont &font)
d_ptr->m_shared->setFont(font);
}
-QFont Q3DBars::font()
+QFont Q3DBars::font() const
{
return d_ptr->m_shared->font();
}
/*!
- * \a transparency Transparency level of labels from \c LabelTransparency.
+ * \property Q3DBars::labelTransparency
+ *
+ * \a transparency Transparency level of labels from \c QDataVis::LabelTransparency.
* \c TransparencyFromTheme by default.
*
* Sets label transparency.
*/
-void Q3DBars::setLabelTransparency(LabelTransparency transparency)
+void Q3DBars::setLabelTransparency(QDataVis::LabelTransparency transparency)
{
d_ptr->m_shared->setLabelTransparency(transparency);
}
-/*!
- * \return \c LabelTransparency.
- */
-LabelTransparency Q3DBars::labelTransparency()
+QDataVis::LabelTransparency Q3DBars::labelTransparency() const
{
return d_ptr->m_shared->labelTransparency();
}
/*!
- * \property Q3DBars::grid
+ * \property Q3DBars::gridVisible
*
- * \a enable Flag to enable or disable grid. \c true by default.
+ * \a visible Flag to enable or disable grid. \c true by default.
*
* Sets grid drawing on or off.
*/
-void Q3DBars::setGridEnabled(bool enable)
+void Q3DBars::setGridVisible(bool visible)
{
- d_ptr->m_shared->setGridEnabled(enable);
+ d_ptr->m_shared->setGridEnabled(visible);
}
-bool Q3DBars::gridEnabled()
+bool Q3DBars::isGridVisible() const
{
return d_ptr->m_shared->gridEnabled();
}
/*!
- * \property Q3DBars::background
+ * \property Q3DBars::backgroundVisible
*
- * \a enable Flag to enable or disable background. \c true by default.
+ * \a visible Flag to enable or disable background. \c true by default.
*
* Sets backround rendering on or off.
*/
-void Q3DBars::setBackgroundEnabled(bool enable)
+void Q3DBars::setBackgroundVisible(bool visible)
{
- d_ptr->m_shared->setBackgroundEnabled(enable);
+ d_ptr->m_shared->setBackgroundEnabled(visible);
}
-bool Q3DBars::backgroundEnabled()
+bool Q3DBars::isBackgroundVisible() const
{
return d_ptr->m_shared->backgroundEnabled();
}
/*!
- * \a quality Shadow quality from \c ShadowQuality. \c ShadowLow by default.
+ * \property Q3DBars::shadowQuality
+ *
+ * \a quality Shadow quality from \c QDataVis::ShadowQuality. \c ShadowLow by default.
+ *
+ * Sets shadow quality. If setting QDataVis::ShadowQuality of a certain level fails, a level is lowered
+ * until it is successful and shadowQualityChanged signal is emitted for each time the change is done.
*/
-void Q3DBars::setShadowQuality(ShadowQuality quality)
+void Q3DBars::setShadowQuality(QDataVis::ShadowQuality quality)
{
- d_ptr->m_shared->setShadowQuality(quality);
+ return d_ptr->m_shared->setShadowQuality(quality);
}
-/*!
- * \return \c ShadowQuality.
- */
-ShadowQuality Q3DBars::shadowQuality()
+QDataVis::ShadowQuality Q3DBars::shadowQuality() const
{
return d_ptr->m_shared->shadowQuality();
}
-/*!
- * \a tickCount How many ticks will be drawn. \c 5 by default.
- *
- * \a step How large a step each tick is.
- *
- * \a minimum Minimum value a bar in data set can have. Setting this correctly is especially
- * important if values can be negative, or autoscaling won't work correctly.
- *
- * Sets tick count and step. Note; tickCount * step should be the maximum possible value of data
- * set.
- */
-void Q3DBars::setTickCount(GLint tickCount, GLfloat step, GLfloat minimum)
+QCategoryAxis *Q3DBars::rowAxis()
{
- d_ptr->m_shared->setTickCount(tickCount, step, minimum);
+ return reinterpret_cast<QCategoryAxis *>(d_ptr->m_shared->axisX());
}
-/*!
- * \a dataRow A vector of floats representing a single row of data. Sample space must be large
- * enough to hold the row.
- *
- * \a labelRow A QString label for the row.
- *
- * \a labelsColumn A vector of strings, one for each item in the row.
- *
- * Add a row of data. Each new row is added to the front of the sample space, moving previous
- * rows back (if sample space is more than one row deep).
- */
-void Q3DBars::addDataRow(const QVector<float> &dataRow, const QString &labelRow,
- const QVector<QString> &labelsColumn)
+QCategoryAxis *Q3DBars::columnAxis()
{
- d_ptr->m_shared->addDataRow(dataRow, labelRow, labelsColumn);
+ return reinterpret_cast<QCategoryAxis *>(d_ptr->m_shared->axisZ());
}
-/*!
- * \a dataRow A vector of QDataItems representing a single row of data. Sample space must be
- * large enough to hold the row. Ownership of QDataItems is transferred to Q3DBars.
- *
- * \a labelRow A QString label for the row.
- *
- * \a labelsColumn A vector of strings, one for each item in the row.
- *
- * Add a row of data. Each new row is added to the front of the sample space, moving previous
- * rows back (if sample space is more than one row deep).
- */
-void Q3DBars::addDataRow(const QVector<QDataItem*> &dataRow, const QString &labelRow,
- const QVector<QString> &labelsColumn)
+void Q3DBars::setValueAxis(QValueAxis *axis)
{
- d_ptr->m_shared->addDataRow(dataRow, labelRow, labelsColumn);
-}
+ Q_ASSERT(axis);
-/*!
- * \a dataRow A QDataRow instance representing a single row of data. Sample space must be
- * large enough to hold the row. Ownership of QDataRow is transferred to Q3DBars.
- *
- * Add a row of data. Each new row is added to the front of the sample space, moving previous
- * rows back (if sample space is more than one row deep).
- */
-void Q3DBars::addDataRow(QDataRow *dataRow)
-{
- d_ptr->m_shared->addDataRow(dataRow);
+ return d_ptr->m_shared->setAxisY(axis);
}
-/*!
- * \a data A vector of vector of floats representing the whole data set. Sample space must be
- * large enough to hold the set.
- *
- * \a labelsRow A vector of strings, one for each column in the row.
- *
- * \a labelsColumn A vector of strings, one for each row in the column.
- *
- * Adds a whole data set at once. If an old data set exists, it is deleted and replaced with the
- * new one.
- */
-void Q3DBars::addDataSet(const QVector< QVector<float> > &data, const QVector<QString> &labelsRow,
- const QVector<QString> &labelsColumn)
+QValueAxis *Q3DBars::valueAxis()
{
- d_ptr->m_shared->addDataSet(data, labelsRow, labelsColumn);
+ return static_cast<QValueAxis *>(d_ptr->m_shared->axisY());
}
-/*!
- * \a data A vector of vector of QDataItems representing the whole data set. Sample space must
- * be large enough to hold the set. Ownership of QDataItems is transferred to Q3DBars.
- *
- * \a labelsRow A vector of strings, one for each column in the row.
- *
- * \a labelsColumn A vector of strings, one for each row in the column.
- *
- * Adds a whole data set at once. If an old data set exists, it is deleted and replaced with the
- * new one.
- */
-void Q3DBars::addDataSet(const QVector< QVector<QDataItem*> > &data,
- const QVector<QString> &labelsRow,
- const QVector<QString> &labelsColumn)
+void Q3DBars::setDataProxy(QBarDataProxy *proxy)
{
- d_ptr->m_shared->addDataSet(data, labelsRow, labelsColumn);
+ d_ptr->m_shared->setDataProxy(proxy);
}
-/*!
- * \a dataSet A QDataSet instance holding the whole data set. Sample space must
- * be large enough to hold the set. Ownership of QDataSet is transferred to Q3DBars.
- *
- * Adds a whole data set at once. If an old data set exists, it is deleted and replaced with the
- * new one.
- */
-void Q3DBars::addDataSet(QDataSet *dataSet)
+QBarDataProxy *Q3DBars::dataProxy()
{
- d_ptr->m_shared->addDataSet(dataSet);
+ return d_ptr->m_shared->dataProxy();
}
-Q3DBarsPrivate::Q3DBarsPrivate(Q3DBars *q, QRect rect, GLuint fbohandle)
+Q3DBarsPrivate::Q3DBarsPrivate(Q3DBars *q, QRect rect)
: q_ptr(q),
- m_shared(new Bars3dShared(rect, fbohandle))
+ m_shared(new Bars3dController(rect))
{
}
@@ -722,4 +484,4 @@ Q3DBarsPrivate::~Q3DBarsPrivate()
delete m_shared;
}
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/engine/q3dbars.h b/src/datavis3d/engine/q3dbars.h
index 03635e4d..a0eb9cb5 100644
--- a/src/datavis3d/engine/q3dbars.h
+++ b/src/datavis3d/engine/q3dbars.h
@@ -1,147 +1,97 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
#ifndef Q3DBARS_H
#define Q3DBARS_H
-#include "QtDataVis3D/qdatavis3dglobal.h"
-#include "QtDataVis3D/qdatavis3namespace.h"
-#include "q3dwindow.h"
-
+#include <QtDataVis3D/qdatavis3denums.h>
+#include <QtDataVis3D/q3dwindow.h>
#include <QFont>
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVIS3D_BEGIN_NAMESPACE
class Q3DBarsPrivate;
-class QDataItem;
-class QDataRow;
-class QDataSet;
-class LabelItem;
+class QCategoryAxis;
+class QValueAxis;
+class QBarDataProxy;
-class QTENTERPRISE_DATAVIS3D_EXPORT Q3DBars : public Q3DWindow
+class QT_DATAVIS3D_EXPORT Q3DBars : public Q3DWindow
{
Q_OBJECT
+ Q_PROPERTY(QtDataVis3D::QDataVis::SelectionMode selectionMode READ selectionMode WRITE setSelectionMode)
+ Q_PROPERTY(QtDataVis3D::QDataVis::LabelTransparency labelTransparency READ labelTransparency WRITE setLabelTransparency)
+ Q_PROPERTY(QtDataVis3D::QDataVis::ShadowQuality shadowQuality READ shadowQuality WRITE setShadowQuality)
Q_PROPERTY(QString windowTitle READ windowTitle WRITE setWindowTitle)
Q_PROPERTY(QFont font READ font WRITE setFont)
Q_PROPERTY(float fontSize READ fontSize WRITE setFontSize)
- Q_PROPERTY(bool grid READ gridEnabled WRITE setGridEnabled)
- Q_PROPERTY(bool background READ backgroundEnabled WRITE setBackgroundEnabled)
+ Q_PROPERTY(bool gridVisible READ isGridVisible WRITE setGridVisible)
+ Q_PROPERTY(bool backgroundVisible READ isBackgroundVisible WRITE setBackgroundVisible)
+ Q_ENUMS(QtDataVis3D::QDataVis::SelectionMode)
+ Q_ENUMS(QtDataVis3D::QDataVis::ShadowQuality)
+ Q_ENUMS(QtDataVis3D::QDataVis::LabelTransparency)
public:
- explicit Q3DBars(GLuint fbohandle = 0, const QSize &windowsize = QSize());
+ explicit Q3DBars();
~Q3DBars();
- // Add a row of data. Each new row is added to the front of the sample space, moving previous
- // rows back (if sample space is more than one row deep)
- Q_INVOKABLE void addDataRow(const QVector<float> &dataRow,
- const QString &labelRow = QString(),
- const QVector<QString> &labelsColumn = QVector<QString>());
- // ownership of dataItems is transferred
- Q_INVOKABLE void addDataRow(const QVector<QDataItem*> &dataRow,
- const QString &labelRow = QString(),
- const QVector<QString> &labelsColumn = QVector<QString>());
- // ownership of dataRow is transferred
- Q_INVOKABLE void addDataRow(QDataRow *dataRow);
-
- // Add complete data set at a time, as a vector of data rows
- Q_INVOKABLE void addDataSet(const QVector< QVector<float> > &data,
- const QVector<QString> &labelsRow = QVector<QString>(),
- const QVector<QString> &labelsColumn = QVector<QString>());
-
- // ownership of dataItems is transferred
- Q_INVOKABLE void addDataSet(const QVector< QVector<QDataItem*> > &data,
- const QVector<QString> &labelsRow = QVector<QString>(),
- const QVector<QString> &labelsColumn = QVector<QString>());
- // ownership of dataSet is transferred
- Q_INVOKABLE void addDataSet(QDataSet* dataSet);
-
// bar thickness, spacing between bars, and is spacing relative to thickness or absolute
// y -component sets the thickness/spacing of z -direction
// With relative 0.0f means side-to-side, 1.0f = one thickness in between
- Q_INVOKABLE void setBarSpecs(QSizeF thickness = QSizeF(1.0f, 1.0f),
- QSizeF spacing = QSizeF(1.0f, 1.0f),
- bool relative = true);
+ void setBarSpecs(QSizeF thickness = QSizeF(1.0f, 1.0f),
+ QSizeF spacing = QSizeF(1.0f, 1.0f),
+ bool relative = true);
// bar type; bars (=cubes), pyramids, cones, cylinders, etc.
- Q_INVOKABLE void setBarType(BarStyle style, bool smooth = false);
+ void setBarType(QDataVis::MeshStyle style, bool smooth = false);
// how many samples per row and column, and names for axes
- Q_INVOKABLE void setupSampleSpace(int samplesRow, int samplesColumn,
- const QString &labelRow = QString(),
- const QString &labelColumn = QString(),
- const QString &labelHeight = QString());
+ // TODO: This defines the data window, needs additional parameters startRow, startColumn
+ void setupSampleSpace(int samplesRow, int samplesColumn);
+ QSize sampleSpace() const; // TODO: Return QRect once data window properly implemented?
// Select preset camera placement
- Q_INVOKABLE void setCameraPreset(CameraPreset preset);
+ void setCameraPreset(QDataVis::CameraPreset preset);
// Set camera rotation if you don't want to use the presets (in horizontal (-180...180) and
// vertical (0...90) (or (-90...90) if there are negative values) angles and distance in
// percentage (10...500))
- Q_INVOKABLE void setCameraPosition(GLfloat horizontal, GLfloat vertical, GLint distance = 100);
+ void setCameraPosition(qreal horizontal, qreal vertical, int distance = 100);
// Set theme (bar colors, shaders, window color, background colors, light intensity and text
// colors are affected)
- Q_INVOKABLE void setTheme(ColorTheme theme);
+ void setTheme(QDataVis::ColorTheme theme);
// Set color if you don't want to use themes. Set uniform to false if you want the (height)
// color to change from bottom to top
- Q_INVOKABLE void setBarColor(QColor baseColor, QColor heightColor, QColor depthColor,
- bool uniform = true);
-
- // Set tick count and step. Note; tickCount * step should be the maximum possible value of data
- // set. Minimum is the absolute minimum possible value a bar can have. This is especially
- // important to set if values can be negative.
- Q_INVOKABLE void setTickCount(GLint tickCount, GLfloat step, GLfloat minimum = 0.0f);
+ void setBarColor(QColor baseColor, QColor heightColor, QColor depthColor,
+ bool uniform = true);
// override bar type with own mesh
- Q_INVOKABLE void setMeshFileName(const QString &objFileName);
+ void setMeshFileName(const QString &objFileName);
// TODO: light placement API
// Change selection mode; single bar, bar and row, bar and column, or all
- void setSelectionMode(SelectionMode mode);
- SelectionMode selectionMode();
+ void setSelectionMode(QDataVis::SelectionMode mode);
+ QDataVis::SelectionMode selectionMode() const;
// Set window title
void setWindowTitle(const QString &title);
- QString windowTitle();
+ QString windowTitle() const;
// Font size adjustment
void setFontSize(float fontsize);
@@ -149,31 +99,48 @@ public:
// Set font
void setFont(const QFont &font);
- QFont font();
+ QFont font() const;
// Label transparency adjustment
- void setLabelTransparency(LabelTransparency transparency);
- LabelTransparency labelTransparency();
+ void setLabelTransparency(QDataVis::LabelTransparency transparency);
+ QDataVis::LabelTransparency labelTransparency() const;
// Enable or disable background grid
- void setGridEnabled(bool enable);
- bool gridEnabled();
+ void setGridVisible(bool visible);
+ bool isGridVisible() const;
- // TODO: Do these need to be public? Where are they called from?
// Size
void setWidth(const int width);
void setHeight(const int height);
// Enable or disable background mesh
- void setBackgroundEnabled(bool enable);
- bool backgroundEnabled();
+ void setBackgroundVisible(bool visible);
+ bool isBackgroundVisible() const;
// Adjust shadow quality
- void setShadowQuality(ShadowQuality quality);
- ShadowQuality shadowQuality();
+ void setShadowQuality(QDataVis::ShadowQuality quality);
+ QDataVis::ShadowQuality shadowQuality() const;
+
+ // Axes - row & column axes are fixed to category axes, value axis can be
+ // customized.
+ QCategoryAxis *rowAxis();
+ QCategoryAxis *columnAxis();
+ void setValueAxis(QValueAxis *axis);
+ QValueAxis *valueAxis();
+
+ // Sets the data proxy. Assumes ownership of the data proxy. Deletes old proxy.
+ void setDataProxy(QBarDataProxy *proxy);
+ QBarDataProxy *dataProxy();
+
+public slots:
+ // Used to detect when shadow quality changes autonomously due to e.g. resizing.
+ void handleShadowQualityUpdate(QDataVis::ShadowQuality quality);
+
+signals:
+ // Signals shadow quality changes.
+ void shadowQualityChanged(QDataVis::ShadowQuality quality);
protected:
- void initialize();
void render();
#if defined(Q_OS_ANDROID)
@@ -187,12 +154,10 @@ protected:
void resizeEvent(QResizeEvent *event);
private:
- void drawZoomScene();
- void drawScene();
QScopedPointer<Q3DBarsPrivate> d_ptr;
Q_DISABLE_COPY(Q3DBars)
};
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
+QT_DATAVIS3D_END_NAMESPACE
#endif
diff --git a/src/datavis3d/engine/q3dbars_p.h b/src/datavis3d/engine/q3dbars_p.h
index f5d0cf38..9eed8162 100644
--- a/src/datavis3d/engine/q3dbars_p.h
+++ b/src/datavis3d/engine/q3dbars_p.h
@@ -1,41 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
@@ -43,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the Qt API. It exists purely as an
+// This file is not part of the QtDataVis3D API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -52,28 +29,23 @@
#ifndef Q3DBARS_p_H
#define Q3DBARS_p_H
-#include "bars3dshared_p.h"
-#include "qdatavis3namespace.h"
-
-class QOpenGLPaintDevice;
-
-class QPoint;
-class QSizeF;
+#include "bars3dcontroller_p.h"
+#include "qdatavis3denums.h"
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVIS3D_BEGIN_NAMESPACE
class Q3DBars;
class Q3DBarsPrivate : public QObject
{
public:
- Q3DBarsPrivate(Q3DBars *q, QRect rect, GLuint fbohandle);
+ Q3DBarsPrivate(Q3DBars *q, QRect rect);
~Q3DBarsPrivate();
Q3DBars *q_ptr;
- Bars3dShared *m_shared;
+ Bars3dController *m_shared;
};
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
+QT_DATAVIS3D_END_NAMESPACE
#endif
diff --git a/src/datavis3d/engine/q3dmaps.cpp b/src/datavis3d/engine/q3dmaps.cpp
index 0a1ca7ff..ffa5ed1b 100644
--- a/src/datavis3d/engine/q3dmaps.cpp
+++ b/src/datavis3d/engine/q3dmaps.cpp
@@ -1,89 +1,30 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
#include "q3dmaps.h"
#include "q3dmaps_p.h"
-#include "camerahelper_p.h"
-#include "qdataitem_p.h"
-#include "qdatarow_p.h"
-#include "qdataset_p.h"
-#include "shaderhelper_p.h"
-#include "objecthelper_p.h"
-#include "texturehelper_p.h"
-#include "theme_p.h"
-#include "utils_p.h"
-#include "drawer_p.h"
+#include "maps3dcontroller_p.h"
-#include <QOpenGLFunctions>
-#include <QMatrix4x4>
-#include <QOpenGLPaintDevice>
-#include <QPainter>
-#include <QScreen>
#include <QMouseEvent>
-#include <qmath.h>
-
#include <QDebug>
-//#define DISPLAY_RENDER_SPEED
-
-// Uncommenting this draws the shadow map with wider FOV than scene itself, making the light
-// seem to be closer to scene than it actually is. This way shadows look slightly better (to me anyway)
-#define USE_WIDER_SHADOWS
-
-// You can verify that depth buffer drawing works correctly by uncommenting this.
-// You should see the scene from where the light is
-//#define SHOW_DEPTH_TEXTURE_SCENE
-
-#ifdef DISPLAY_RENDER_SPEED
-#include <QTime>
-#endif
-
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
-
-//#define DISPLAY_FULL_DATA_ON_SELECTION // Append selection value text with row and column labels
-
-const GLfloat gridLineWidth = 0.005f;
-GLfloat distanceMod = 0.0f;
-static QVector3D skipColor = QVector3D(255, 255, 255); // Selection texture's background color
+QT_DATAVIS3D_BEGIN_NAMESPACE
/*!
* \class Q3DMaps
@@ -104,8 +45,9 @@ static QVector3D skipColor = QVector3D(255, 255, 255); // Selection texture's ba
* Constructs Q3DMaps.
*/
Q3DMaps::Q3DMaps()
- : d_ptr(new Q3DMapsPrivate(this))
+ : d_ptr(new Q3DMapsPrivate(this, geometry()))
{
+ d_ptr->m_shared->initializeOpenGL();
}
/*!
@@ -118,840 +60,9 @@ Q3DMaps::~Q3DMaps()
/*!
* \internal
*/
-void Q3DMaps::initialize()
-{
- // Initialize shaders
-#if !defined(QT_OPENGL_ES_2)
- if (d_ptr->m_shadowQuality > ShadowNone) {
- if (!d_ptr->m_theme->m_uniformColor) {
- d_ptr->initShaders(QStringLiteral(":/shaders/vertexShadow"),
- QStringLiteral(":/shaders/fragmentShadowNoTexColorOnY"));
- } else {
- d_ptr->initShaders(QStringLiteral(":/shaders/vertexShadow"),
- QStringLiteral(":/shaders/fragmentShadowNoTex"));
- }
- d_ptr->initBackgroundShaders(QStringLiteral(":/shaders/vertexShadow"),
- QStringLiteral(":/shaders/fragmentShadow"));
- // Init the depth buffer (for shadows)
- d_ptr->initDepthBuffer();
- } else {
- if (!d_ptr->m_theme->m_uniformColor) {
- d_ptr->initShaders(QStringLiteral(":/shaders/vertex"),
- QStringLiteral(":/shaders/fragmentColorOnY"));
- } else {
- d_ptr->initShaders(QStringLiteral(":/shaders/vertex"),
- QStringLiteral(":/shaders/fragment"));
- }
- d_ptr->initBackgroundShaders(QStringLiteral(":/shaders/vertexTexture"),
- QStringLiteral(":/shaders/fragmentTexture"));
- }
-#else
- if (!d_ptr->m_theme->m_uniformColor) {
- d_ptr->initShaders(QStringLiteral(":/shaders/vertexES2"),
- QStringLiteral(":/shaders/fragmentColorOnYES2"));
- } else {
- d_ptr->initShaders(QStringLiteral(":/shaders/vertexES2"),
- QStringLiteral(":/shaders/fragmentES2"));
- }
- d_ptr->initBackgroundShaders(QStringLiteral(":/shaders/vertexTexture"), // Same vertex shader ok for ES2
- QStringLiteral(":/shaders/fragmentTextureES2"));
-#endif
- d_ptr->initLabelShaders(QStringLiteral(":/shaders/vertexLabel"),
- QStringLiteral(":/shaders/fragmentLabel"));
-
-#if !defined(QT_OPENGL_ES_2)
- // Init depth shader (for shadows). Init in any case, easier to handle shadow activation if done via api.
- d_ptr->initDepthShader();
-#endif
-
- // Init selection shader
- d_ptr->initSelectionShader();
-
- // Init the selection buffer
- d_ptr->initSelectionBuffer();
-
- // Load default mesh
- d_ptr->loadBarMesh();
-
- // Load background mesh
- d_ptr->loadBackgroundMesh();
-
- // Load grid line mesh
- d_ptr->loadGridLineMesh();
-
- // Load label mesh
- d_ptr->loadLabelMesh();
-
- // Set OpenGL features
- glEnable(GL_DEPTH_TEST);
- glDepthFunc(GL_LESS);
- glEnable(GL_CULL_FACE);
- glCullFace(GL_BACK);
-
-#if !defined(QT_OPENGL_ES_2)
- glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
- glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
- glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
-#endif
-
- // Set initial camera position
- // X must be 0 for rotation to work - we can use "setCameraRotation" for setting it later
- CameraHelper::setDefaultCameraOrientation(QVector3D(0.0f, 0.0f, 1.0f + 2.9f * zComp),
- QVector3D(0.0f, 0.0f, zComp),
- QVector3D(0.0f, 1.0f, 0.0f));
-
- // Adjust to default rotation
- setCameraPosition(d_ptr->m_horizontalRotation, d_ptr->m_verticalRotation, d_ptr->m_zoomLevel);
-
- // Set view port
- glViewport(0, 0, width(), height());
-
- // Set initialized -flag
- d_ptr->m_isInitialized = true;
-
- d_ptr->m_drawer->initializeOpenGL();
-
- // Update default light position
-#ifndef USE_WIDER_SHADOWS
- distanceMod = 1.0f;
-#endif
-}
-
-/*!
- * \internal
- */
void Q3DMaps::render()
{
- if (!d_ptr->m_isInitialized)
- return;
-
-#ifdef DISPLAY_RENDER_SPEED
- // For speed computation
- static bool firstRender = true;
- static QTime lastTime;
- static GLint nbFrames = 0;
- if (firstRender) {
- lastTime.start();
- firstRender = false;
- }
-
- // Measure speed (as milliseconds per frame)
- nbFrames++;
- if (lastTime.elapsed() >= 1000) { // print only if last measurement was more than 1s ago
- qDebug() << qreal(lastTime.elapsed()) / qreal(nbFrames) << "ms/frame (=" << qreal(nbFrames) << "fps)";
- nbFrames = 0;
- lastTime.restart();
- }
-#endif
-
- // Draw scene
- drawScene();
-}
-
-/*!
- * \internal
- */
-void Q3DMaps::drawScene()
-{
- // Set clear color
- QVector3D clearColor = Utils::vectorFromColor(d_ptr->m_theme->m_windowColor);
- glClearColor(clearColor.x(), clearColor.y(), clearColor.z(), 1.0f);
-
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
- static QVector3D selection = skipColor;
-
- // Specify viewport
- glViewport(d_ptr->m_sceneViewPort.x(), d_ptr->m_sceneViewPort.y(),
- d_ptr->m_sceneViewPort.width(), d_ptr->m_sceneViewPort.height());
-
- // Set up projection matrix
- QMatrix4x4 projectionMatrix;
- projectionMatrix.perspective(45.0f, (GLfloat)d_ptr->m_sceneViewPort.width()
- / (GLfloat)d_ptr->m_sceneViewPort.height(), 0.1f, 100.0f);
-
- // Calculate view matrix
- QMatrix4x4 viewMatrix = CameraHelper::calculateViewMatrix(d_ptr->m_mousePos,
- d_ptr->m_zoomLevel
- * d_ptr->m_zoomAdjustment,
- d_ptr->m_sceneViewPort.width(),
- d_ptr->m_sceneViewPort.height());
-
- // Get light position (rotate light with camera, a bit above it (as set in defaultLightPos))
- QVector3D lightPos = CameraHelper::calculateLightPosition(defaultLightPos, 0.0f, distanceMod);
-
- // Map adjustment direction to model matrix scaling
- GLfloat heightMultiplier = 0.0f;
- GLfloat widthMultiplier = 0.0f;
- GLfloat depthMultiplier = 0.0f;
- GLfloat heightScaler = 0.0f;
- GLfloat widthScaler = 0.0f;
- GLfloat depthScaler = 0.0f;
- switch (d_ptr->m_adjustDirection) {
- case AdjustHeight:
- widthMultiplier = 0.0f;
- heightMultiplier = 1.0f;
- depthMultiplier = 0.0f;
- widthScaler = d_ptr->m_barThickness.x() / d_ptr->m_scaleFactor;
- heightScaler = 0.0f;
- depthScaler = d_ptr->m_barThickness.z() / d_ptr->m_scaleFactor;
- break;
- case AdjustWidth:
- widthMultiplier = 1.0f;
- heightMultiplier = 0.0f;
- depthMultiplier = 0.0f;
- widthScaler = 0.0f;
- heightScaler = d_ptr->m_barThickness.y() / d_ptr->m_scaleFactor;
- depthScaler = d_ptr->m_barThickness.z() / d_ptr->m_scaleFactor;
- break;
- case AdjustDepth:
- widthMultiplier = 0.0f;
- heightMultiplier = 0.0f;
- depthMultiplier = 1.0f;
- widthScaler = d_ptr->m_barThickness.x() / d_ptr->m_scaleFactor;
- heightScaler = d_ptr->m_barThickness.y() / d_ptr->m_scaleFactor;
- depthScaler = 0.0f;
- break;
- case AdjustRadius:
- widthMultiplier = 1.0f;
- heightMultiplier = 0.0f;
- depthMultiplier = 1.0f;
- widthScaler = 0.0f;
- heightScaler = d_ptr->m_barThickness.y() / d_ptr->m_scaleFactor;
- depthScaler = 0.0f;
- break;
- case AdjustAll:
- widthMultiplier = 1.0f;
- heightMultiplier = 1.0f;
- depthMultiplier = 1.0f;
- widthScaler = 0.0f;
- heightScaler = 0.0f;
- depthScaler = 0.0f;
- break;
- }
-
- // Introduce regardless of shadow quality to simplify logic
- QMatrix4x4 depthViewMatrix;
- QMatrix4x4 depthProjectionMatrix;
-
-#if !defined(QT_OPENGL_ES_2)
- if (d_ptr->m_shadowQuality > ShadowNone) {
- // Render scene into a depth texture for using with shadow mapping
- // Bind depth shader
- d_ptr->m_depthShader->bind();
-
- // Set viewport for depth map rendering. Must match texture size. Larger values give smoother shadows.
- glViewport(d_ptr->m_sceneViewPort.x(), d_ptr->m_sceneViewPort.y(),
- d_ptr->m_sceneViewPort.width() * d_ptr->m_shadowQuality,
- d_ptr->m_sceneViewPort.height() * d_ptr->m_shadowQuality);
-
- // Enable drawing to framebuffer
- glBindFramebuffer(GL_FRAMEBUFFER, d_ptr->m_depthFrameBuffer);
- glClear(GL_DEPTH_BUFFER_BIT);
-
- // Set front face culling to reduce self-shadowing issues
- glCullFace(GL_FRONT);
-
- // Get the depth view matrix
- // It may be possible to hack lightPos here if we want to make some tweaks to shadow
- depthViewMatrix.lookAt(lightPos, QVector3D(0.0f, -d_ptr->m_yAdjustment, zComp),
- QVector3D(0.0f, 1.0f, 0.0f));
- // TODO: Why does depthViewMatrix.column(3).y() goes to zero when we're directly above? That causes the scene to be not drawn from above -> must be fixed
- //qDebug() << lightPos << depthViewMatrix << depthViewMatrix.column(3);
- // Set the depth projection matrix
-#ifdef USE_WIDER_SHADOWS
- // Use this for a bit exaggerated shadows
- depthProjectionMatrix.perspective(60.0f, (GLfloat)d_ptr->m_sceneViewPort.width()
- / (GLfloat)d_ptr->m_sceneViewPort.height(), 3.0f, 100.0f);
-#else
- // Use these for normal shadows, with the light further away
- depthProjectionMatrix = projectionMatrix;
-#endif
-#if 0
- // Draw background to depth buffer (You don't want to do this, except maybe for debugging purposes)
- if (d_ptr->m_backgroundObj) {
- QMatrix4x4 modelMatrix;
- QMatrix4x4 MVPMatrix;
-
- modelMatrix.translate(0.0f, -d_ptr->m_yAdjustment, zComp);
- modelMatrix.scale(QVector3D(d_ptr->m_areaSize.width() / d_ptr->m_scaleFactor,
- 1.0f,
- d_ptr->m_areaSize.height() / d_ptr->m_scaleFactor));
- modelMatrix.rotate(-90.0f, 1.0f, 0.0f, 0.0f);
-
- MVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
-
- d_ptr->m_depthShader->setUniformValue(d_ptr->m_depthShader->MVP(), MVPMatrix);
-
- // 1st attribute buffer : vertices
- glEnableVertexAttribArray(d_ptr->m_depthShader->posAtt());
- glBindBuffer(GL_ARRAY_BUFFER, d_ptr->m_backgroundObj->vertexBuf());
- glVertexAttribPointer(d_ptr->m_depthShader->posAtt(), 3, GL_FLOAT, GL_FALSE, 0, (void *)0);
-
- // Index buffer
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, d_ptr->m_backgroundObj->elementBuf());
-
- // Draw the triangles
- glDrawElements(GL_TRIANGLES, d_ptr->m_backgroundObj->indexCount(), GL_UNSIGNED_SHORT,
- (void *)0);
-
- // Free buffers
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
-
- glDisableVertexAttribArray(d_ptr->m_depthShader->posAtt());
- }
-#endif
- // Draw bars to depth buffer
- for (int bar = 0; bar < d_ptr->m_data->d_ptr->row().size(); bar++) {
- QDataItem *item = d_ptr->m_data->d_ptr->getItem(bar);
- if (!item)
- continue;
-
- GLfloat barHeight = item->d_ptr->value() / d_ptr->m_heightNormalizer;
-
- QMatrix4x4 modelMatrix;
- QMatrix4x4 MVPMatrix;
-
- modelMatrix.translate(item->d_ptr->translation().x(),
- heightMultiplier * barHeight + heightScaler
- - d_ptr->m_yAdjustment,
- item->d_ptr->translation().z());
- modelMatrix.scale(QVector3D(widthMultiplier * barHeight + widthScaler,
- heightMultiplier * barHeight + heightScaler,
- depthMultiplier * barHeight + depthScaler));
-
- MVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
-
- d_ptr->m_depthShader->setUniformValue(d_ptr->m_depthShader->MVP(), MVPMatrix);
-
- // 1st attribute buffer : vertices
- glEnableVertexAttribArray(d_ptr->m_depthShader->posAtt());
- glBindBuffer(GL_ARRAY_BUFFER, d_ptr->m_barObj->vertexBuf());
- glVertexAttribPointer(d_ptr->m_depthShader->posAtt(), 3, GL_FLOAT, GL_FALSE, 0, (void *)0);
-
- // Index buffer
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, d_ptr->m_barObj->elementBuf());
-
- // Draw the triangles
- glDrawElements(GL_TRIANGLES, d_ptr->m_barObj->indexCount(), GL_UNSIGNED_SHORT, (void *)0);
-
- // Free buffers
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
-
- glDisableVertexAttribArray(d_ptr->m_depthShader->posAtt());
- }
-
- // Disable drawing to framebuffer (= enable drawing to screen)
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
-
- // Reset culling to normal
- glCullFace(GL_BACK);
-
- // Release depth shader
- d_ptr->m_depthShader->release();
-
- // Revert to original viewport
- glViewport(d_ptr->m_sceneViewPort.x(), d_ptr->m_sceneViewPort.y(),
- d_ptr->m_sceneViewPort.width(), d_ptr->m_sceneViewPort.height());
-
-#if 0 // Use this if you want to see what is being drawn to the framebuffer
- // You'll also have to comment out GL_COMPARE_R_TO_TEXTURE -line in texturehelper (if using it)
- d_ptr->m_labelShader->bind();
- glEnable(GL_TEXTURE_2D);
- QMatrix4x4 modelMatrix;
- QMatrix4x4 viewmatrix;
- viewmatrix.lookAt(QVector3D(0.0f, 0.0f, 2.5f + zComp),
- QVector3D(0.0f, 0.0f, zComp),
- QVector3D(0.0f, 1.0f, 0.0f));
- modelMatrix.translate(0.0, 0.0, zComp);
- QMatrix4x4 MVPMatrix = projectionMatrix * viewmatrix * modelMatrix;
- d_ptr->m_labelShader->setUniformValue(d_ptr->m_labelShader->MVP(), MVPMatrix);
- d_ptr->m_drawer->drawObject(d_ptr->m_labelShader, d_ptr->m_labelObj,
- d_ptr->m_depthTexture);
- glDisable(GL_TEXTURE_2D);
- d_ptr->m_labelShader->release();
-#endif
- }
-#endif
-
-#if 1
- // Skip selection mode drawing if we're zoomed or have no selection mode
- if (!d_ptr->m_zoomActivated && d_ptr->m_selectionMode > ModeNone) {
- // Bind selection shader
- d_ptr->m_selectionShader->bind();
-
- // Draw bars to selection buffer
- glBindFramebuffer(GL_FRAMEBUFFER, d_ptr->m_selectionFrameBuffer);
- glEnable(GL_DEPTH_TEST); // Needed, otherwise the depth render buffer is not used
- glClearColor(skipColor.x() / 255, skipColor.y() / 255, skipColor.z() / 255, 1.0f); // Set clear color to white (= skipColor)
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Needed for clearing the frame buffer
- glDisable(GL_DITHER); // disable dithering, it may affect colors if enabled
- GLint barIdxRed = 0;
- GLint barIdxGreen = 0;
- GLint barIdxBlue = 0;
- for (int bar = 0; bar < d_ptr->m_data->d_ptr->row().size(); bar++, barIdxRed++) {
- QDataItem *item = d_ptr->m_data->d_ptr->getItem(bar);
- if (!item)
- continue;
-
- GLfloat barHeight = item->d_ptr->value() / d_ptr->m_heightNormalizer;
-
- QMatrix4x4 modelMatrix;
- QMatrix4x4 MVPMatrix;
-
- modelMatrix.translate(item->d_ptr->translation().x(),
- heightMultiplier * barHeight + heightScaler
- - d_ptr->m_yAdjustment,
- item->d_ptr->translation().z());
- modelMatrix.scale(QVector3D(widthMultiplier * barHeight + widthScaler,
- heightMultiplier * barHeight + heightScaler,
- depthMultiplier * barHeight + depthScaler));
-
- MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
-
- if (barIdxRed > 0 && barIdxRed % 256 == 0) {
- barIdxRed = 0;
- barIdxGreen++;
- }
- if (barIdxGreen > 0 && barIdxGreen % 256 == 0) {
- barIdxGreen = 0;
- barIdxBlue++;
- }
- if (barIdxBlue > 255)
- qFatal("Too many objects");
-
- QVector3D barColor = QVector3D((GLfloat)barIdxRed / 255.0f,
- (GLfloat)barIdxGreen / 255.0f,
- (GLfloat)barIdxBlue / 255.0f);
-
- d_ptr->m_selectionShader->setUniformValue(d_ptr->m_selectionShader->MVP(),
- MVPMatrix);
- d_ptr->m_selectionShader->setUniformValue(d_ptr->m_selectionShader->color(),
- barColor);
-
- // 1st attribute buffer : vertices
- glEnableVertexAttribArray(d_ptr->m_selectionShader->posAtt());
- glBindBuffer(GL_ARRAY_BUFFER, d_ptr->m_barObj->vertexBuf());
- glVertexAttribPointer(d_ptr->m_selectionShader->posAtt(),
- 3, GL_FLOAT, GL_FALSE, 0, (void *)0);
-
- // Index buffer
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, d_ptr->m_barObj->elementBuf());
-
- // Draw the triangles
- glDrawElements(GL_TRIANGLES, d_ptr->m_barObj->indexCount(), GL_UNSIGNED_SHORT,
- (void *)0);
-
- // Free buffers
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
-
- glDisableVertexAttribArray(d_ptr->m_selectionShader->posAtt());
- }
- glEnable(GL_DITHER);
-
- // Read color under cursor
- if (Q3DMapsPrivate::MouseOnScene == d_ptr->m_mousePressed)
- selection = Utils::getSelection(d_ptr->m_mousePos, height());
-
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
-
- // Release selection shader
- d_ptr->m_selectionShader->release();
-
-#if 0 // Use this if you want to see what is being drawn to the framebuffer
- d_ptr->m_labelShader->bind();
- glDisable(GL_DEPTH_TEST);
- glEnable(GL_TEXTURE_2D);
- QMatrix4x4 modelMatrix;
- QMatrix4x4 viewmatrix;
- viewmatrix.lookAt(QVector3D(0.0f, 0.0f, 2.0f + zComp),
- QVector3D(0.0f, 0.0f, zComp),
- QVector3D(0.0f, 1.0f, 0.0f));
- modelMatrix.translate(0.0, 0.0, zComp);
- QMatrix4x4 MVPMatrix = projectionMatrix * viewmatrix * modelMatrix;
- d_ptr->m_labelShader->setUniformValue(d_ptr->m_labelShader->MVP(), MVPMatrix);
- d_ptr->m_drawer->drawObject(d_ptr->m_labelShader, d_ptr->m_labelObj,
- d_ptr->m_selectionTexture);
- glDisable(GL_TEXTURE_2D);
- d_ptr->m_labelShader->release();
-#endif
- }
-#if 1
- // Bind bar shader
- d_ptr->m_barShader->bind();
-
- // Enable texture
- glEnable(GL_TEXTURE_2D);
-
- // Draw bars
- // TODO: Handle zoom by camera transformations
- //if (!d_ptr->m_zoomActivated)
-
- bool barSelectionFound = false;
- for (int bar = 0; bar < d_ptr->m_data->d_ptr->row().size(); bar++) {
- QDataItem *item = d_ptr->m_data->d_ptr->getItem(bar);
- if (!item)
- continue;
-
- GLfloat barHeight = item->d_ptr->value() / d_ptr->m_heightNormalizer;
-
- QMatrix4x4 modelMatrix;
- QMatrix4x4 MVPMatrix;
- QMatrix4x4 depthMVPMatrix;
- QMatrix4x4 itModelMatrix;
-
- modelMatrix.translate(item->d_ptr->translation().x(),
- heightMultiplier * barHeight + heightScaler - d_ptr->m_yAdjustment,
- item->d_ptr->translation().z());
- modelMatrix.scale(QVector3D(widthMultiplier * barHeight + widthScaler,
- heightMultiplier * barHeight + heightScaler,
- depthMultiplier * barHeight + depthScaler));
- itModelMatrix.scale(QVector3D(widthMultiplier * barHeight + widthScaler,
- heightMultiplier * barHeight + heightScaler,
- depthMultiplier * barHeight + depthScaler));
-
-#ifdef SHOW_DEPTH_TEXTURE_SCENE
- MVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
-#else
- MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
-#endif
- depthMVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
-
- QVector3D baseColor = Utils::vectorFromColor(d_ptr->m_theme->m_baseColor);
- QVector3D heightColor = Utils::vectorFromColor(d_ptr->m_theme->m_heightColor)
- * barHeight;
-
- QVector3D barColor = baseColor + heightColor;
-
- GLfloat lightStrength = d_ptr->m_theme->m_lightStrength;
- if (d_ptr->m_selectionMode > ModeNone) {
- Q3DMapsPrivate::SelectionType selectionType = d_ptr->isSelected(bar, selection);
- switch (selectionType) {
- case Q3DMapsPrivate::SelectionBar: {
- barColor = Utils::vectorFromColor(d_ptr->m_theme->m_highlightBarColor);
- lightStrength = d_ptr->m_theme->m_highlightLightStrength;
- // Insert data to QDataItem. We have no ownership, don't delete the previous one
- if (!d_ptr->m_zoomActivated) {
- d_ptr->m_selectedBar = item;
- barSelectionFound = true;
- }
- break;
- }
- case Q3DMapsPrivate::SelectionNone: {
- // Current bar is not selected, nor on a row or column
- // do nothing
- break;
- }
- default: {
- // Unsupported selection mode
- // do nothing
- break;
- }
- }
- }
-
- if (barHeight != 0) {
- // Set shader bindings
- d_ptr->m_barShader->setUniformValue(d_ptr->m_barShader->lightP(), lightPos);
- d_ptr->m_barShader->setUniformValue(d_ptr->m_barShader->view(), viewMatrix);
- d_ptr->m_barShader->setUniformValue(d_ptr->m_barShader->model(), modelMatrix);
- d_ptr->m_barShader->setUniformValue(d_ptr->m_barShader->nModel(),
- itModelMatrix.inverted().transposed());
- d_ptr->m_barShader->setUniformValue(d_ptr->m_barShader->MVP(), MVPMatrix);
- d_ptr->m_barShader->setUniformValue(d_ptr->m_barShader->color(), barColor);
- d_ptr->m_barShader->setUniformValue(d_ptr->m_barShader->ambientS(),
- d_ptr->m_theme->m_ambientStrength);
-
-#if !defined(QT_OPENGL_ES_2)
- if (d_ptr->m_shadowQuality > ShadowNone) {
- // Set shadow shader bindings
- d_ptr->m_barShader->setUniformValue(d_ptr->m_barShader->shadowQ(),
- d_ptr->m_shadowQualityToShader);
- d_ptr->m_barShader->setUniformValue(d_ptr->m_barShader->depth(),
- depthMVPMatrix);
- d_ptr->m_barShader->setUniformValue(d_ptr->m_barShader->lightS(),
- lightStrength / 10.0f);
-
- // Draw the object
- d_ptr->m_drawer->drawObject(d_ptr->m_barShader, d_ptr->m_barObj,
- 0, d_ptr->m_depthTexture);
- } else
-#endif
- {
- // Set shadowless shader bindings
- d_ptr->m_barShader->setUniformValue(d_ptr->m_barShader->lightS(), lightStrength);
-
- // Draw the object
- d_ptr->m_drawer->drawObject(d_ptr->m_barShader, d_ptr->m_barObj);
- }
- }
- }
-
- // Release bar shader
- d_ptr->m_barShader->release();
-#if 1
- // Bind background shader
- d_ptr->m_backgroundShader->bind();
- if (d_ptr->m_bgrHasAlpha) {
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- }
-
- // Draw background
- if (d_ptr->m_backgroundObj) {
- QMatrix4x4 modelMatrix;
- QMatrix4x4 MVPMatrix;
- QMatrix4x4 depthMVPMatrix;
- QMatrix4x4 itModelMatrix;
-
- modelMatrix.translate(0.0f, -d_ptr->m_yAdjustment, zComp);
- modelMatrix.scale(QVector3D(d_ptr->m_areaSize.width() / d_ptr->m_scaleFactor,
- 1.0f,
- d_ptr->m_areaSize.height() / d_ptr->m_scaleFactor));
- modelMatrix.rotate(-90.0f, 1.0f, 0.0f, 0.0f);
- itModelMatrix.scale(QVector3D(d_ptr->m_areaSize.width() / d_ptr->m_scaleFactor,
- 1.0f,
- d_ptr->m_areaSize.height() / d_ptr->m_scaleFactor));
-
-#ifdef SHOW_DEPTH_TEXTURE_SCENE
- MVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
-#else
- MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
-#endif
- depthMVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
-
- // Set shader bindings
- d_ptr->m_backgroundShader->setUniformValue(d_ptr->m_backgroundShader->lightP(), lightPos);
- d_ptr->m_backgroundShader->setUniformValue(d_ptr->m_backgroundShader->view(), viewMatrix);
- d_ptr->m_backgroundShader->setUniformValue(d_ptr->m_backgroundShader->model(), modelMatrix);
- d_ptr->m_backgroundShader->setUniformValue(d_ptr->m_backgroundShader->nModel(),
- itModelMatrix.inverted().transposed());
- d_ptr->m_backgroundShader->setUniformValue(d_ptr->m_backgroundShader->MVP(), MVPMatrix);
- d_ptr->m_backgroundShader->setUniformValue(d_ptr->m_backgroundShader->ambientS(),
- d_ptr->m_theme->m_ambientStrength * 3.0f);
-
-#if !defined(QT_OPENGL_ES_2)
- if (d_ptr->m_shadowQuality > ShadowNone) {
- // Set shadow shader bindings
- d_ptr->m_backgroundShader->setUniformValue(d_ptr->m_backgroundShader->shadowQ(),
- d_ptr->m_shadowQualityToShader);
- d_ptr->m_backgroundShader->setUniformValue(d_ptr->m_backgroundShader->depth(),
- depthMVPMatrix);
- d_ptr->m_backgroundShader->setUniformValue(d_ptr->m_backgroundShader->lightS(),
- d_ptr->m_theme->m_lightStrength / 25.0f);
-
- // Draw the object
- d_ptr->m_drawer->drawObject(d_ptr->m_backgroundShader, d_ptr->m_backgroundObj,
- d_ptr->m_bgrTexture, d_ptr->m_depthTexture);
- } else
-#endif
- {
- // Set shadowless shader bindings
- d_ptr->m_backgroundShader->setUniformValue(d_ptr->m_backgroundShader->lightS(),
- d_ptr->m_theme->m_lightStrength);
-
- // Draw the object
- d_ptr->m_drawer->drawObject(d_ptr->m_backgroundShader, d_ptr->m_backgroundObj,
- d_ptr->m_bgrTexture);
- }
- }
-
- // Disable textures
- glDisable(GL_TEXTURE_2D);
- if (d_ptr->m_bgrHasAlpha)
- glDisable(GL_BLEND);
-
- // Release background shader
- d_ptr->m_backgroundShader->release();
-#endif
-
- // Handle zoom activation and label drawing
- if (!barSelectionFound) {
- // We have no ownership, don't delete. Just NULL the pointer.
- d_ptr->m_selectedBar = NULL;
- //if (d_ptr->m_zoomActivated && Q3DMapsPrivate::MouseOnOverview == d_ptr->m_mousePressed) {
- //d_ptr->m_sceneViewPort = QRect(0, 0, width(), height());
- //d_ptr->m_zoomActivated = false;
- //}
- } /*else if (d_ptr->m_selectionMode >= ModeZoomRow
- && Q3DMapsPrivate::MouseOnScene == d_ptr->m_mousePressed) {
- // Activate zoom mode
- d_ptr->m_zoomActivated = true;
- d_ptr->m_sceneViewPort = QRect(0, height() - height() / 5, width() / 5, height() / 5);
-
- // Create label textures
- for (int col = 0; col < d_ptr->m_zoomSelection->d_ptr->row().size(); col++) {
- QDataItem *item = d_ptr->m_zoomSelection->d_ptr->getItem(col);
- d_ptr->m_drawer->generateLabelTexture(item);
- }
- }*/ else {
- // Print value of selected bar
- static QDataItem *prevItem = d_ptr->m_selectedBar;
- d_ptr->m_labelShader->bind();
- glDisable(GL_DEPTH_TEST);
- glEnable(GL_TEXTURE_2D);
- if (d_ptr->m_labelTransparency > TransparencyNone) {
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- }
-#ifndef DISPLAY_FULL_DATA_ON_SELECTION
- // Draw just the value string of the selected bar
- if (prevItem != d_ptr->m_selectedBar || d_ptr->m_updateLabels) {
- d_ptr->m_drawer->generateLabelTexture(d_ptr->m_selectedBar);
- prevItem = d_ptr->m_selectedBar;
- }
-
- d_ptr->m_drawer->drawLabel(*d_ptr->m_selectedBar, d_ptr->m_selectedBar->d_ptr->label(),
- viewMatrix, projectionMatrix,
- QVector3D(0.0f, d_ptr->m_yAdjustment, zComp),
- QVector3D(0.0f, 0.0f, 0.0f), d_ptr->m_heightNormalizer,
- d_ptr->m_selectionMode, d_ptr->m_labelShader,
- d_ptr->m_labelObj, true);
-#else
- static bool firstSelection = true;
- // Draw the value string followed by row label and column label
- LabelItem labelItem = d_ptr->m_selectedBar->d_ptr->selectionLabel();
- if (firstSelection || prevItem != d_ptr->m_selectedBar || d_ptr->m_updateLabels) {
- QString labelText = d_ptr->m_selectedBar->d_ptr->valueStr();
- // if ((d_ptr->m_data->d_ptr->columnLabels().size()
- // > d_ptr->m_selectedBar->d_ptr->position().y())
- // && (d_ptr->m_data->d_ptr->rowLabels().size()
- // > d_ptr->m_selectedBar->d_ptr->position().x())) {
- // labelText.append(QStringLiteral(" ("));
- // labelText.append(d_ptr->m_data->d_ptr->rowLabels().at(
- // d_ptr->m_selectedBar->d_ptr->position().x()));
- // labelText.append(QStringLiteral(", "));
- // labelText.append(d_ptr->m_data->d_ptr->columnLabels().at(
- // d_ptr->m_selectedBar->d_ptr->position().y()));
- // labelText.append(QStringLiteral(")"));
- // //qDebug() << labelText;
- // }
- d_ptr->m_drawer->generateLabelItem(&labelItem, labelText);
- d_ptr->m_selectedBar->d_ptr->setSelectionLabel(labelItem);
- prevItem = d_ptr->m_selectedBar;
- firstSelection = false;
- }
-
- d_ptr->m_drawer->drawLabel(*d_ptr->m_selectedBar, labelItem, viewMatrix, projectionMatrix,
- QVector3D(0.0f, d_ptr->m_yAdjustment, zComp),
- QVector3D(0.0f, 0.0f, 0.0f), d_ptr->m_heightNormalizer,
- d_ptr->m_selectionMode, d_ptr->m_labelShader,
- d_ptr->m_labelObj, true, false);
-#endif
- glDisable(GL_TEXTURE_2D);
- if (d_ptr->m_labelTransparency > TransparencyNone)
- glDisable(GL_BLEND);
- glEnable(GL_DEPTH_TEST);
-
- // Release label shader
- d_ptr->m_labelShader->release();
-
- // Reset label update flag; they should have been updated when we get here
- d_ptr->m_updateLabels = false;
- }
-#if 0
- // TODO: Calculations done temporarily here. When optimizing, move to after data set addition? Keep drawing of the labels here.
- // Bind label shader
- d_ptr->m_labelShader->bind();
-
- glEnable(GL_TEXTURE_2D);
- if (d_ptr->m_labelTransparency > TransparencyNone) {
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- }
-
- // Calculate the positions for row and column labels and store them into QDataItems (and QDataRows?)
- for (int row = 0; row != d_ptr->m_sampleCount.second; row += 1) {
- // Go through all rows and get position of max+1 or min-1 column, depending on x flip
- // We need only positions for them, labels have already been generated at QDataSet. Just add LabelItems
- rowPos = (row + 1) * (d_ptr->m_barSpacing.height());
- barPos = 0;
- GLfloat rotLabelX = -90.0f;
- GLfloat rotLabelY = 0.0f;
- Qt::AlignmentFlag alignment = Qt::AlignRight;
- if (d_ptr->m_zFlipped)
- rotLabelY = 180.0f;
- if (d_ptr->m_xFlipped) {
- barPos = (d_ptr->m_sampleCount.first + 1) * (d_ptr->m_barSpacing.width());
- alignment = Qt::AlignLeft;
- }
- QVector3D labelPos = QVector3D((d_ptr->m_rowWidth - barPos) / d_ptr->m_scaleFactor,
- -d_ptr->m_yAdjustment + 0.005f, // raise a bit over background to avoid depth "glimmering"
- (d_ptr->m_columnDepth - rowPos) / d_ptr->m_scaleFactor
- + zComp);
-
- // TODO: Try it; draw the label here
-
- // Create a data item
- QDataItem *label = new QDataItem();
- label->d_ptr->setTranslation(labelPos);
- if (d_ptr->m_data->d_ptr->rowLabelItems().size() > row) {
- label->d_ptr->setLabel(d_ptr->m_data->d_ptr->rowLabelItems().at(
- d_ptr->m_data->d_ptr->rowLabelItems().size() - row - 1));
- }
-
- //qDebug() << "labelPos, row" << row + 1 << ":" << labelPos << d_ptr->m_dataSet->d_ptr->rowLabels().at(row);
-
- d_ptr->m_drawer->drawLabel(*label, label->d_ptr->label(), viewMatrix, projectionMatrix,
- QVector3D(0.0f, d_ptr->m_yAdjustment, zComp),
- QVector3D(rotLabelX, rotLabelY, 0.0f), d_ptr->m_heightNormalizer,
- d_ptr->m_selectionMode, d_ptr->m_labelShader,
- d_ptr->m_labelObj, true, true, LabelMid, alignment);
-
- delete label;
- }
- for (int bar = 0; bar != d_ptr->m_sampleCount.first; bar += 1) {
- // Go through all columns and get position of max+1 or min-1 row, depending on z flip
- // We need only positions for them, labels have already been generated at QDataSet. Just add LabelItems
- barPos = (bar + 1) * (d_ptr->m_barSpacing.width());
- rowPos = 0;
- GLfloat rotLabelX = -90.0f;
- GLfloat rotLabelY = 90.0f;
- Qt::AlignmentFlag alignment = Qt::AlignLeft;
- if (d_ptr->m_xFlipped)
- rotLabelY = -90.0f;
- if (d_ptr->m_zFlipped) {
- rowPos = (d_ptr->m_sampleCount.second + 1) * (d_ptr->m_barSpacing.height());
- alignment = Qt::AlignRight;
- }
- QVector3D labelPos = QVector3D((d_ptr->m_rowWidth - barPos) / d_ptr->m_scaleFactor,
- -d_ptr->m_yAdjustment + 0.005f, // raise a bit over background to avoid depth "glimmering"
- (d_ptr->m_columnDepth - rowPos) / d_ptr->m_scaleFactor
- + zComp);
-
- // TODO: Try it; draw the label here
-
- // Create a data item
- QDataItem *label = new QDataItem();
- label->d_ptr->setTranslation(labelPos);
- if (d_ptr->m_data->d_ptr->columnLabelItems().size() > bar) {
- label->d_ptr->setLabel(d_ptr->m_data->d_ptr->columnLabelItems().at(
- d_ptr->m_data->d_ptr->columnLabelItems().size()
- - bar - 1));
- }
-
- //qDebug() << "labelPos, col" << bar + 1 << ":" << labelPos << d_ptr->m_dataSet->d_ptr->columnLabels().at(bar);
-
- d_ptr->m_drawer->drawLabel(*label, label->d_ptr->label(), viewMatrix, projectionMatrix,
- QVector3D(0.0f, d_ptr->m_yAdjustment, zComp),
- QVector3D(rotLabelX, rotLabelY, 0.0f), d_ptr->m_heightNormalizer,
- d_ptr->m_selectionMode, d_ptr->m_labelShader,
- d_ptr->m_labelObj, true, true, LabelMid, alignment);
-
- delete label;
- }
- glDisable(GL_TEXTURE_2D);
- if (d_ptr->m_labelTransparency > TransparencyNone)
- glDisable(GL_BLEND);
-
- // Release label shader
- d_ptr->m_labelShader->release();
-#endif
-#endif
-#endif
+ d_ptr->m_shared->render();
}
#if defined(Q_OS_ANDROID)
@@ -960,11 +71,7 @@ void Q3DMaps::drawScene()
*/
void Q3DMaps::mouseDoubleClickEvent(QMouseEvent *event)
{
- if (!d_ptr->m_zoomActivated) {
- d_ptr->m_mousePressed = Q3DMapsPrivate::MouseOnScene;
- // update mouse positions to prevent jumping when releasing or repressing a button
- d_ptr->m_mousePos = event->pos();
- }
+ d_ptr->m_shared->mouseDoubleClickEvent(event);
}
/*!
@@ -972,30 +79,7 @@ void Q3DMaps::mouseDoubleClickEvent(QMouseEvent *event)
*/
void Q3DMaps::touchEvent(QTouchEvent *event)
{
- static int prevDistance = 0;
-
- QList<QTouchEvent::TouchPoint> points;
- points = event->touchPoints();
-
- if (points.count() == 2) {
- d_ptr->m_mousePressed = Q3DMapsPrivate::MouseOnPinch;
-
- QPointF distance = points.at(0).pos() - points.at(1).pos();
- int newDistance = distance.manhattanLength();
- int zoomRate = 1;
- if (d_ptr->m_zoomLevel > 100)
- zoomRate = 5;
- if (newDistance > prevDistance)
- d_ptr->m_zoomLevel += zoomRate;
- else
- d_ptr->m_zoomLevel -= zoomRate;
- if (d_ptr->m_zoomLevel > 500)
- d_ptr->m_zoomLevel = 500;
- else if (d_ptr->m_zoomLevel < 10)
- d_ptr->m_zoomLevel = 10;
- prevDistance = newDistance;
- //qDebug() << "distance" << distance.manhattanLength();
- }
+ d_ptr->m_shared->touchEvent(event);
}
#endif
@@ -1004,40 +88,7 @@ void Q3DMaps::touchEvent(QTouchEvent *event)
*/
void Q3DMaps::mousePressEvent(QMouseEvent *event)
{
- if (Qt::LeftButton == event->button()) {
- if (d_ptr->m_zoomActivated) {
- //qDebug() << event->pos().x() << event->pos().y() << d_ptr->m_sceneViewPort << d_ptr->m_zoomViewPort;
- if (event->pos().x() <= d_ptr->m_sceneViewPort.width()
- && event->pos().y() <= d_ptr->m_sceneViewPort.height()) {
- d_ptr->m_mousePressed = Q3DMapsPrivate::MouseOnOverview;
- //qDebug() << "Mouse pressed on overview";
- } else {
- d_ptr->m_mousePressed = Q3DMapsPrivate::MouseOnZoom;
- //qDebug() << "Mouse pressed on zoom";
- }
- } else {
-#if !defined(Q_OS_ANDROID)
- d_ptr->m_mousePressed = Q3DMapsPrivate::MouseOnScene;
-#else
- d_ptr->m_mousePressed = Q3DMapsPrivate::MouseRotating;
-#endif
- // update mouse positions to prevent jumping when releasing or repressing a button
- d_ptr->m_mousePos = event->pos();
- //qDebug() << "Mouse pressed on scene";
- }
- } else if (Qt::MiddleButton == event->button()) {
- // reset rotations
- d_ptr->m_mousePos = QPoint(0, 0);
- } else if (Qt::RightButton == event->button()) {
-#if !defined(Q_OS_ANDROID)
- d_ptr->m_mousePressed = Q3DMapsPrivate::MouseRotating;
-#else
- d_ptr->m_mousePressed = Q3DMapsPrivate::MouseOnScene;
-#endif
- // update mouse positions to prevent jumping when releasing or repressing a button
- d_ptr->m_mousePos = event->pos();
- }
- CameraHelper::updateMousePos(d_ptr->m_mousePos);
+ d_ptr->m_shared->mousePressEvent(event, event->pos());
}
/*!
@@ -1045,13 +96,7 @@ void Q3DMaps::mousePressEvent(QMouseEvent *event)
*/
void Q3DMaps::mouseReleaseEvent(QMouseEvent *event)
{
- //qDebug() << "mouse button released" << event->button();
- if (Q3DMapsPrivate::MouseRotating == d_ptr->m_mousePressed) {
- // update mouse positions to prevent jumping when releasing or repressing a button
- d_ptr->m_mousePos = event->pos();
- CameraHelper::updateMousePos(event->pos());
- }
- d_ptr->m_mousePressed = Q3DMapsPrivate::MouseNone;
+ d_ptr->m_shared->mouseReleaseEvent(event, event->pos());
}
/*!
@@ -1059,25 +104,7 @@ void Q3DMaps::mouseReleaseEvent(QMouseEvent *event)
*/
void Q3DMaps::mouseMoveEvent(QMouseEvent *event)
{
- if (Q3DMapsPrivate::MouseRotating == d_ptr->m_mousePressed) {
- //qDebug() << "mouse moved while pressed" << event->pos();
- d_ptr->m_mousePos = event->pos();
- }
-#if 0
- // TODO: Testi - laske kursorin sijainti scenessä
- QPointF mouse3D((2.0f * event->pos().x() - width()) / height(),
- 1.0f - (2.0f * event->pos().y()) / height());
- //qDebug() << "mouse position in scene" << mouse3D;
-
- // TODO: Testi laske focal point
- GLfloat focalPoint = tan(45.0f / 2.0f);
-
- // TODO: Testi - laske viewmatriisin kerroin
- QVector3D worldRay = QVector3D(0.0f, 0.0f, 0.0f)
- - QVector3D(mouse3D.x(), mouse3D.y(), -focalPoint);
- //qDebug() << "worldRay" << worldRay;
- // multiply viewmatrix with this to get something?
-#endif
+ d_ptr->m_shared->mouseMoveEvent(event, event->pos());
}
/*!
@@ -1085,16 +112,7 @@ void Q3DMaps::mouseMoveEvent(QMouseEvent *event)
*/
void Q3DMaps::wheelEvent(QWheelEvent *event)
{
- if (d_ptr->m_zoomLevel > 100)
- d_ptr->m_zoomLevel += event->angleDelta().y() / 12;
- else if (d_ptr->m_zoomLevel > 50)
- d_ptr->m_zoomLevel += event->angleDelta().y() / 60;
- else
- d_ptr->m_zoomLevel += event->angleDelta().y() / 120;
- if (d_ptr->m_zoomLevel > 500)
- d_ptr->m_zoomLevel = 500;
- else if (d_ptr->m_zoomLevel < 10)
- d_ptr->m_zoomLevel = 10;
+ d_ptr->m_shared->wheelEvent(event);
}
/*!
@@ -1103,195 +121,78 @@ void Q3DMaps::wheelEvent(QWheelEvent *event)
void Q3DMaps::resizeEvent(QResizeEvent *event)
{
Q_UNUSED(event);
+ d_ptr->m_shared->setWidth(width());
+ d_ptr->m_shared->setHeight(height());
+ d_ptr->m_shared->resizeNotify();
+}
- // Set view port
- if (d_ptr->m_zoomActivated)
- d_ptr->m_sceneViewPort = QRect(0, height() - height() / 5, width() / 5, height() / 5);
- else
- d_ptr->m_sceneViewPort = QRect(0, 0, width(), height());
- d_ptr->m_zoomViewPort = QRect(0, 0, width(), height());
-
- // Calculate zoom level based on aspect ratio
- GLfloat div;
- GLfloat zoomAdjustment;
- div = qMin(width(), height());
- zoomAdjustment = defaultRatio * ((width() / div) / (height() / div));
- //qDebug() << "zoom adjustment" << zoomAdjustment;
- d_ptr->m_zoomAdjustment = qMin(zoomAdjustment, 1.0f); // clamp to 1.0f
-
- // Re-init selection buffer
- d_ptr->initSelectionBuffer();
+// TODO: Document
+// Size
+void Q3DMaps::setWidth(const int width)
+{
+ d_ptr->m_shared->setWidth(width);
+ QWindow::setWidth(width);
+}
-#if !defined(QT_OPENGL_ES_2)
- // Re-init depth buffer
- if (d_ptr->m_isInitialized && d_ptr->m_shadowQuality > ShadowNone)
- d_ptr->initDepthBuffer();
-#endif
+void Q3DMaps::setHeight(const int height)
+{
+ d_ptr->m_shared->setHeight(height);
+ QWindow::setHeight(height);
}
void Q3DMaps::setBarSpecs(const QVector3D &thickness, AdjustmentDirection direction)
{
- d_ptr->m_barThickness = thickness;
- d_ptr->m_adjustDirection = direction;
+ d_ptr->m_shared->setBarSpecs(thickness, direction);
}
-void Q3DMaps::setBarType(BarStyle style, bool smooth)
+void Q3DMaps::setBarType(QDataVis::MeshStyle style, bool smooth)
{
- if (style == Bars) {
- if (smooth)
- d_ptr->m_objFile = QStringLiteral(":/defaultMeshes/barSmooth");
- else
- d_ptr->m_objFile = QStringLiteral(":/defaultMeshes/bar");
- } else if (style == Pyramids) {
- if (smooth)
- d_ptr->m_objFile = QStringLiteral(":/defaultMeshes/pyramidSmooth");
- else
- d_ptr->m_objFile = QStringLiteral(":/defaultMeshes/pyramid");
- } else if (style == Cones) {
- if (smooth)
- d_ptr->m_objFile = QStringLiteral(":/defaultMeshes/coneSmooth");
- else
- d_ptr->m_objFile = QStringLiteral(":/defaultMeshes/cone");
- } else if (style == Cylinders) {
- if (smooth)
- d_ptr->m_objFile = QStringLiteral(":/defaultMeshes/cylinderSmooth");
- else
- d_ptr->m_objFile = QStringLiteral(":/defaultMeshes/cylinder");
- } else if (style == BevelBars) {
- if (smooth)
- d_ptr->m_objFile = QStringLiteral(":/defaultMeshes/bevelbarSmooth");
- else
- d_ptr->m_objFile = QStringLiteral(":/defaultMeshes/bevelbar");
- } else if (style == Spheres) {
- if (smooth)
- d_ptr->m_objFile = QStringLiteral(":/defaultMeshes/sphereSmooth");
- else
- d_ptr->m_objFile = QStringLiteral(":/defaultMeshes/sphere");
- }
- // Reload mesh data
- if (d_ptr->m_isInitialized)
- d_ptr->loadBarMesh();
+ d_ptr->m_shared->setBarType(style, smooth);
}
void Q3DMaps::setMeshFileName(const QString &objFileName)
{
- d_ptr->m_objFile = objFileName;
+ d_ptr->m_shared->setMeshFileName(objFileName);
}
-void Q3DMaps::setCameraPreset(CameraPreset preset)
+void Q3DMaps::setCameraPreset(QDataVis::CameraPreset preset)
{
- CameraHelper::setCameraPreset(preset);
+ d_ptr->m_shared->setCameraPreset(preset);
}
void Q3DMaps::setCameraPosition(GLfloat horizontal, GLfloat vertical, GLint distance)
{
- d_ptr->m_horizontalRotation = qBound(-180.0f, horizontal, 180.0f);
- d_ptr->m_verticalRotation = qBound(0.0f, vertical, 90.0f);
- d_ptr->m_zoomLevel = qBound(10, distance, 500);
- CameraHelper::setCameraRotation(QPointF(d_ptr->m_horizontalRotation,
- d_ptr->m_verticalRotation));
- //qDebug() << "camera rotation set to" << d_ptr->m_horizontalRotation << d_ptr->m_verticalRotation;
+ d_ptr->m_shared->setCameraPosition(horizontal, vertical, distance);
}
-void Q3DMaps::setTheme(ColorTheme theme)
+void Q3DMaps::setTheme(QDataVis::ColorTheme theme)
{
- d_ptr->m_theme->useTheme(theme);
- d_ptr->m_drawer->setTheme(*d_ptr->m_theme);
-#if !defined(QT_OPENGL_ES_2)
- if (d_ptr->m_shadowQuality > ShadowNone) {
- // Re-init shaders
- if (!d_ptr->m_theme->m_uniformColor) {
- d_ptr->initShaders(QStringLiteral(":/shaders/vertexShadow"),
- QStringLiteral(":/shaders/fragmentShadowNoTexColorOnY"));
- } else {
- d_ptr->initShaders(QStringLiteral(":/shaders/vertexShadow"),
- QStringLiteral(":/shaders/fragmentShadowNoTex"));
- }
- } else {
- // Re-init shaders
- if (!d_ptr->m_theme->m_uniformColor) {
- d_ptr->initShaders(QStringLiteral(":/shaders/vertex"),
- QStringLiteral(":/shaders/fragmentColorOnY"));
- } else {
- d_ptr->initShaders(QStringLiteral(":/shaders/vertex"),
- QStringLiteral(":/shaders/fragment"));
- }
- }
-#else
- if (!d_ptr->m_theme->m_uniformColor) {
- d_ptr->initShaders(QStringLiteral(":/shaders/vertexES2"),
- QStringLiteral(":/shaders/fragmentColorOnYES2"));
- } else {
- d_ptr->initShaders(QStringLiteral(":/shaders/vertexES2"),
- QStringLiteral(":/shaders/fragmentES2"));
- }
-#endif
- d_ptr->m_updateLabels = true;
+ d_ptr->m_shared->setTheme(theme);
}
void Q3DMaps::setBarColor(QColor baseColor, QColor heightColor, bool uniform)
{
- d_ptr->m_theme->m_baseColor = baseColor;
- d_ptr->m_theme->m_heightColor = heightColor;
- if (d_ptr->m_theme->m_uniformColor != uniform) {
-#if !defined(QT_OPENGL_ES_2)
- if (d_ptr->m_shadowQuality > ShadowNone) {
- // Re-init shaders
- if (!d_ptr->m_theme->m_uniformColor) {
- d_ptr->initShaders(QStringLiteral(":/shaders/vertexShadow"),
- QStringLiteral(":/shaders/fragmentShadowNoTexColorOnY"));
- } else {
- d_ptr->initShaders(QStringLiteral(":/shaders/vertexShadow"),
- QStringLiteral(":/shaders/fragmentShadowNoTex"));
- }
- } else {
- // Re-init shaders
- if (!d_ptr->m_theme->m_uniformColor) {
- d_ptr->initShaders(QStringLiteral(":/shaders/vertex"),
- QStringLiteral(":/shaders/fragmentColorOnY"));
- } else {
- d_ptr->initShaders(QStringLiteral(":/shaders/vertex"),
- QStringLiteral(":/shaders/fragment"));
- }
- }
-#else
- if (!d_ptr->m_theme->m_uniformColor) {
- d_ptr->initShaders(QStringLiteral(":/shaders/vertexES2"),
- QStringLiteral(":/shaders/fragmentColorOnYES2"));
- } else {
- d_ptr->initShaders(QStringLiteral(":/shaders/vertexES2"),
- QStringLiteral(":/shaders/fragmentES2"));
- }
-#endif
- }
- d_ptr->m_theme->m_uniformColor = uniform;
+ d_ptr->m_shared->setBarColor(baseColor, heightColor, uniform);
}
void Q3DMaps::setAreaSpecs(const QRect &areaRect, const QImage &image)
{
- d_ptr->calculateSceneScalingFactors(areaRect);
- setImage(image);
+ d_ptr->m_shared->setAreaSpecs(areaRect, image);
}
void Q3DMaps::setImage(const QImage &image)
{
- d_ptr->m_bgrHasAlpha = image.hasAlphaChannel();
- if (d_ptr->m_bgrTexture)
- glDeleteTextures(1, &d_ptr->m_bgrTexture);
- d_ptr->m_bgrTexture = d_ptr->m_textureHelper->create2DTexture(image, true, true);
+ d_ptr->m_shared->setImage(image);
}
-void Q3DMaps::setSelectionMode(SelectionMode mode)
+void Q3DMaps::setSelectionMode(QDataVis::SelectionMode mode)
{
- d_ptr->m_selectionMode = mode;
- // Disable zoom if mode changes
- //d_ptr->m_zoomActivated = false;
- //d_ptr->m_sceneViewPort = QRect(0, 0, width(), height());
+ d_ptr->m_shared->setSelectionMode(mode);
}
-SelectionMode Q3DMaps::selectionMode()
+QDataVis::SelectionMode Q3DMaps::selectionMode() const
{
- return d_ptr->m_selectionMode;
+ return d_ptr->m_shared->selectionMode();
}
void Q3DMaps::setWindowTitle(const QString &title)
@@ -1299,478 +200,71 @@ void Q3DMaps::setWindowTitle(const QString &title)
setTitle(title);
}
-QString Q3DMaps::windowTitle()
+QString Q3DMaps::windowTitle() const
{
return title();
}
void Q3DMaps::setFontSize(float fontsize)
{
- d_ptr->m_font.setPointSizeF(fontsize);
- d_ptr->m_drawer->setFont(d_ptr->m_font);
- d_ptr->m_updateLabels = true;
+ d_ptr->m_shared->setFontSize(fontsize);
}
-float Q3DMaps::fontSize()
+float Q3DMaps::fontSize() const
{
- return d_ptr->m_font.pointSizeF();
+ return d_ptr->m_shared->fontSize();
}
void Q3DMaps::setFont(const QFont &font)
{
- d_ptr->m_font = font;
- d_ptr->m_drawer->setFont(font);
- d_ptr->m_updateLabels = true;
-}
-
-QFont Q3DMaps::font()
-{
- return d_ptr->m_font;
-}
-
-void Q3DMaps::setLabelTransparency(LabelTransparency transparency)
-{
- d_ptr->m_labelTransparency = transparency;
- d_ptr->m_drawer->setTransparency(transparency);
- d_ptr->m_updateLabels = true;
-}
-
-LabelTransparency Q3DMaps::labelTransparency()
-{
- return d_ptr->m_labelTransparency;
+ d_ptr->m_shared->setFont(font);
}
-void Q3DMaps::setShadowQuality(ShadowQuality quality)
+QFont Q3DMaps::font() const
{
- d_ptr->m_shadowQuality = quality;
- switch (quality) {
- case ShadowLow:
- //qDebug() << "ShadowLow";
- d_ptr->m_shadowQualityToShader = 33.3f;
- break;
- case ShadowMedium:
- //qDebug() << "ShadowMedium";
- d_ptr->m_shadowQualityToShader = 100.0f;
- break;
- case ShadowHigh:
- //qDebug() << "ShadowHigh";
- d_ptr->m_shadowQualityToShader = 200.0f;
- break;
- default:
- d_ptr->m_shadowQualityToShader = 0.0f;
- break;
- }
- if (d_ptr->m_isInitialized) {
-#if !defined(QT_OPENGL_ES_2)
- if (d_ptr->m_shadowQuality > ShadowNone) {
- // Re-init depth buffer
- d_ptr->initDepthBuffer();
- // Re-init shaders
- if (!d_ptr->m_theme->m_uniformColor) {
- d_ptr->initShaders(QStringLiteral(":/shaders/vertexShadow"),
- QStringLiteral(":/shaders/fragmentShadowNoTexColorOnY"));
- } else {
- d_ptr->initShaders(QStringLiteral(":/shaders/vertexShadow"),
- QStringLiteral(":/shaders/fragmentShadowNoTex"));
- }
- d_ptr->initBackgroundShaders(QStringLiteral(":/shaders/vertexShadow"),
- QStringLiteral(":/shaders/fragmentShadow"));
- } else {
- // Re-init shaders
- if (!d_ptr->m_theme->m_uniformColor) {
- d_ptr->initShaders(QStringLiteral(":/shaders/vertex"),
- QStringLiteral(":/shaders/fragmentColorOnY"));
- } else {
- d_ptr->initShaders(QStringLiteral(":/shaders/vertex"),
- QStringLiteral(":/shaders/fragment"));
- }
- d_ptr->initBackgroundShaders(QStringLiteral(":/shaders/vertexTexture"),
- QStringLiteral(":/shaders/fragmentTexture"));
- }
-#else
- if (!d_ptr->m_theme->m_uniformColor) {
- d_ptr->initShaders(QStringLiteral(":/shaders/vertexES2"),
- QStringLiteral(":/shaders/fragmentColorOnYES2"));
- } else {
- d_ptr->initShaders(QStringLiteral(":/shaders/vertexES2"),
- QStringLiteral(":/shaders/fragmentES2"));
- }
- d_ptr->initBackgroundShaders(QStringLiteral(":/shaders/vertexTexture"), // Same vertex shader ok for ES2
- QStringLiteral(":/shaders/fragmentTextureES2"));
-#endif
- }
+ return d_ptr->m_shared->font();
}
-ShadowQuality Q3DMaps::shadowQuality()
+void Q3DMaps::setLabelTransparency(QDataVis::LabelTransparency transparency)
{
- return d_ptr->m_shadowQuality;
+ d_ptr->m_shared->setLabelTransparency(transparency);
}
-bool Q3DMaps::addDataItem(QDataItem* dataItem)
+QDataVis::LabelTransparency Q3DMaps::labelTransparency() const
{
- // Check validity
- if (!d_ptr->isValid(*dataItem))
- return false;
- // Convert position to translation
- d_ptr->calculateTranslation(dataItem);
- // Add item
- d_ptr->m_data->addItem(dataItem);
- // Get the limits
- QPair<GLfloat, GLfloat> limits = d_ptr->m_data->d_ptr->limitValues();
- d_ptr->m_heightNormalizer = (GLfloat)qMax(qFabs(limits.second), qFabs(limits.first));
- d_ptr->calculateHeightAdjustment(limits);
- return true;
+ return d_ptr->m_shared->labelTransparency();
}
-bool Q3DMaps::addData(const QVector<QDataItem*> &data)
+QDataVis::ShadowQuality Q3DMaps::setShadowQuality(QDataVis::ShadowQuality quality)
{
- // Convert to QDataRow
- for (int i = 0; i < data.size(); i++) {
- QDataItem *item = data.at(i);
- // Check validity
- if (!d_ptr->isValid(*item)) {
- return false;
- } else {
- // Convert position to translation
- d_ptr->calculateTranslation(item);
- // Add item
- d_ptr->m_data->addItem(item);
- }
- }
- // Get the limits
- QPair<GLfloat, GLfloat> limits = d_ptr->m_data->d_ptr->limitValues();
- d_ptr->m_heightNormalizer = (GLfloat)qMax(qFabs(limits.second), qFabs(limits.first));
- d_ptr->calculateHeightAdjustment(limits);
- return true;
+ return d_ptr->m_shared->setShadowQuality(quality);
}
-bool Q3DMaps::addData(const QDataRow &dataRow)
+QDataVis::ShadowQuality Q3DMaps::shadowQuality() const
{
- for (int itemIdx = 0; itemIdx < dataRow.d_ptr->row().size(); itemIdx++) {
- QDataItem *item = dataRow.d_ptr->getItem(itemIdx);
- // Check validity
- if (!d_ptr->isValid(*item)) {
- return false;
- } else {
- // Convert position to translation
- d_ptr->calculateTranslation(item);
- // Add item
- d_ptr->m_data->addItem(item);
- }
- }
- // Get the limits
- QPair<GLfloat, GLfloat> limits = d_ptr->m_data->d_ptr->limitValues();
- d_ptr->m_heightNormalizer = (GLfloat)qMax(qFabs(limits.second), qFabs(limits.first));
- d_ptr->calculateHeightAdjustment(limits);
- return true;
+ return d_ptr->m_shared->shadowQuality();
}
-bool Q3DMaps::setData(const QVector<QDataItem*> &dataRow)
+void Q3DMaps::setDataProxy(QMapDataProxy *proxy)
{
- // Delete previous data
- delete d_ptr->m_data;
- // Convert to QDataRow
- d_ptr->m_data = new QDataRow();
- for (int i = 0; i < dataRow.size(); i++) {
- QDataItem *item = dataRow.at(i);
- // Check validity
- if (!d_ptr->isValid(*item)) {
- return false;
- } else {
- // Convert position to translation
- d_ptr->calculateTranslation(item);
- // Add item
- d_ptr->m_data->addItem(item);
- }
- }
- // Get the limits
- QPair<GLfloat, GLfloat> limits = d_ptr->m_data->d_ptr->limitValues();
- d_ptr->m_heightNormalizer = (GLfloat)qMax(qFabs(limits.second), qFabs(limits.first));
- d_ptr->calculateHeightAdjustment(limits);
- return true;
+ d_ptr->m_shared->setDataProxy(proxy);
}
-bool Q3DMaps::setData(QDataRow *dataRow)
+QMapDataProxy *Q3DMaps::dataProxy()
{
- // Check validity
- for (int i = 0; i < dataRow->d_ptr->row().size(); i++) {
- if (!d_ptr->isValid(*dataRow->d_ptr->row().at(i)))
- return false;
- else
- d_ptr->calculateTranslation(dataRow->d_ptr->row()[i]);
- }
- // Delete previous data
- delete d_ptr->m_data;
- // Set give data as new data
- d_ptr->m_data = dataRow;
- // Get the limits
- QPair<GLfloat, GLfloat> limits = d_ptr->m_data->d_ptr->limitValues();
- d_ptr->m_heightNormalizer = (GLfloat)qMax(qFabs(limits.second), qFabs(limits.first));
- d_ptr->calculateHeightAdjustment(limits);
- return true;
+ return d_ptr->m_shared->dataProxy();
}
-Q3DMapsPrivate::Q3DMapsPrivate(Q3DMaps *q)
+Q3DMapsPrivate::Q3DMapsPrivate(Q3DMaps *q, const QRect &rect)
: q_ptr(q),
- m_paintDevice(0),
- m_barShader(0),
- m_depthShader(0),
- m_selectionShader(0),
- m_backgroundShader(0),
- m_labelShader(0),
- m_barObj(0),
- m_backgroundObj(0),
- m_gridLineObj(0),
- m_labelObj(0),
- m_objFile(QStringLiteral(":/defaultMeshes/bar")),
- m_mousePressed(MouseNone),
- m_mousePos(QPoint(0, 0)),
- m_zoomLevel(100),
- m_zoomAdjustment(1.0f),
- m_horizontalRotation(0.0f),
- m_verticalRotation(45.0f),
- m_barThickness(QVector3D(1.0f, 0.0f, 1.0f)),
- m_heightNormalizer(0.0f),
- m_yAdjustment(0.0f),
- m_scaleFactor(1.0f),
- m_theme(new Theme()),
- m_isInitialized(false),
- m_selectionMode(ModeBar),
- m_selectedBar(0),
- m_data(new QDataRow()),
- m_axisLabelX(QStringLiteral("X")),
- m_axisLabelZ(QStringLiteral("Z")),
- m_axisLabelY(QStringLiteral("Y")),
- m_sceneViewPort(0, 0, q->width(), q->height()),
- m_zoomViewPort(0, 0, q->width(), q->height()),
- m_zoomActivated(false),
- m_textureHelper(new TextureHelper()),
- m_labelTransparency(TransparencyFromTheme),
- m_font(QFont(QStringLiteral("Arial"))),
- m_drawer(new Drawer(*m_theme, m_font, m_labelTransparency)),
- m_areaSize(QSizeF(1.0f, 1.0f)),
- m_bgrTexture(0),
- m_depthTexture(0),
- m_selectionTexture(0),
- m_depthFrameBuffer(0),
- m_selectionFrameBuffer(0),
- m_selectionDepthBuffer(0),
- m_updateLabels(true),
- m_shadowQuality(ShadowLow),
- m_shadowQualityToShader(33.3f),
- m_bgrHasAlpha(false)
+ m_shared(new Maps3DController(rect))
{
- //m_data->d_ptr->setDrawer(m_drawer);
- //QObject::connect(m_drawer, &Drawer::drawerChanged, this, &Q3DMapsPrivate::updateTextures);
}
Q3DMapsPrivate::~Q3DMapsPrivate()
{
- m_textureHelper->glDeleteFramebuffers(1, &m_depthFrameBuffer);
- m_textureHelper->glDeleteFramebuffers(1, &m_selectionFrameBuffer);
- m_textureHelper->glDeleteRenderbuffers(1, &m_selectionDepthBuffer);
- m_textureHelper->deleteTexture(&m_selectionTexture);
- m_textureHelper->deleteTexture(&m_bgrTexture);
- delete m_data;
- delete m_barShader;
- delete m_selectionShader;
- delete m_backgroundShader;
- delete m_barObj;
- delete m_backgroundObj;
- delete m_gridLineObj;
- delete m_textureHelper;
- delete m_drawer;
-}
-
-void Q3DMapsPrivate::loadBarMesh()
-{
- if (m_barObj)
- delete m_barObj;
- m_barObj = new ObjectHelper(m_objFile);
- m_barObj->load();
-}
-
-void Q3DMapsPrivate::loadBackgroundMesh()
-{
- if (m_backgroundObj)
- delete m_backgroundObj;
- m_backgroundObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/label"));
- m_backgroundObj->load();
-}
-
-void Q3DMapsPrivate::loadGridLineMesh()
-{
- if (m_gridLineObj)
- delete m_gridLineObj;
- m_gridLineObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/bar"));
- m_gridLineObj->load();
-}
-
-void Q3DMapsPrivate::loadLabelMesh()
-{
- if (m_labelObj)
- delete m_labelObj;
- m_labelObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/label"));
- m_labelObj->load();
-}
-
-void Q3DMapsPrivate::initShaders(const QString &vertexShader, const QString &fragmentShader)
-{
- if (m_barShader)
- delete m_barShader;
- m_barShader = new ShaderHelper(q_ptr, vertexShader, fragmentShader);
- m_barShader->initialize();
-}
-
-void Q3DMapsPrivate::initSelectionShader()
-{
- if (m_selectionShader)
- delete m_selectionShader;
- m_selectionShader = new ShaderHelper(q_ptr, QStringLiteral(":/shaders/vertexSelection"),
- QStringLiteral(":/shaders/fragmentSelection"));
- m_selectionShader->initialize();
-}
-
-void Q3DMapsPrivate::initSelectionBuffer()
-{
- if (m_selectionTexture) {
-
- m_textureHelper->glDeleteFramebuffers(1, &m_selectionFrameBuffer);
- m_textureHelper->glDeleteRenderbuffers(1, &m_selectionDepthBuffer);
- m_textureHelper->deleteTexture(&m_selectionTexture);
- }
- m_selectionTexture = m_textureHelper->createSelectionTexture(q_ptr->size(),
- m_selectionFrameBuffer,
- m_selectionDepthBuffer);
-}
-
-#if !defined(QT_OPENGL_ES_2)
-void Q3DMapsPrivate::initDepthShader()
-{
- if (m_depthShader)
- delete m_depthShader;
- m_depthShader = new ShaderHelper(q_ptr, QStringLiteral(":/shaders/vertexDepth"),
- QStringLiteral(":/shaders/fragmentDepth"));
- m_depthShader->initialize();
-}
-
-void Q3DMapsPrivate::initDepthBuffer()
-{
- if (m_depthTexture) {
- m_textureHelper->glDeleteFramebuffers(1, &m_depthFrameBuffer);
- m_textureHelper->deleteTexture(&m_depthTexture);
- }
- m_depthTexture = m_textureHelper->createDepthTexture(q_ptr->size(), m_depthFrameBuffer,
- m_shadowQuality);
-}
-#endif
-
-void Q3DMapsPrivate::initBackgroundShaders(const QString &vertexShader,
- const QString &fragmentShader)
-{
- if (m_backgroundShader)
- delete m_backgroundShader;
- m_backgroundShader = new ShaderHelper(q_ptr, vertexShader, fragmentShader);
- m_backgroundShader->initialize();
-}
-
-void Q3DMapsPrivate::initLabelShaders(const QString &vertexShader, const QString &fragmentShader)
-{
- if (m_labelShader)
- delete m_labelShader;
- m_labelShader = new ShaderHelper(q_ptr, vertexShader, fragmentShader);
- // m_labelShader = new ShaderHelper(q_ptr, QStringLiteral(":/shaders/testDepthVert"),
- // QStringLiteral(":/shaders/testDepthFrag"));
- m_labelShader->initialize();
-}
-
-void Q3DMapsPrivate::updateTextures()
-{
- // Drawer has changed; this flag needs to be checked when checking if we need to update labels
- m_updateLabels = true;
-}
-
-void Q3DMapsPrivate::calculateSceneScalingFactors(const QRect &areaRect)
-{
- m_areaSize = areaRect.size();
- // Calculate scaling factor so that we can be sure the whole area fits to positive z space
- if (zComp > 1.0f)
- m_scaleFactor = qMax(m_areaSize.width(), m_areaSize.height()) / zComp;
- else
- m_scaleFactor = qMax(m_areaSize.width(), m_areaSize.height());
- //qDebug() << "scaleFactor" << m_scaleFactor;
-}
-
-void Q3DMapsPrivate::calculateHeightAdjustment(const QPair<GLfloat, GLfloat> &limits)
-{
- // 2.0f = max difference between minimum and maximum value after scaling with m_heightNormalizer
- m_yAdjustment = 2.0f - ((limits.second - limits.first) / m_heightNormalizer);
- //qDebug() << m_yAdjustment;
-}
-
-void Q3DMapsPrivate::calculateTranslation(QDataItem *item)
-{
- // We need to convert position (which is in coordinates), to translation (which has origin in the center and is scaled)
- // -> move pos(center, center) to trans(0, 0) and pos(0, 0) to trans(left, top)
- GLfloat xTrans = 2.0f * (item->d_ptr->position().x() - (m_areaSize.width() / 2.0f))
- / m_scaleFactor;
- GLfloat zTrans = 2.0f * (item->d_ptr->position().y() - (m_areaSize.height() / 2.0f))
- / m_scaleFactor;
- //qDebug() << "x, y" << item->d_ptr->position().x() << item->d_ptr->position().y();
- item->d_ptr->setTranslation(QVector3D(xTrans, 0.0f, zTrans + zComp));
- //qDebug() << item->d_ptr->translation();
-}
-
-Q3DMapsPrivate::SelectionType Q3DMapsPrivate::isSelected(GLint bar, const QVector3D &selection)
-{
- GLubyte barIdxRed = 0;
- GLubyte barIdxGreen = 0;
- GLubyte barIdxBlue = 0;
- //static QVector3D prevSel = selection; // TODO: For debugging
- SelectionType isSelectedType = SelectionNone;
-
- if (selection == skipColor)
- return isSelectedType; // skip window
-
- if (bar <= 255) {
- barIdxRed = bar;
- } else if (bar <= 65535) {
- barIdxGreen = bar / 256;
- barIdxRed = bar % 256;
- } else {
- barIdxBlue = bar / 65535;
- barIdxGreen = bar % 65535;
- barIdxRed = bar % 256;
- }
-
- QVector3D current = QVector3D(barIdxRed, barIdxGreen, barIdxBlue);
-
- // TODO: For debugging
- //if (selection != prevSel) {
- // qDebug() << selection.x() << selection .y() << selection.z();
- // prevSel = selection;
- //}
-
- if (current == selection)
- isSelectedType = SelectionBar;
-
- return isSelectedType;
-}
-
-bool Q3DMapsPrivate::isValid(const QDataItem &item)
-{
- bool retval = true;
- if (item.d_ptr->value() < 0) {
- qCritical("Data item value out of range");
- retval = false;
- } else if (item.d_ptr->position().x() < 0 || item.d_ptr->position().x() > m_areaSize.width()) {
- qCritical("Data item x position out of range");
- retval = false;
- } else if (item.d_ptr->position().y() < 0 || item.d_ptr->position().y() > m_areaSize.height()) {
- qCritical("Data item y position out of range");
- retval = false;
- }
- return retval;
+ qDebug() << "Destroying Q3DMapsPrivate";
+ delete m_shared;
}
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/engine/q3dmaps.h b/src/datavis3d/engine/q3dmaps.h
index 67c8860b..195b91e0 100644
--- a/src/datavis3d/engine/q3dmaps.h
+++ b/src/datavis3d/engine/q3dmaps.h
@@ -1,66 +1,40 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
#ifndef Q3DMAPS_H
#define Q3DMAPS_H
-#include "QtDataVis3D/qdatavis3dglobal.h"
-#include "QtDataVis3D/qdatavis3namespace.h"
-#include "q3dwindow.h"
+#include <QtDataVis3D/qdatavis3denums.h>
+#include <QtDataVis3D/q3dwindow.h>
#include <QFont>
+#include <QVector3D>
-class QOpenGLShaderProgram;
class QImage;
class QRect;
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVIS3D_BEGIN_NAMESPACE
+class Maps3DController;
class Q3DMapsPrivate;
-class QDataItem;
-class QDataRow;
-class QDataSet;
-class LabelItem;
+class QMapDataProxy;
-class QTENTERPRISE_DATAVIS3D_EXPORT Q3DMaps : public Q3DWindow
+class QT_DATAVIS3D_EXPORT Q3DMaps : public Q3DWindow
{
Q_OBJECT
Q_PROPERTY(QString windowTitle READ windowTitle WRITE setWindowTitle)
@@ -68,6 +42,7 @@ class QTENTERPRISE_DATAVIS3D_EXPORT Q3DMaps : public Q3DWindow
Q_PROPERTY(float fontSize READ fontSize WRITE setFontSize)
public:
+
enum AdjustmentDirection {
AdjustHeight = 0, // map value to y
AdjustWidth, // map value to x
@@ -80,82 +55,72 @@ public:
explicit Q3DMaps();
~Q3DMaps();
- // Add data item. New data item is appended to old data.
- // ownership of data is transferred
- Q_INVOKABLE bool addDataItem(QDataItem *dataItem);
-
- // Add data set. New data is appended to old data.
- // ownership of data is transferred
- Q_INVOKABLE bool addData(const QVector<QDataItem*> &data);
- // ownership of data is transferred
- Q_INVOKABLE bool addData(const QDataRow &data);
-
- // Add data set. Old data is deleted.
- // ownership of data is transferred
- Q_INVOKABLE bool setData(const QVector<QDataItem*> &data);
- // ownership of data is transferred
- Q_INVOKABLE bool setData(QDataRow *data);
+ void setWidth(const int width);
+ void setHeight(const int height);
// bar specifications; base thickness in x, y and z, enum to indicate which direction is increased with value
// TODO: Start using thickness also in adjustment direction; use it as a relative value.
// For example, in AdjustAll mode setting thickness to (0.1f, 1.0f, 0.5f) would apply value to
// x at 10%, y at 100% and z at 50%. If a dimension is not included, given thickness states its absolute value.
- Q_INVOKABLE void setBarSpecs(const QVector3D &thickness = QVector3D(1.0f, 1.0f, 1.0f),
- AdjustmentDirection direction = AdjustHeight);
+ void setBarSpecs(const QVector3D &thickness = QVector3D(1.0f, 1.0f, 1.0f),
+ AdjustmentDirection direction = AdjustHeight);
// bar type; bars (=cubes), pyramids, cones, cylinders, balls, etc.
- Q_INVOKABLE void setBarType(BarStyle style, bool smooth = false);
+ void setBarType(QDataVis::MeshStyle style, bool smooth = false);
// override bar type with own mesh
- Q_INVOKABLE void setMeshFileName(const QString &objFileName);
+ void setMeshFileName(const QString &objFileName);
// Select preset camera placement
- Q_INVOKABLE void setCameraPreset(CameraPreset preset);
+ void setCameraPreset(QDataVis::CameraPreset preset);
// Set camera rotation if you don't want to use the presets (in horizontal (-180...180) and
// vertical (0...90) angles and distance in percentage (10...500))
- Q_INVOKABLE void setCameraPosition(GLfloat horizontal, GLfloat vertical, GLint distance = 100);
+ void setCameraPosition(GLfloat horizontal, GLfloat vertical, GLint distance = 100);
// Set theme (bar colors, shaders, window color, background colors, light intensity and text colors are affected)
- Q_INVOKABLE void setTheme(ColorTheme theme);
+ void setTheme(QDataVis::ColorTheme theme);
// Set color if you don't want to use themes. Set uniform to false if you want the (height) color to change from bottom to top
- Q_INVOKABLE void setBarColor(QColor baseColor, QColor heightColor, bool uniform = true);
+ void setBarColor(QColor baseColor, QColor heightColor, bool uniform = true);
// Set area specs
- Q_INVOKABLE void setAreaSpecs(const QRect &areaRect, const QImage &image);
+ void setAreaSpecs(const QRect &areaRect, const QImage &image);
// Set area image
- Q_INVOKABLE void setImage(const QImage &image);
+ void setImage(const QImage &image);
// TODO: light placement API
// Change selection mode; single bar, bar and row, bar and column, or all
- void setSelectionMode(SelectionMode mode);
- SelectionMode selectionMode();
+ void setSelectionMode(QDataVis::SelectionMode mode);
+ QDataVis::SelectionMode selectionMode() const;
// Set window title
void setWindowTitle(const QString &title);
- QString windowTitle();
+ QString windowTitle() const;
// Font size adjustment
void setFontSize(float fontsize);
- float fontSize();
+ float fontSize() const;
// Set font
void setFont(const QFont &font);
- QFont font();
+ QFont font() const;
// Label transparency adjustment
- void setLabelTransparency(LabelTransparency transparency);
- LabelTransparency labelTransparency();
+ void setLabelTransparency(QDataVis::LabelTransparency transparency);
+ QDataVis::LabelTransparency labelTransparency() const;
// Adjust shadow quality
- void setShadowQuality(ShadowQuality quality);
- ShadowQuality shadowQuality();
+ QDataVis::ShadowQuality setShadowQuality(QDataVis::ShadowQuality quality);
+ QDataVis::ShadowQuality shadowQuality() const;
+
+ // Sets the data proxy. Assumes ownership of the data proxy. Deletes old proxy.
+ void setDataProxy(QMapDataProxy *proxy);
+ QMapDataProxy *dataProxy();
protected:
- void initialize();
void render();
#if defined(Q_OS_ANDROID)
@@ -169,11 +134,10 @@ protected:
void resizeEvent(QResizeEvent *event);
private:
- void drawScene();
QScopedPointer<Q3DMapsPrivate> d_ptr;
- Q_DISABLE_COPY(Q3DMaps);
+ Q_DISABLE_COPY(Q3DMaps)
};
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
+QT_DATAVIS3D_END_NAMESPACE
#endif
diff --git a/src/datavis3d/engine/q3dmaps_p.h b/src/datavis3d/engine/q3dmaps_p.h
index 4c94d85e..166ed8f7 100644
--- a/src/datavis3d/engine/q3dmaps_p.h
+++ b/src/datavis3d/engine/q3dmaps_p.h
@@ -1,41 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
@@ -43,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the Qt API. It exists purely as an
+// This file is not part of the QtDataVis3D API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -52,123 +29,23 @@
#ifndef Q3DMAPS_P_H
#define Q3DMAPS_P_H
-#include "qdatavis3dglobal.h"
-#include "qdatavis3namespace.h"
-#include <QOpenGLFunctions>
-#include <QFont>
-
-class QOpenGLPaintDevice;
-
-class QPoint;
-class QSizeF;
+#include "maps3dcontroller_p.h"
+#include "qdatavis3denums.h"
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVIS3D_BEGIN_NAMESPACE
class Q3DMaps;
-class QDataItem;
-class QDataRow;
-class QDataSet;
-class ShaderHelper;
-class ObjectHelper;
-class TextureHelper;
-class Theme;
-class Drawer;
class Q3DMapsPrivate : public QObject
{
public:
- enum SelectionType {
- SelectionNone = 0,
- SelectionBar,
- SelectionRow,
- SelectionColumn
- };
-
- enum MousePressType {
- MouseNone = 0,
- MouseOnScene,
- MouseOnOverview,
- MouseOnZoom,
- MouseRotating,
- MouseOnPinch
- };
-
-public:
- Q3DMapsPrivate(Q3DMaps *q);
+ Q3DMapsPrivate(Q3DMaps *q, const QRect &rect);
~Q3DMapsPrivate();
- void loadBarMesh();
- void loadBackgroundMesh();
- void loadGridLineMesh();
- void loadLabelMesh();
- void initShaders(const QString &vertexShader, const QString &fragmentShader);
- void initSelectionShader();
- void initBackgroundShaders(const QString &vertexShader, const QString &fragmentShader);
- void initLabelShaders(const QString &vertexShader, const QString &fragmentShader);
- void initSelectionBuffer();
-#if !defined(QT_OPENGL_ES_2)
- void initDepthShader();
- void initDepthBuffer();
-#endif
- void updateTextures();
- void calculateSceneScalingFactors(const QRect &areaRect);
- void calculateHeightAdjustment(const QPair<GLfloat, GLfloat> &limits);
- void calculateTranslation(QDataItem *item);
- SelectionType isSelected(GLint bar, const QVector3D &selection);
- bool isValid(const QDataItem &item);
-
Q3DMaps *q_ptr;
-
- QOpenGLPaintDevice *m_paintDevice;
- ShaderHelper *m_barShader;
- ShaderHelper *m_depthShader;
- ShaderHelper *m_selectionShader;
- ShaderHelper *m_backgroundShader;
- ShaderHelper *m_labelShader;
- ObjectHelper *m_barObj;
- ObjectHelper *m_backgroundObj;
- ObjectHelper *m_gridLineObj;
- ObjectHelper *m_labelObj;
- QString m_objFile;
- MousePressType m_mousePressed;
- QPoint m_mousePos;
- GLint m_zoomLevel;
- GLfloat m_zoomAdjustment;
- GLfloat m_horizontalRotation;
- GLfloat m_verticalRotation;
- QVector3D m_barThickness;
- GLfloat m_heightNormalizer;
- GLfloat m_yAdjustment;
- GLfloat m_scaleFactor;
- Theme *m_theme;
- bool m_isInitialized;
- SelectionMode m_selectionMode;
- QDataItem *m_selectedBar;
- QDataRow *m_data;
- QString m_axisLabelX;
- QString m_axisLabelZ;
- QString m_axisLabelY;
- QRect m_sceneViewPort;
- QRect m_zoomViewPort;
- bool m_zoomActivated;
- TextureHelper *m_textureHelper;
- LabelTransparency m_labelTransparency;
- QFont m_font;
- Drawer *m_drawer;
- QSizeF m_areaSize;
- GLuint m_bgrTexture;
- GLuint m_depthTexture;
- GLuint m_selectionTexture;
- GLuint m_depthFrameBuffer;
- GLuint m_selectionFrameBuffer;
- GLuint m_selectionDepthBuffer;
- bool m_updateLabels;
- Q3DMaps::AdjustmentDirection m_adjustDirection;
- ShadowQuality m_shadowQuality;
- GLfloat m_shadowQualityToShader;
- bool m_bgrHasAlpha;
+ Maps3DController *m_shared;
};
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
+QT_DATAVIS3D_END_NAMESPACE
#endif
diff --git a/src/datavis3d/engine/q3dscatter.cpp b/src/datavis3d/engine/q3dscatter.cpp
new file mode 100644
index 00000000..a9c4a1b0
--- /dev/null
+++ b/src/datavis3d/engine/q3dscatter.cpp
@@ -0,0 +1,463 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "q3dscatter.h"
+#include "q3dscatter_p.h"
+#include "scatter3dcontroller_p.h"
+#include "qvalueaxis.h"
+
+#include <QMouseEvent>
+
+#include <QDebug>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+/*!
+ * \class Q3DScatter
+ * \inmodule QtDataVis3D
+ * \brief The Q3DScatter class provides methods for rendering 3D scatter graphs.
+ * \since 1.0.0
+ *
+ * This class enables developers to render bar graphs in 3D and to view them by rotating the scene
+ * freely. Rotation is done by holding down the right mouse button and moving the mouse. Zooming
+ * is done by mouse wheel. Selection, if enabled, is done by left mouse button. The scene can be
+ * reset to default camera view by clicking mouse wheel. In touch devices rotation is done
+ * by tap-and-move, selection by tap-and-hold and zoom by pinch.
+ *
+ * Methods are provided for changing bar types, themes, bar selection modes and so on. See the
+ * methods for more detailed descriptions.
+ *
+ * \section1 How to construct a minimal Q3DScatter chart
+ *
+ * After constructing Q3DScatter, you need to set up sample space using setupSampleSpace(). Let's
+ * set the sample space to 5 rows and 5 columns:
+ *
+ * \snippet doc_src_q3dscatter_construction.cpp 0
+ *
+ * Now Q3DScatter is ready to receive data to be rendered. Add one row of 5 floats into the data
+ * set:
+ *
+ * \snippet doc_src_q3dscatter_construction.cpp 1
+ *
+ * \note We set the sample space to 5 x 5, but we are inserting only one row of data. This is ok,
+ * the rest of the rows will just be blank.
+ *
+ * Finally you will need to set it visible:
+ *
+ * \snippet doc_src_q3dscatter_construction.cpp 2
+ *
+ * The complete code needed to create and display this chart is:
+ *
+ * \snippet doc_src_q3dscatter_construction.cpp 3
+ *
+ * And this is what those few lines of code produce:
+ *
+ * \image q3dscatter-minimal.png
+ *
+ * The scene can be rotated and zoomed into, but no other interaction is included in this minimal
+ * code example. You can learn more by familiarizing yourself with the examples provided, like
+ * the \l{Rainfall Example} or the \l{Widget Example}.
+ *
+ * \sa Q3DMaps, {Qt Data Visualization 3D C++ Classes}
+ */
+
+/*!
+ * Constructs a new 3D scatter window.
+ */
+Q3DScatter::Q3DScatter()
+ : d_ptr(new Q3DScatterPrivate(this, geometry()))
+{
+ d_ptr->m_shared->initializeOpenGL();
+ QObject::connect(d_ptr->m_shared, &Scatter3DController::shadowQualityChanged, this,
+ &Q3DScatter::handleShadowQualityUpdate);
+}
+
+/*!
+ * Destroys the 3D scatter window.
+ */
+Q3DScatter::~Q3DScatter()
+{
+}
+
+/*!
+ * \internal
+ */
+void Q3DScatter::render()
+{
+ d_ptr->m_shared->synchDataToRenderer();
+ d_ptr->m_shared->render();
+}
+
+void Q3DScatter::handleShadowQualityUpdate(QDataVis::ShadowQuality quality)
+{
+ emit shadowQualityChanged(quality);
+}
+
+#if defined(Q_OS_ANDROID)
+/*!
+ * \internal
+ */
+void Q3DScatter::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ d_ptr->m_shared->mouseDoubleClickEvent(event);
+}
+
+/*!
+ * \internal
+ */
+void Q3DScatter::touchEvent(QTouchEvent *event)
+{
+ d_ptr->m_shared->touchEvent(event);
+}
+#endif
+
+/*!
+ * \internal
+ */
+void Q3DScatter::mousePressEvent(QMouseEvent *event)
+{
+ d_ptr->m_shared->mousePressEvent(event, event->pos());
+}
+
+/*!
+ * \internal
+ */
+void Q3DScatter::mouseReleaseEvent(QMouseEvent *event)
+{
+ d_ptr->m_shared->mouseReleaseEvent(event, event->pos());
+}
+
+/*!
+ * \internal
+ */
+void Q3DScatter::mouseMoveEvent(QMouseEvent *event)
+{
+ d_ptr->m_shared->mouseMoveEvent(event, event->pos());
+}
+
+/*!
+ * \internal
+ */
+void Q3DScatter::wheelEvent(QWheelEvent *event)
+{
+ d_ptr->m_shared->wheelEvent(event);
+}
+
+/*!
+ * \internal
+ */
+void Q3DScatter::resizeEvent(QResizeEvent *event)
+{
+ Q_UNUSED(event);
+ d_ptr->m_shared->setSize(width(), height());
+}
+
+// TODO: Document
+// Size
+void Q3DScatter::setWidth(const int width)
+{
+ d_ptr->m_shared->setWidth(width);
+ QWindow::setWidth(width);
+}
+
+void Q3DScatter::setHeight(const int height)
+{
+ d_ptr->m_shared->setHeight(height);
+ QWindow::setHeight(height);
+}
+
+/*!
+ * \a style One of the values in \c QDataVis::MeshStyle. \c Spheres by default.
+ *
+ * \a smooth A flag to set shading to smooth. \c false by default.
+ *
+ * Sets the object type to one of the supplied ones.
+ *
+ * \sa setMeshFileName()
+ */
+void Q3DScatter::setObjectType(QDataVis::MeshStyle style, bool smooth)
+{
+ d_ptr->m_shared->setObjectType(style, smooth);
+}
+
+/*!
+ * \a preset Move camera to a predefined position from \c QDataVis::CameraPreset.
+ *
+ * Moves camera to a predefined position.
+ */
+void Q3DScatter::setCameraPreset(QDataVis::CameraPreset preset)
+{
+ d_ptr->m_shared->setCameraPreset(preset);
+}
+
+/*!
+ * \a horizontal Horizontal angle for camera.
+ *
+ * \a vertical Vertical angle for camera.
+ *
+ * \a distance Distance from the center. \c 100 by default.
+ *
+ * Move camera to a wanted position based on horizontal and veritcal angles. Angles are limited
+ * to -180...180 in horizontal direction and -90...90 in vertical.
+ * Distance is adjustable between 10 and 500.
+ */
+void Q3DScatter::setCameraPosition(qreal horizontal, qreal vertical, int distance)
+{
+ d_ptr->m_shared->setCameraPosition(GLfloat(horizontal), GLfloat(vertical), GLint(distance));
+}
+
+/*!
+ * \a theme Apply a predefined theme from \c QDataVis::ColorTheme.
+ *
+ * Sets a predefined theme. Theme affects object colors, label colors, text color, background color,
+ * window color and grid color. Lighting is also adjusted by themes.
+ */
+void Q3DScatter::setTheme(QDataVis::ColorTheme theme)
+{
+ d_ptr->m_shared->setColorTheme(theme);
+}
+
+/*!
+ * \a baseColor The base color of an object. If all other colors are black, this sets the final
+ * color of the object.
+ *
+ * \a heightColor This color is added to the object based on its y-position. The higher the object,
+ * the more prominent this color becomes. Setting this black keeps the color unchanged regardless
+ * of y-position.
+ *
+ * \a depthColor This color becomes more prominent the further back in z-position the object is.
+ * Setting this black keeps objects the same color regardless of "depth" in the set.
+ *
+ * \a uniform A flag to define if color needs to be uniform throughout object's length, or will the
+ * colors be applied by height. \c true by default.
+ *
+ * Set object color using your own colors. This overrides colors from theme.
+ */
+void Q3DScatter::setObjectColor(QColor baseColor, QColor heightColor, QColor depthColor, bool uniform)
+{
+ d_ptr->m_shared->setObjectColor(baseColor, heightColor, depthColor, uniform);
+}
+
+/*!
+ * \property Q3DScatter::selectionMode
+ *
+ * \a mode Set object selection mode from \c QDataVis::SelectionMode. \c ModeItem by default.
+ *
+ * Sets object selection mode to be used.
+ */
+void Q3DScatter::setSelectionMode(QDataVis::SelectionMode mode)
+{
+ d_ptr->m_shared->setSelectionMode(mode);
+}
+
+QDataVis::SelectionMode Q3DScatter::selectionMode() const
+{
+ return d_ptr->m_shared->selectionMode();
+}
+
+/*!
+ * \property Q3DScatter::windowTitle
+ *
+ * \a title QString label to be used as window title.
+ *
+ * Sets the window title. The default is application executable name.
+ */
+void Q3DScatter::setWindowTitle(const QString &title)
+{
+ setTitle(title);
+}
+
+QString Q3DScatter::windowTitle() const
+{
+ return title();
+}
+
+/*!
+ * \a objFileName File name of a mesh object. Object needs to be in Wavefront obj format
+ * and include vertices, normals and UVs. It also needs to be in triangles.
+ *
+ * Override object type with an object mesh. \sa setObjectType()
+ */
+void Q3DScatter::setMeshFileName(const QString &objFileName)
+{
+ d_ptr->m_shared->setMeshFileName(objFileName);
+}
+
+/*!
+ * \property Q3DScatter::fontSize
+ *
+ * \a fontsize Size of the font.
+ *
+ * Sets font size.
+ */
+void Q3DScatter::setFontSize(float fontsize)
+{
+ d_ptr->m_shared->setFontSize(fontsize);
+}
+
+float Q3DScatter::fontSize() const
+{
+ return d_ptr->m_shared->fontSize();
+}
+
+/*!
+ * \property Q3DScatter::font
+ *
+ * \a font QFont to be used for labels. \c Arial by default.
+ *
+ * Sets the font for labels.
+ */
+void Q3DScatter::setFont(const QFont &font)
+{
+ d_ptr->m_shared->setFont(font);
+}
+
+QFont Q3DScatter::font() const
+{
+ return d_ptr->m_shared->font();
+}
+
+/*!
+ * \property Q3DScatter::labelTransparency
+ *
+ * \a transparency Transparency level of labels from \c QDataVis::LabelTransparency.
+ * \c TransparencyFromTheme by default.
+ *
+ * Sets label transparency.
+ */
+void Q3DScatter::setLabelTransparency(QDataVis::LabelTransparency transparency)
+{
+ d_ptr->m_shared->setLabelTransparency(transparency);
+}
+
+QDataVis::LabelTransparency Q3DScatter::labelTransparency() const
+{
+ return d_ptr->m_shared->labelTransparency();
+}
+
+/*!
+ * \property Q3DScatter::gridVisible
+ *
+ * \a visible Flag to enable or disable grid. \c true by default.
+ *
+ * Sets grid drawing on or off.
+ */
+void Q3DScatter::setGridVisible(bool visible)
+{
+ d_ptr->m_shared->setGridEnabled(visible);
+}
+
+bool Q3DScatter::isGridVisible() const
+{
+ return d_ptr->m_shared->gridEnabled();
+}
+
+/*!
+ * \property Q3DScatter::backgroundVisible
+ *
+ * \a visible Flag to enable or disable background. \c true by default.
+ *
+ * Sets backround rendering on or off.
+ */
+void Q3DScatter::setBackgroundVisible(bool visible)
+{
+ d_ptr->m_shared->setBackgroundEnabled(visible);
+}
+
+bool Q3DScatter::isBackgroundVisible() const
+{
+ return d_ptr->m_shared->backgroundEnabled();
+}
+
+/*!
+ * \property Q3DScatter::shadowQuality
+ *
+ * \a quality Shadow quality from \c QDataVis::ShadowQuality. \c ShadowLow by default.
+ *
+ * Sets shadow quality. If setting QDataVis::ShadowQuality of a certain level fails, a level is lowered
+ * until it is successful and shadowQualityChanged signal is emitted for each time the change is done.
+ */
+void Q3DScatter::setShadowQuality(QDataVis::ShadowQuality quality)
+{
+ return d_ptr->m_shared->setShadowQuality(quality);
+}
+
+QDataVis::ShadowQuality Q3DScatter::shadowQuality() const
+{
+ return d_ptr->m_shared->shadowQuality();
+}
+
+void Q3DScatter::setValueAxisX(QValueAxis *axis)
+{
+ Q_ASSERT(axis);
+
+ return d_ptr->m_shared->setAxisX(axis);
+}
+
+QValueAxis *Q3DScatter::valueAxisX()
+{
+ return static_cast<QValueAxis *>(d_ptr->m_shared->axisX());
+}
+
+void Q3DScatter::setValueAxisY(QValueAxis *axis)
+{
+ Q_ASSERT(axis);
+
+ return d_ptr->m_shared->setAxisY(axis);
+}
+
+QValueAxis *Q3DScatter::valueAxisY()
+{
+ return static_cast<QValueAxis *>(d_ptr->m_shared->axisY());
+}
+
+void Q3DScatter::setValueAxisZ(QValueAxis *axis)
+{
+ Q_ASSERT(axis);
+
+ return d_ptr->m_shared->setAxisZ(axis);
+}
+
+QValueAxis *Q3DScatter::valueAxisZ()
+{
+ return static_cast<QValueAxis *>(d_ptr->m_shared->axisZ());
+}
+
+void Q3DScatter::setDataProxy(QScatterDataProxy *proxy)
+{
+ d_ptr->m_shared->setDataProxy(proxy);
+}
+
+QScatterDataProxy *Q3DScatter::dataProxy()
+{
+ return d_ptr->m_shared->dataProxy();
+}
+
+Q3DScatterPrivate::Q3DScatterPrivate(Q3DScatter *q, QRect rect)
+ : q_ptr(q),
+ m_shared(new Scatter3DController(rect))
+{
+}
+
+Q3DScatterPrivate::~Q3DScatterPrivate()
+{
+ qDebug() << "Destroying Q3DScatterPrivate";
+ delete m_shared;
+}
+
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/engine/q3dscatter.h b/src/datavis3d/engine/q3dscatter.h
new file mode 100644
index 00000000..73a7d214
--- /dev/null
+++ b/src/datavis3d/engine/q3dscatter.h
@@ -0,0 +1,153 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef Q3DSCATTER_H
+#define Q3DSCATTER_H
+
+#include <QtDataVis3D/qdatavis3denums.h>
+#include <QtDataVis3D/q3dwindow.h>
+#include <QFont>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class Q3DScatterPrivate;
+class LabelItem;
+class QValueAxis;
+class QCategoryAxis;
+class QScatterDataProxy;
+
+class QT_DATAVIS3D_EXPORT Q3DScatter : public Q3DWindow
+{
+ Q_OBJECT
+ Q_PROPERTY(QtDataVis3D::QDataVis::SelectionMode selectionMode READ selectionMode WRITE setSelectionMode)
+ Q_PROPERTY(QtDataVis3D::QDataVis::LabelTransparency labelTransparency READ labelTransparency WRITE setLabelTransparency)
+ Q_PROPERTY(QtDataVis3D::QDataVis::ShadowQuality shadowQuality READ shadowQuality WRITE setShadowQuality)
+ Q_PROPERTY(QString windowTitle READ windowTitle WRITE setWindowTitle)
+ Q_PROPERTY(QFont font READ font WRITE setFont)
+ Q_PROPERTY(float fontSize READ fontSize WRITE setFontSize)
+ Q_PROPERTY(bool gridVisible READ isGridVisible WRITE setGridVisible)
+ Q_PROPERTY(bool backgroundVisible READ isBackgroundVisible WRITE setBackgroundVisible)
+ Q_ENUMS(QtDataVis3D::QDataVis::SelectionMode)
+ Q_ENUMS(QtDataVis3D::QDataVis::ShadowQuality)
+ Q_ENUMS(QtDataVis3D::QDataVis::LabelTransparency)
+
+public:
+ explicit Q3DScatter();
+ ~Q3DScatter();
+
+ // object type; spheres, dots
+ void setObjectType(QDataVis::MeshStyle style, bool smooth = false);
+
+ // Select preset camera placement
+ void setCameraPreset(QDataVis::CameraPreset preset);
+
+ // Set camera rotation if you don't want to use the presets (in horizontal (-180...180) and
+ // vertical (-90...90) angles and distance in percentage (10...500))
+ void setCameraPosition(qreal horizontal, qreal vertical, int distance = 100);
+
+ // Set theme (object colors, shaders, window color, background colors, light intensity and text
+ // colors are affected)
+ void setTheme(QDataVis::ColorTheme theme);
+
+ // Set color if you don't want to use themes. Set uniform to false if you want the (height)
+ // color to change from bottom to top
+ void setObjectColor(QColor baseColor, QColor heightColor, QColor depthColor,
+ bool uniform = true);
+
+ // override object type with own mesh
+ void setMeshFileName(const QString &objFileName);
+
+ // Change selection mode
+ void setSelectionMode(QDataVis::SelectionMode mode);
+ QDataVis::SelectionMode selectionMode() const;
+
+ // Set window title
+ void setWindowTitle(const QString &title);
+ QString windowTitle() const;
+
+ // Font size adjustment
+ void setFontSize(float fontsize);
+ float fontSize() const;
+
+ // Set font
+ void setFont(const QFont &font);
+ QFont font() const;
+
+ // Label transparency adjustment
+ void setLabelTransparency(QDataVis::LabelTransparency transparency);
+ QDataVis::LabelTransparency labelTransparency() const;
+
+ // Enable or disable background grid
+ void setGridVisible(bool visible);
+ bool isGridVisible() const;
+
+ // Size
+ void setWidth(const int width);
+ void setHeight(const int height);
+
+ // Enable or disable background mesh
+ void setBackgroundVisible(bool visible);
+ bool isBackgroundVisible() const;
+
+ // Adjust shadow quality
+ void setShadowQuality(QDataVis::ShadowQuality quality);
+ QDataVis::ShadowQuality shadowQuality() const;
+
+ // Axes
+ void setValueAxisX(QValueAxis *axis);
+ QValueAxis *valueAxisX();
+
+ void setValueAxisY(QValueAxis *axis);
+ QValueAxis *valueAxisY();
+
+ void setValueAxisZ(QValueAxis *axis);
+ QValueAxis *valueAxisZ();
+
+ // Sets the data proxy. Assumes ownership of the data proxy. Deletes old proxy.
+ void setDataProxy(QtDataVis3D::QScatterDataProxy *proxy);
+ QScatterDataProxy *dataProxy();
+
+public slots:
+ // Used to detect when shadow quality changes autonomously due to e.g. resizing.
+ void handleShadowQualityUpdate(QDataVis::ShadowQuality quality);
+
+signals:
+ // Signals shadow quality changes.
+ void shadowQualityChanged(QDataVis::ShadowQuality quality);
+
+protected:
+ void render();
+
+#if defined(Q_OS_ANDROID)
+ void mouseDoubleClickEvent(QMouseEvent *event);
+ void touchEvent(QTouchEvent *event);
+#endif
+ void mousePressEvent(QMouseEvent *event);
+ void mouseReleaseEvent(QMouseEvent *event);
+ void mouseMoveEvent(QMouseEvent *event);
+ void wheelEvent(QWheelEvent *event);
+ void resizeEvent(QResizeEvent *event);
+
+private:
+ QScopedPointer<Q3DScatterPrivate> d_ptr;
+ Q_DISABLE_COPY(Q3DScatter)
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/engine/q3dscatter_p.h b/src/datavis3d/engine/q3dscatter_p.h
new file mode 100644
index 00000000..ab2e2b06
--- /dev/null
+++ b/src/datavis3d/engine/q3dscatter_p.h
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Q3DSCATTER_p_H
+#define Q3DSCATTER_p_H
+
+#include "scatter3dcontroller_p.h"
+#include "qdatavis3denums.h"
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class Q3DScatter;
+
+class Q3DScatterPrivate : public QObject
+{
+public:
+ Q3DScatterPrivate(Q3DScatter *q, QRect rect);
+ ~Q3DScatterPrivate();
+
+ Q3DScatter *q_ptr;
+ Scatter3DController *m_shared;
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/engine/q3dsurface.cpp b/src/datavis3d/engine/q3dsurface.cpp
new file mode 100644
index 00000000..7647ad10
--- /dev/null
+++ b/src/datavis3d/engine/q3dsurface.cpp
@@ -0,0 +1,181 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "q3dsurface.h"
+#include "q3dsurface_p.h"
+
+#include <QMouseEvent>
+
+#include <QDebug>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+Q3DSurface::Q3DSurface()
+ : d_ptr(new Q3DSurfacePrivate(this, geometry()))
+{
+ d_ptr->m_shared->initializeOpenGL();
+}
+
+Q3DSurface::~Q3DSurface()
+{
+}
+
+void Q3DSurface::render()
+{
+ d_ptr->m_shared->render();
+}
+
+#if defined(Q_OS_ANDROID)
+void Q3DSurface::mouseDoubleClickEvent(QMouseEvent *event)
+{
+}
+void Q3DSurface::touchEvent(QTouchEvent *event)
+{
+}
+#endif
+
+void Q3DSurface::mousePressEvent(QMouseEvent *event)
+{
+ d_ptr->m_shared->mousePressEvent(event, event->pos());
+}
+
+void Q3DSurface::mouseReleaseEvent(QMouseEvent *event)
+{
+ d_ptr->m_shared->mouseReleaseEvent(event, event->pos());
+}
+
+void Q3DSurface::mouseMoveEvent(QMouseEvent *event)
+{
+ d_ptr->m_shared->mouseMoveEvent(event, event->pos());
+}
+
+void Q3DSurface::wheelEvent(QWheelEvent *event)
+{
+ Q_UNUSED(event)
+}
+
+void Q3DSurface::resizeEvent(QResizeEvent *event)
+{
+ Q_UNUSED(event);
+ d_ptr->m_shared->setWidth(width());
+ d_ptr->m_shared->setHeight(height());
+}
+
+void Q3DSurface::setSmoothSurface(bool enable)
+{
+ d_ptr->m_shared->setSmoothSurface(enable);
+}
+
+bool Q3DSurface::smoothSurface() const
+{
+ return d_ptr->m_shared->smoothSurface();
+}
+
+void Q3DSurface::setSurfaceGrid(bool enable)
+{
+ d_ptr->m_shared->setSurfaceGrid(enable);
+}
+
+bool Q3DSurface::surfaceGrid() const
+{
+ return d_ptr->m_shared->surfaceGrid();
+}
+
+void Q3DSurface::setWidth(const int width)
+{
+ d_ptr->m_shared->setWidth(width);
+ QWindow::setWidth(width);
+}
+
+void Q3DSurface::setHeight(const int height)
+{
+ d_ptr->m_shared->setHeight(height);
+ QWindow::setHeight(height);
+}
+
+/*!
+ * \a segmentCount How many segments will be drawn. \c 5 by default.
+ *
+ * \a step How large a step each segment is.
+ *
+ * \a minimum Minimum value a bar in data set can have. Setting this correctly is especially
+ * important if values can be negative, or autoscaling won't work correctly.
+ *
+ * Sets segment count and step. Note; segmentCount * step should be the maximum possible value of data
+ * set.
+ */
+void Q3DSurface::setSegmentCount(int segmentCount, qreal step, qreal minimum)
+{
+ d_ptr->m_shared->setSegmentCount(GLint(segmentCount), GLfloat(step), GLfloat(minimum));
+}
+
+void Q3DSurface::setGradientColorAt(qreal pos, const QColor &color)
+{
+ d_ptr->m_shared->setGradientColorAt(pos, color);
+}
+
+// TODO /////////////////////////////////////////
+void Q3DSurface::appendSeries(QList<qreal> series, int width, int depth )
+{
+ d_ptr->appendSeries(series);
+ d_ptr->m_shared->setData(series, width, depth);
+}
+
+void Q3DSurface::showData() const
+{
+ for (int i = 0; i < d_ptr->numOfSeries(); i++) {
+ QList<qreal> s = d_ptr->seriesAt(i);
+ qDebug() << "Series = ";
+ foreach (qreal val, s) {
+ qDebug() << val;
+ }
+ }
+}
+
+// TODO END //////////////////////////////////////////
+
+/////////////////// PRIVATE ///////////////////////////////////
+
+Q3DSurfacePrivate::Q3DSurfacePrivate(Q3DSurface *q, QRect rect)
+ : q_ptr(q),
+ m_shared(new Surface3dController(rect))
+{
+}
+
+Q3DSurfacePrivate::~Q3DSurfacePrivate()
+{
+ qDebug() << "Q3DSurfacePrivate::~Q3DSurfacePrivate";
+ delete m_shared;
+}
+
+void Q3DSurfacePrivate::appendSeries(QList<qreal> series)
+{
+ m_seriesList.append(series);
+}
+
+QList<qreal> Q3DSurfacePrivate::seriesAt(int i)
+{
+ return m_seriesList.at(i);
+}
+
+int Q3DSurfacePrivate::numOfSeries()
+{
+ return m_seriesList.count();
+}
+
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/engine/q3dsurface.h b/src/datavis3d/engine/q3dsurface.h
new file mode 100644
index 00000000..c2deea9a
--- /dev/null
+++ b/src/datavis3d/engine/q3dsurface.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef Q3DSURFACE_H
+#define Q3DSURFACE_H
+
+#include <QtDataVis3D/qdatavis3denums.h>
+#include <QtDataVis3D/q3dwindow.h>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class Q3DSurfacePrivate;
+
+class QT_DATAVIS3D_EXPORT Q3DSurface : public Q3DWindow
+{
+ Q_OBJECT
+ Q_PROPERTY(bool smoothSurface READ smoothSurface WRITE setSmoothSurface)
+ Q_PROPERTY(bool surfaceGrid READ surfaceGrid WRITE setSurfaceGrid)
+
+public:
+ explicit Q3DSurface();
+ ~Q3DSurface();
+
+ // Enable or disable the smoothes of the surface
+ void setSmoothSurface(bool enable);
+ bool smoothSurface() const;
+
+ // Enable or disable the grid on the surface
+ void setSurfaceGrid(bool enable);
+ bool surfaceGrid() const;
+
+ void setGradientColorAt(qreal pos, const QColor &color);
+
+ // Set segment count and step. Note; segmentCount * step should be the maximum possible value of data
+ // set. Minimum is the absolute minimum possible value a bar can have. This is especially
+ // important to set if values can be negative.
+ void setSegmentCount(int segmentCount, qreal step, qreal minimum = 0.0f);
+
+//TODO part
+ void appendSeries(QList<qreal> series, int width, int depth);
+ void showData() const;
+//END TODO
+
+ // TODO: Do these need to be public? Where are they called from?
+ // Size
+ void setWidth(const int width);
+ void setHeight(const int height);
+
+protected:
+ void render();
+
+#if defined(Q_OS_ANDROID)
+ void mouseDoubleClickEvent(QMouseEvent *event);
+ void touchEvent(QTouchEvent *event);
+#endif
+ void mousePressEvent(QMouseEvent *event);
+ void mouseReleaseEvent(QMouseEvent *event);
+ void mouseMoveEvent(QMouseEvent *event);
+ void wheelEvent(QWheelEvent *event);
+ void resizeEvent(QResizeEvent *event);
+
+private:
+ QScopedPointer<Q3DSurfacePrivate> d_ptr;
+ Q_DISABLE_COPY(Q3DSurface)
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif // Q3DSURFACE_H
diff --git a/src/datavis3d/engine/q3dsurface_p.h b/src/datavis3d/engine/q3dsurface_p.h
new file mode 100644
index 00000000..1e132416
--- /dev/null
+++ b/src/datavis3d/engine/q3dsurface_p.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Q3DSURFACE_P_H
+#define Q3DSURFACE_P_H
+
+#include "surface3dcontroller_p.h"
+#include "qdatavis3denums.h"
+
+#include <QList>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class Q3DSurface;
+
+class Q3DSurfacePrivate : public QObject
+{
+public:
+ Q3DSurfacePrivate(Q3DSurface *q, QRect rect);
+ ~Q3DSurfacePrivate();
+
+ // TODO
+ void appendSeries(QList<qreal> series);
+ QList<qreal> seriesAt(int i);
+ int numOfSeries();
+ // TODO
+
+ Surface3dController *m_shared;
+
+private:
+ Q3DSurface *q_ptr;
+ QList<QList<qreal> > m_seriesList; // Temp to be replaced by dataset
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif // Q3DSURFACE_P_H
diff --git a/src/datavis3d/engine/q3dwindow.cpp b/src/datavis3d/engine/q3dwindow.cpp
index af975cb1..5b2b70ab 100644
--- a/src/datavis3d/engine/q3dwindow.cpp
+++ b/src/datavis3d/engine/q3dwindow.cpp
@@ -1,41 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
@@ -50,7 +27,7 @@
#include <QDebug>
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVIS3D_BEGIN_NAMESPACE
/*!
* \class Q3DWindow
@@ -95,28 +72,13 @@ Q3DWindow::Q3DWindow(QWindow *parent)
qDebug() << "initializeOpenGLFunctions()";
initializeOpenGLFunctions();
- initialize();
-}
-
-/*!
- * Destroys Q3DWindow.
- */
-Q3DWindow::~Q3DWindow()
-{
-}
-
-/*!
- * \internal
- */
-void Q3DWindow::initialize()
-{
const GLubyte *version = glGetString(GL_VERSION);
qDebug() << "OpenGL version:" << (const char *)version;
version = glGetString(GL_SHADING_LANGUAGE_VERSION);
qDebug() << "GLSL version:" << (const char *)version;
#if !defined(QT_OPENGL_ES_2)
// If we have real OpenGL, GLSL version must be 1.2 or over. Quit if not.
- QStringList splitversionstr = QString((const char *)version).split(" ");
+ QStringList splitversionstr = QString::fromLatin1((const char *)version).split(QChar::fromLatin1(' '));
if (splitversionstr[0].toFloat() < 1.2)
qFatal("GLSL version must be 1.20 or higher. Try installing latest display drivers.");
#endif
@@ -124,6 +86,13 @@ void Q3DWindow::initialize()
}
/*!
+ * Destroys Q3DWindow.
+ */
+Q3DWindow::~Q3DWindow()
+{
+}
+
+/*!
* \internal
*/
void Q3DWindow::render()
@@ -174,17 +143,10 @@ void Q3DWindow::renderNow()
if (!isExposed())
return;
- static bool needsInit = true;
-
d_ptr->m_updatePending = false;
d_ptr->m_context->makeCurrent(this);
- if (needsInit) {
- initialize();
- needsInit = false;
- }
-
render();
d_ptr->m_context->swapBuffers(this);
@@ -216,4 +178,4 @@ Q3DWindowPrivate::~Q3DWindowPrivate()
{
}
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/engine/q3dwindow.h b/src/datavis3d/engine/q3dwindow.h
index bf7d8f74..e9f8fe1d 100644
--- a/src/datavis3d/engine/q3dwindow.h
+++ b/src/datavis3d/engine/q3dwindow.h
@@ -1,59 +1,36 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
#ifndef Q3DWINDOW_H
#define Q3DWINDOW_H
-#include "QtDataVis3D/qdatavis3dglobal.h"
+#include <QtDataVis3D/qdatavis3denums.h>
#include <QWindow>
#include <QOpenGLFunctions>
class QPainter;
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVIS3D_BEGIN_NAMESPACE
class Q3DWindowPrivate;
-class QTENTERPRISE_DATAVIS3D_EXPORT Q3DWindow : public QWindow, protected QOpenGLFunctions
+class QT_DATAVIS3D_EXPORT Q3DWindow : public QWindow, protected QOpenGLFunctions
{
Q_OBJECT
@@ -67,7 +44,6 @@ private slots:
protected:
virtual void render();
- virtual void initialize();
void setAnimating(bool animating);
bool event(QEvent *event);
@@ -80,6 +56,6 @@ private:
friend class Q3DBars;
};
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
+QT_DATAVIS3D_END_NAMESPACE
#endif
diff --git a/src/datavis3d/engine/q3dwindow_p.h b/src/datavis3d/engine/q3dwindow_p.h
index 4c6c5209..d32facfa 100644
--- a/src/datavis3d/engine/q3dwindow_p.h
+++ b/src/datavis3d/engine/q3dwindow_p.h
@@ -1,41 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
@@ -43,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the Qt API. It exists purely as an
+// This file is not part of the QtDataVis3D API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -52,12 +29,12 @@
#ifndef Q3DWINDOW_p_H
#define Q3DWINDOW_p_H
-#include "qdatavis3dglobal.h"
+#include "datavis3dglobal_p.h"
class QOpenGLContext;
class QOpenGLPaintDevice;
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVIS3D_BEGIN_NAMESPACE
class Q3DWindow;
@@ -76,6 +53,6 @@ public:
QOpenGLContext *m_context;
};
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
+QT_DATAVIS3D_END_NAMESPACE
#endif
diff --git a/src/datavis3d/engine/qdataitem.cpp b/src/datavis3d/engine/qdataitem.cpp
deleted file mode 100644
index 883c190c..00000000
--- a/src/datavis3d/engine/qdataitem.cpp
+++ /dev/null
@@ -1,230 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtDataVis3D module.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** 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 Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qdataitem.h"
-#include "qdataitem_p.h"
-
-#include <QPoint>
-#include <QString>
-
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
-
-/*!
- * \class QDataItem
- * \inmodule QtDataVis3D
- * \brief The QDataItem class provides a container for data to be added to graphs.
- * \since 1.0.0
- *
- * A QDataItem holds data for a single bar in a Q3DMaps or Q3DBars graph.
- *
- * \sa QDataRow, QDataSet, {Qt Data Visualization 3D C++ Classes}
- */
-
-/*!
- * \a value A float value of the data item.
- *
- * \a label A QString label for the item.
- *
- * Constructs QDataItem.
- */
-QDataItem::QDataItem(float value, const QString &label)
- : d_ptr(new QDataItemPrivate(this, value, label))
-{
-}
-
-/*!
- * Destroys QDataItem.
- */
-QDataItem::~QDataItem()
-{
-}
-
-/*!
- * \property QDataItem::label
- *
- * \a label A QString label for the data item. Unit, for example.
- *
- * \a prepend A flag to indicate if the label is to be prepended or appended to the value.
- * \c false by default.
- *
- * Sets label for the data item.
- */
-void QDataItem::setLabel(const QString &label, bool prepend)
-{
- d_ptr->m_labelString = label;
- d_ptr->m_prependLabel = prepend;
-}
-
-QString QDataItem::label()
-{
- return d_ptr->m_labelString;
-}
-
-/*!
- * \property QDataItem::value
- *
- * \a value A float value for the data item.
- *
- * Sets value for the data item.
- */
-void QDataItem::setValue(float value)
-{
- d_ptr->m_value = value;
-}
-
-/*!
- * \overload QDataItem::value
- *
- * \a value An int value for the data item.
- *
- * Sets value for the data item.
- */
-void QDataItem::setValue(int value)
-{
- d_ptr->m_value = (float)value;
-}
-
-float QDataItem::value()
-{
- return d_ptr->m_value;
-}
-
-/*!
- * \property QDataItem::position
- *
- * \a position A QPointF position for the data item.
- *
- * Sets position for the data item. Has no effect in Q3DBars.
- */
-void QDataItem::setPosition(const QPointF &position)
-{
- d_ptr->m_position = position;
-}
-
-/*!
- * \overload QDataItem::position
- *
- * \a position A QPoint position for the data item.
- *
- * Sets position for the data item. Has no effect in Q3DBars.
- */
-void QDataItem::setPosition(const QPoint &position)
-{
- d_ptr->m_position = (QPointF)position;
-}
-
-QPointF QDataItem::position()
-{
- return d_ptr->m_position;
-}
-
-QDataItemPrivate::QDataItemPrivate(QDataItem *q, float value, const QString &label)
- : q_ptr(q),
- m_value(value),
- m_labelString(label),
- m_prependLabel(false),
- m_translation(QVector3D(0, 0, 0)),
- m_label(LabelItem()),
- m_selectionLabel(LabelItem())
-{
-}
-
-QDataItemPrivate::~QDataItemPrivate()
-{
-}
-
-void QDataItemPrivate::setTranslation(const QVector3D &translation)
-{
- m_translation = translation;
-}
-
-QVector3D QDataItemPrivate::translation()
-{
- return m_translation;
-}
-
-float QDataItemPrivate::value()
-{
- return m_value;
-}
-
-QString QDataItemPrivate::valueStr()
-{
- QString strVal;
- QString numStr;
- numStr.setNum(m_value);
- if (m_prependLabel) {
- strVal.append(m_labelString);
- strVal.append(QStringLiteral(" "));
- strVal.append(numStr);
- } else {
- strVal.append(numStr);
- strVal.append(m_labelString);
- }
- return strVal;
-}
-
-void QDataItemPrivate::setLabel(const LabelItem &label)
-{
- m_label = label;
-}
-
-LabelItem QDataItemPrivate::label()
-{
- return m_label;
-}
-
-void QDataItemPrivate::setSelectionLabel(const LabelItem &label)
-{
- m_selectionLabel = label;
-}
-
-LabelItem QDataItemPrivate::selectionLabel()
-{
- return m_selectionLabel;
-}
-
-QPointF QDataItemPrivate::position()
-{
- return m_position;
-}
-
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/engine/qdataitem.h b/src/datavis3d/engine/qdataitem.h
deleted file mode 100644
index 7c8302f4..00000000
--- a/src/datavis3d/engine/qdataitem.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtDataVis3D module.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** 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 Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDATAITEM_H
-#define QDATAITEM_H
-
-#include "QtDataVis3D/qdatavis3dglobal.h"
-#include <QScopedPointer>
-#include <QString>
-#include <QObject>
-#include <QPointF>
-
-class QPoint;
-
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
-
-class QDataItemPrivate;
-
-class QTENTERPRISE_DATAVIS3D_EXPORT QDataItem : public QObject
-{
- Q_OBJECT
- Q_PROPERTY(QString label READ label WRITE setLabel)
- Q_PROPERTY(float value READ value WRITE setValue)
- Q_PROPERTY(int value READ value WRITE setValue)
- Q_PROPERTY(QPointF position READ position WRITE setPosition)
-
-public:
- explicit QDataItem(float value = 0.0f, const QString &label = QString());
- ~QDataItem();
-
- // TODO: Provide a Q_INVOKABLE version of this, or move prepend to it's own property.
- void setLabel(const QString &label, bool prepend = false); // label for value, unit for example
- QString label();
- void setValue(float value);
- void setValue(int value);
- float value();
- // Has no effect in Q3DBars
- void setPosition(const QPointF &position);
- void setPosition(const QPoint &position);
- QPointF position();
-
-private:
- QScopedPointer<QDataItemPrivate> d_ptr;
- friend class Bars3dShared;
- friend class Q3DMaps;
- friend class Q3DMapsPrivate;
- friend class QDataRowPrivate;
- friend class Drawer;
-};
-
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
-
-#endif
diff --git a/src/datavis3d/engine/qdataitem_p.h b/src/datavis3d/engine/qdataitem_p.h
deleted file mode 100644
index 6b8a9b83..00000000
--- a/src/datavis3d/engine/qdataitem_p.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtDataVis3D module.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** 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 Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-
-#ifndef QDATAITEM_P_H
-#define QDATAITEM_P_H
-
-#include "qdatavis3dglobal.h"
-#include "qdataitem.h"
-#include "labelitem_p.h"
-
-#include <QOpenGLFunctions>
-#include <QSize>
-#include <QString>
-#include <QVector3D>
-
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
-
-class QDataItemPrivate
-{
- public:
- explicit QDataItemPrivate(QDataItem *q, float value = 0.0f,
- const QString &label = QString());
- ~QDataItemPrivate();
-
- // Position in 3D scene
- void setTranslation(const QVector3D &translation);
- QVector3D translation();
- // Value of bar
- float value();
- // Value and label appended into a string. If label has prepend -flag set, append label and value
- QString valueStr();
- // Label item (containing valueStr as texture)
- void setLabel(const LabelItem &label);
- LabelItem label();
- // Selection label item (containing specialar selection texture, if mode is activated)
- void setSelectionLabel(const LabelItem &label);
- LabelItem selectionLabel();
- QPointF position();
-
- private:
- QDataItem *q_ptr;
- float m_value;
- QString m_labelString;
- bool m_prependLabel;
- QVector3D m_translation;
- LabelItem m_label;
- LabelItem m_selectionLabel;
- QPointF m_position;
- friend class QDataItem;
-};
-
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
-
-#endif
diff --git a/src/datavis3d/engine/qdatarow.cpp b/src/datavis3d/engine/qdatarow.cpp
deleted file mode 100644
index 6bdd6d14..00000000
--- a/src/datavis3d/engine/qdatarow.cpp
+++ /dev/null
@@ -1,187 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtDataVis3D module.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** 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 Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qdatarow.h"
-#include "qdatarow_p.h"
-#include "qdataitem.h"
-#include "qdataitem_p.h"
-
-#include <QString>
-
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
-
-/*!
- * \class QDataRow
- * \inmodule QtDataVis3D
- * \brief The QDataRow class provides a container for data items to be added to graphs.
- * \since 1.0.0
- *
- * A QDataRow is a container for all data to be added to a Q3DMaps instance, or a single row to
- * be added to a QDataSet. It holds instances of QDataItem and has no knowledge of possible
- * sample space sizes set for a Q3DBars instance. The ownership of QDataItem added is transferred
- * to QDataRow.
- *
- * \sa QDataItem, QDataSet, {Qt Data Visualization 3D C++ Classes}
- */
-
-/*!
- * \a label A QString label for the row.
- *
- * Constructs QDataRow.
- */
-QDataRow::QDataRow(const QString &label)
- : d_ptr(new QDataRowPrivate(this, label))
-{
-}
-
-/*!
- * Destroys QDataRow and all instances of QDataItem it may hold.
- */
-QDataRow::~QDataRow()
-{
-}
-
-/*!
- * \property QDataRow::label
- *
- * \a label A QString label for the row.
- *
- * Sets a label for the row.
- */
-void QDataRow::setLabel(const QString &label)
-{
- d_ptr->m_label = label;
-}
-
-QString QDataRow::label()
-{
- return d_ptr->m_label;
-}
-
-/*!
- * \a item A QDataItem instance.
- *
- * Adds a QDataItem to the QDataRow. Ownership of QDataItem is transferred to QDataRow.
- */
-void QDataRow::addItem(QDataItem *item)
-{
- d_ptr->m_row.prepend(item);
-}
-
-QDataRowPrivate::QDataRowPrivate(QDataRow *q, const QString &label)
- : q_ptr(q),
- m_label(label),
- m_labelItem(LabelItem())
-{
-}
-
-QDataRowPrivate::~QDataRowPrivate()
-{
- for (int itemCount = 0; itemCount < m_row.size(); itemCount++)
- delete m_row.at(itemCount);
- m_row.clear();
-}
-
-QVector<QDataItem*> QDataRowPrivate::row()
-{
- return m_row;
-}
-
-void QDataRowPrivate::clear()
-{
- m_row.clear();
-}
-
-QDataItem *QDataRowPrivate::getItem(int itemIndex)
-{
- QDataItem *item = NULL;
- if (m_row.size() > itemIndex)
- item = m_row.at(itemIndex);
- return item;
-}
-
-void QDataRowPrivate::verifySize(int size)
-{
- if (size > m_row.size()) {
- // QVector's resize doesn't delete data contained in it
- // Delete contents of items to be removed
- int nbrToBeRemoved = m_row.size() - size;
- for (int itemCount = 0; itemCount < nbrToBeRemoved; itemCount++) {
- int itemToBeRemoved = m_row.size() - itemCount - 1; // -1 to compensate index 0
- delete m_row.at(itemToBeRemoved);
- }
- // Resize vector
- m_row.resize(size);
- } else if (size < m_row.size()) {
- qCritical("Check your sample space size! Your row is too short.");
- }
-}
-
-QPair<GLfloat, GLfloat> QDataRowPrivate::limitValues()
-{
- QPair<GLfloat, GLfloat> limits = qMakePair(100.0f, -100.0f);
- for (int i = 0; i < m_row.size(); i++) {
- QDataItem *item = m_row.at(i);
- float itemValue = item->d_ptr->value();
- if (limits.second < itemValue)
- limits.second = itemValue;
- if (limits.first > itemValue)
- limits.first = itemValue;
- }
- return limits;
-}
-
-QString QDataRowPrivate::label()
-{
- return m_label;
-}
-
-void QDataRowPrivate::setLabelItem(const LabelItem &item)
-{
- m_labelItem = item;
-}
-
-LabelItem QDataRowPrivate::labelItem()
-{
- return m_labelItem;
-}
-
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/engine/qdatarow.h b/src/datavis3d/engine/qdatarow.h
deleted file mode 100644
index 72fa5f55..00000000
--- a/src/datavis3d/engine/qdatarow.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtDataVis3D module.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** 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 Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDATAROW_H
-#define QDATAROW_H
-
-#include "QtDataVis3D/qdatavis3dglobal.h"
-#include <QScopedPointer>
-#include <QString>
-#include <QObject>
-
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
-
-class QDataRowPrivate;
-class QDataItem;
-
-class QTENTERPRISE_DATAVIS3D_EXPORT QDataRow : public QObject
-{
- Q_OBJECT
- Q_PROPERTY(QString label READ label WRITE setLabel)
-
-public:
- explicit QDataRow(const QString &label = QString());
- ~QDataRow();
-
- void setLabel(const QString &label); // label for value, unit for example
- QString label();
- Q_INVOKABLE void addItem(QDataItem *item);
-
-private:
- QScopedPointer<QDataRowPrivate> d_ptr;
- friend class Bars3dShared;
- friend class Q3DMaps;
- friend class Q3DMapsPrivate;
- friend class QDataSetPrivate;
-};
-
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
-
-#endif
diff --git a/src/datavis3d/engine/qdatarow_p.h b/src/datavis3d/engine/qdatarow_p.h
deleted file mode 100644
index d563fe8a..00000000
--- a/src/datavis3d/engine/qdatarow_p.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtDataVis3D module.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** 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 Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-
-#ifndef QDATAROW_P_H
-#define QDATAROW_P_H
-
-#include "qdatavis3dglobal.h"
-#include "qdatarow.h"
-#include "labelitem_p.h"
-#include <QVector>
-#include <QString>
-
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
-
-class QDataItem;
-
-class QDataRowPrivate
-{
-public:
- explicit QDataRowPrivate(QDataRow *q, const QString &label = QString());
- ~QDataRowPrivate();
-
- QVector<QDataItem*> row();
- // Clears vector, doesn't delete items
- void clear();
- QDataItem *getItem(int itemIndex);
- void verifySize(int size);
- QPair<GLfloat, GLfloat> limitValues();
- QString label();
- void setLabelItem(const LabelItem &item);
- LabelItem labelItem();
-
-private:
- QDataRow *q_ptr;
- QVector<QDataItem*> m_row;
- QString m_label;
- LabelItem m_labelItem;
- friend class QDataRow;
-};
-
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
-
-#endif
diff --git a/src/datavis3d/engine/qdataset.cpp b/src/datavis3d/engine/qdataset.cpp
deleted file mode 100644
index 6fd59baf..00000000
--- a/src/datavis3d/engine/qdataset.cpp
+++ /dev/null
@@ -1,307 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtDataVis3D module.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** 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 Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qdataset.h"
-#include "qdataset_p.h"
-#include "qdatarow.h"
-#include "qdatarow_p.h"
-
-#include <QPoint>
-#include <QString>
-
-//#include <QDebug>
-
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
-
-const QString empty;
-
-/*!
- * \class QDataSet
- * \inmodule QtDataVis3D
- * \brief The QDataSet class provides a container for data rows to be added to graphs.
- * \since 1.0.0
- *
- * A QDataSet is a container for data to be added into a Q3DBars instance. It holds instances of
- * QDataRow and has no knowledge of sample space size set for Q3DBars. The ownership of QDataRow
- * added is transferred to QDataSet.
- *
- * \sa QDataItem, QDataRow, {Qt Data Visualization 3D C++ Classes}
- */
-
-/*!
- * Constructs QDataSet.
- */
-QDataSet::QDataSet()
- : d_ptr(new QDataSetPrivate(this))
-{
-}
-
-/*!
- * Destroys QDataSet, including all QDataRow instances it may hold.
- */
-QDataSet::~QDataSet()
-{
-}
-
-/*!
- * \a xAxis A QString label for x axis.
- *
- * \a zAxis A QString label for z axis.
- *
- * \a yAxis A QString label for y axis.
- *
- * \a labelsRow A QVector of QStrings, one for each row.
- *
- * \a labelsColumn A QVector of QStrings, one for each column.
- *
- * Sets labels for the QDataSet.
- */
-void QDataSet::setLabels(const QString &xAxis,
- const QString &zAxis,
- const QString &yAxis,
- const QVector<QString> &labelsRow,
- const QVector<QString> &labelsColumn)
-{
- // skip empty labels, keep the previous ones
- if (xAxis != empty && d_ptr->m_xAxis != xAxis) {
- d_ptr->m_xAxis = xAxis;
- // Generate axis label texture
- if (d_ptr->m_drawer)
- d_ptr->m_drawer->generateLabelItem(&d_ptr->m_xAxisItem, xAxis);
- }
- if (zAxis != empty && d_ptr->m_zAxis != zAxis) {
- d_ptr->m_zAxis = zAxis;
- // Generate axis label texture
- if (d_ptr->m_drawer)
- d_ptr->m_drawer->generateLabelItem(&d_ptr->m_zAxisItem, zAxis);
- }
- if (yAxis != empty && d_ptr->m_yAxis != yAxis) {
- d_ptr->m_yAxis = yAxis;
- // Generate axis label texture
- if (d_ptr->m_drawer)
- d_ptr->m_drawer->generateLabelItem(&d_ptr->m_yAxisItem, yAxis);
- }
- d_ptr->m_labelsRow = labelsRow;
- d_ptr->m_labelsColumn = labelsColumn;
- // Generate row and column label textures
- if (d_ptr->m_drawer) {
- for (int itemCount = 0; itemCount < labelsColumn.size(); itemCount++) {
- d_ptr->m_labelItemsColumn.append(LabelItem());
- d_ptr->m_drawer->generateLabelItem(&d_ptr->m_labelItemsColumn[itemCount],
- labelsColumn.at(itemCount));
- }
- for (int itemCount = 0; itemCount < labelsRow.size(); itemCount++) {
- d_ptr->m_labelItemsRow.append(LabelItem());
- d_ptr->m_drawer->generateLabelItem(&d_ptr->m_labelItemsRow[itemCount],
- labelsRow.at(itemCount));
- }
- }
-}
-
-/*!
- * \a row A QDataRow instance.
- *
- * Adds a QDataRow instance to QDataSet. Ownership of the QDataRow instance is transferred to
- * QDataSet.
- */
-void QDataSet::addRow(QDataRow *row)
-{
- d_ptr->m_set.prepend(row);
-}
-
-QDataSetPrivate::QDataSetPrivate(QDataSet *q)
- : q_ptr(q),
- m_set(QVector<QDataRow*>()),
- m_xAxis(QString()),
- m_zAxis(QString()),
- m_yAxis(QString()),
- m_labelsRow(QVector<QString>()),
- m_labelsColumn(QVector<QString>()),
- m_xAxisItem(LabelItem()),
- m_zAxisItem(LabelItem()),
- m_yAxisItem(LabelItem()),
- m_labelItemsRow(QVector<LabelItem>()),
- m_labelItemsColumn(QVector<LabelItem>()),
- m_drawer(0)
-{
-}
-
-QDataSetPrivate::~QDataSetPrivate()
-{
- for (int itemCount = 0; itemCount < m_set.size(); itemCount++)
- delete m_set.at(itemCount);
- m_set.clear();
- // Delete axis textures
- GLuint textureid = m_xAxisItem.textureId();
- if (textureid)
- glDeleteTextures(1, &textureid);
- textureid = m_zAxisItem.textureId();
- if (textureid)
- glDeleteTextures(1, &textureid);
- textureid = m_yAxisItem.textureId();
- if (textureid)
- glDeleteTextures(1, &textureid);
- // Delete row and column textures
- for (int itemCount = 0; itemCount < m_labelItemsColumn.size(); itemCount++) {
- LabelItem item = m_labelItemsColumn.at(itemCount);
- textureid = item.textureId();
- if (textureid)
- glDeleteTextures(1, &textureid);
- }
- for (int itemCount = 0; itemCount < m_labelItemsRow.size(); itemCount++) {
- LabelItem item = m_labelItemsRow.at(itemCount);
- textureid = item.textureId();
- if (textureid)
- glDeleteTextures(1, &textureid);
- }
-}
-
-void QDataSetPrivate::setDrawer(Drawer *drawer)
-{
- m_drawer = drawer;
- connect(m_drawer, SIGNAL(drawerChanged()), this, SLOT(updateTextures()));
- updateTextures();
-}
-
-QVector<QDataRow*> QDataSetPrivate::set()
-{
- return m_set;
-}
-
-QDataRow *QDataSetPrivate::getRow(int rowIndex)
-{
- QDataRow *row = NULL;
- if (m_set.size() > rowIndex)
- row = m_set.at(rowIndex);
- return row;
-}
-
-QVector<QString> QDataSetPrivate::rowLabels()
-{
- return m_labelsRow;
-}
-
-QVector<QString> QDataSetPrivate::columnLabels()
-{
- return m_labelsColumn;
-}
-
-QVector<LabelItem> QDataSetPrivate::rowLabelItems()
-{
- return m_labelItemsRow;
-}
-
-QVector<LabelItem> QDataSetPrivate::columnLabelItems()
-{
- return m_labelItemsColumn;
-}
-
-void QDataSetPrivate::axisLabels(QString *xAxis, QString *zAxis, QString *yAxis)
-{
- *xAxis = m_xAxis;
- *zAxis = m_zAxis;
- *yAxis = m_yAxis;
-}
-
-void QDataSetPrivate::axisLabelItems(LabelItem *xAxisItem, LabelItem *zAxisItem,
- LabelItem *yAxisItem)
-{
- *xAxisItem = m_xAxisItem;
- *zAxisItem = m_zAxisItem;
- *yAxisItem = m_yAxisItem;
-}
-
-void QDataSetPrivate::verifySize(int colSize, int rowSize)
-{
- // First verify columns
- // QVector's resize doesn't delete data contained in it
- // Delete contents of rows to be removed
- if (colSize < m_set.size()) {
- int nbrToBeRemoved = m_set.size() - colSize;
- for (int rowCount = 0; rowCount < nbrToBeRemoved; rowCount++) {
- int rowToBeRemoved = m_set.size() - rowCount - 1; // -1 to compensate index 0
- delete m_set.at(rowToBeRemoved);
- }
- // Resize vector
- m_set.resize(colSize);
- }
- // Then verify each row left
- if (rowSize) {
- for (int i = 0; i < m_set.size(); i++)
- m_set.at(i)->d_ptr->verifySize(rowSize);
- }
-}
-
-QPair<GLfloat, GLfloat> QDataSetPrivate::limitValues()
-{
- QPair<GLfloat, GLfloat> limits = qMakePair(100.0f, -100.0f);
- QPair<GLfloat, GLfloat> rowLimits;
- for (int i = 0; i < m_set.size(); i++) {
- rowLimits = m_set.at(i)->d_ptr->limitValues();
- if (limits.second < rowLimits.second)
- limits.second = rowLimits.second;
- if (limits.first > rowLimits.first)
- limits.first = rowLimits.first;
- }
- return limits;
-}
-
-void QDataSetPrivate::updateTextures()
-{
- if (m_xAxis != empty)
- m_drawer->generateLabelItem(&m_xAxisItem, m_xAxis);
- if (m_zAxis != empty)
- m_drawer->generateLabelItem(&m_zAxisItem, m_zAxis);
- if (m_yAxis != empty)
- m_drawer->generateLabelItem(&m_yAxisItem, m_yAxis);
- for (int itemCount = 0; itemCount < m_labelsColumn.size(); itemCount++) {
- if (m_labelItemsColumn.size() < itemCount + 1)
- m_labelItemsColumn.append(LabelItem());
- m_drawer->generateLabelItem(&m_labelItemsColumn[itemCount], m_labelsColumn.at(itemCount));
- }
- for (int itemCount = 0; itemCount < m_labelsRow.size(); itemCount++) {
- if (m_labelItemsRow.size() < itemCount + 1)
- m_labelItemsRow.append(LabelItem());
- m_drawer->generateLabelItem(&m_labelItemsRow[itemCount], m_labelsRow.at(itemCount));
- }
-}
-
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/engine/qdataset.h b/src/datavis3d/engine/qdataset.h
deleted file mode 100644
index e645bc16..00000000
--- a/src/datavis3d/engine/qdataset.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtDataVis3D module.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** 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 Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QDATASET_H
-#define QDATASET_H
-
-#include "QtDataVis3D/qdatavis3dglobal.h"
-#include "qdataitem.h"
-#include "qdatarow.h"
-
-#include <QScopedPointer>
-#include <QVector>
-#include <QString>
-
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
-
-class QDataSetPrivate;
-
-class QTENTERPRISE_DATAVIS3D_EXPORT QDataSet : public QObject
-{
- Q_OBJECT
-
-public:
- explicit QDataSet();
- ~QDataSet();
-
- Q_INVOKABLE void setLabels(const QString &xAxis = QString(),
- const QString &zAxis = QString(),
- const QString &yAxis = QString(),
- const QVector<QString> &labelsRow = QVector<QString>(),
- const QVector<QString> &labelsColumn = QVector<QString>());
- Q_INVOKABLE void addRow(QDataRow *row);
-
-private:
- QScopedPointer<QDataSetPrivate> d_ptr;
- friend class Bars3dShared;
- friend class Q3DMaps;
- friend class Q3DMapsPrivate;
-};
-
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
-
-#endif
diff --git a/src/datavis3d/engine/qdataset_p.h b/src/datavis3d/engine/qdataset_p.h
deleted file mode 100644
index a259aa9a..00000000
--- a/src/datavis3d/engine/qdataset_p.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtDataVis3D module.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** 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 Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-
-#ifndef QDATASET_P_H
-#define QDATASET_P_H
-
-#include "qdatavis3dglobal.h"
-#include "qdataset.h"
-#include "drawer_p.h"
-#include "labelitem_p.h"
-#include <QVector>
-#include <QString>
-
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
-
-class QDataSetPrivate : public QObject
-{
- Q_OBJECT
-
-public:
- explicit QDataSetPrivate(QDataSet *q);
- ~QDataSetPrivate();
-
- void setDrawer(Drawer *drawer);
- QVector<QDataRow*> set();
- QDataRow *getRow(int rowIndex);
- QVector<QString> rowLabels();
- QVector<QString> columnLabels();
- QVector<LabelItem> rowLabelItems();
- QVector<LabelItem> columnLabelItems();
- void axisLabels(QString *xAxis, QString *zAxis, QString *yAxis);
- void axisLabelItems(LabelItem *xAxisItem, LabelItem *zAxisItem, LabelItem *yAxisItem);
- void verifySize(int colSize, int rowSize = 0); // If rowSize is 0, don't verify rows
- // first = min, second = max
- QPair<GLfloat, GLfloat> limitValues();
-
-public Q_SLOTS:
- void updateTextures();
-
-private:
- QDataSet *q_ptr;
- QVector<QDataRow*> m_set;
- QString m_xAxis;
- QString m_zAxis;
- QString m_yAxis;
- QVector<QString> m_labelsRow;
- QVector<QString> m_labelsColumn;
- LabelItem m_xAxisItem;
- LabelItem m_zAxisItem;
- LabelItem m_yAxisItem;
- QVector<LabelItem> m_labelItemsRow;
- QVector<LabelItem> m_labelItemsColumn;
- Drawer *m_drawer;
- friend class QDataSet;
-};
-
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
-
-#endif
diff --git a/src/datavis3d/engine/scatter3dcontroller.cpp b/src/datavis3d/engine/scatter3dcontroller.cpp
new file mode 100644
index 00000000..0d93b06f
--- /dev/null
+++ b/src/datavis3d/engine/scatter3dcontroller.cpp
@@ -0,0 +1,365 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "scatter3dcontroller_p.h"
+#include "scatter3drenderer_p.h"
+#include "camerahelper_p.h"
+#include "qabstractaxis_p.h"
+#include "qvalueaxis_p.h"
+#include "qscatterdataproxy_p.h"
+
+#include <QMatrix4x4>
+#include <QMouseEvent>
+#include <qmath.h>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+Scatter3DController::Scatter3DController(QRect boundRect)
+ : Abstract3DController(boundRect),
+ m_mouseState(MouseNone),
+ m_mousePos(QPoint(0, 0)),
+ m_isSlicingActivated(false),
+ m_renderer(0),
+ m_data(0)
+{
+ // Default axes
+ setAxisX(new QValueAxis());
+ setAxisY(new QValueAxis());
+ setAxisZ(new QValueAxis());
+
+ setObjectType(QDataVis::Spheres, false); // default object type
+
+ setDataProxy(new QScatterDataProxy);
+}
+
+Scatter3DController::~Scatter3DController()
+{
+ delete m_data;
+}
+
+void Scatter3DController::initializeOpenGL()
+{
+ // Initialization is called multiple times when Qt Quick components are used
+ if (isInitialized())
+ return;
+
+ m_renderer = new Scatter3DRenderer(this);
+ setRenderer(m_renderer);
+}
+
+void Scatter3DController::synchDataToRenderer()
+{
+ Abstract3DController::synchDataToRenderer();
+
+ if (!isInitialized())
+ return;
+
+ // Notify changes to renderer
+ if (m_changeTracker.slicingActiveChanged) {
+ // TODO: Add notification.
+ m_changeTracker.slicingActiveChanged = false;
+ }
+
+ if (m_isDataDirty) {
+ m_renderer->updateDataModel(m_data);
+ m_isDataDirty = false;
+ }
+}
+
+QMatrix4x4 Scatter3DController::calculateViewMatrix(int zoom, int viewPortWidth,
+ int viewPortHeight, bool showUnder)
+{
+ return m_cameraHelper->calculateViewMatrix(m_mousePos,
+ zoom,
+ viewPortWidth,
+ viewPortHeight,
+ showUnder);
+}
+
+bool Scatter3DController::isSlicingActive()
+{
+ return m_isSlicingActivated;
+}
+
+void Scatter3DController::setSlicingActive(bool isSlicing)
+{
+ m_isSlicingActivated = isSlicing;
+
+ m_changeTracker.slicingActiveChanged = true;
+ emit slicingActiveChanged(m_isSlicingActivated);
+}
+
+Scatter3DController::MouseState Scatter3DController::mouseState()
+{
+ return m_mouseState;
+}
+
+#if defined(Q_OS_ANDROID)
+void Scatter3DController::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ if (!m_isSlicingActivated) {
+ m_mouseState = Scatter3DController::MouseOnScene;
+ // update mouse positions to prevent jumping when releasing or repressing a button
+ m_mousePos = event->pos();
+ }
+}
+
+void Scatter3DController::touchEvent(QTouchEvent *event)
+{
+ static int prevDistance = 0;
+
+ QList<QTouchEvent::TouchPoint> points;
+ points = event->touchPoints();
+
+ if (points.count() == 2) {
+ m_mouseState = Scatter3DController::MouseOnPinch;
+
+ QPointF distance = points.at(0).pos() - points.at(1).pos();
+ int newDistance = distance.manhattanLength();
+ int zoomRate = 1;
+ int zoomLevel = m_zoomLevel;
+ if (zoomLevel > 100)
+ zoomRate = 5;
+ if (newDistance > prevDistance)
+ zoomLevel += zoomRate;
+ else
+ zoomLevel -= zoomRate;
+ if (zoomLevel > 500)
+ zoomLevel = 500;
+ else if (zoomLevel < 10)
+ zoomLevel = 10;
+ setZoomLevel(zoomLevel);
+ prevDistance = newDistance;
+ //qDebug() << "distance" << distance.manhattanLength();
+ }
+}
+#endif
+
+void Scatter3DController::mousePressEvent(QMouseEvent *event, const QPoint &mousePos)
+{
+ QRect mainViewPort = m_renderer->mainViewPort();
+ if (Qt::LeftButton == event->button()) {
+ if (m_isSlicingActivated) {
+ if (mousePos.x() <= mainViewPort.width()
+ && mousePos.y() <= mainViewPort.height()) {
+ m_mouseState = Scatter3DController::MouseOnOverview;
+ //qDebug() << "Mouse pressed on overview";
+ } else {
+ m_mouseState = Scatter3DController::MouseOnZoom;
+ //qDebug() << "Mouse pressed on zoom";
+ }
+ } else {
+#if !defined(Q_OS_ANDROID)
+ m_mouseState = Scatter3DController::MouseOnScene;
+#else
+ m_mouseState = Scatter3DController::MouseRotating;
+#endif
+ // update mouse positions to prevent jumping when releasing or repressing a button
+ m_mousePos = mousePos;
+ //qDebug() << "Mouse pressed on scene";
+ }
+ } else if (Qt::MiddleButton == event->button()) {
+ // reset rotations
+ m_mousePos = QPoint(0, 0);
+ } else if (Qt::RightButton == event->button()) {
+#if !defined(Q_OS_ANDROID)
+ m_mouseState = Scatter3DController::MouseRotating;
+#else
+ m_mouseState = Scatter3DController::MouseOnScene;
+#endif
+ // update mouse positions to prevent jumping when releasing or repressing a button
+ m_mousePos = mousePos;
+ }
+ m_cameraHelper->updateMousePos(m_mousePos);
+}
+
+void Scatter3DController::mouseReleaseEvent(QMouseEvent *event, const QPoint &mousePos)
+{
+ Q_UNUSED(event);
+ if (Scatter3DController::MouseRotating == m_mouseState) {
+ // update mouse positions to prevent jumping when releasing or repressing a button
+ m_mousePos = mousePos;
+ m_cameraHelper->updateMousePos(mousePos);
+ }
+ m_mouseState = Scatter3DController::MouseNone;
+}
+
+void Scatter3DController::mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos)
+{
+ Q_UNUSED(event);
+ if (Scatter3DController::MouseRotating == m_mouseState)
+ m_mousePos = mousePos;
+}
+
+void Scatter3DController::wheelEvent(QWheelEvent *event)
+{
+ int zoomLevel = m_zoomLevel;
+ if (zoomLevel > 100)
+ zoomLevel += event->angleDelta().y() / 12;
+ else if (zoomLevel > 50)
+ zoomLevel += event->angleDelta().y() / 60;
+ else
+ zoomLevel += event->angleDelta().y() / 120;
+ if (zoomLevel > 500)
+ zoomLevel = 500;
+ else if (zoomLevel < 10)
+ zoomLevel = 10;
+
+ setZoomLevel(zoomLevel);
+}
+
+void Scatter3DController::setDataProxy(QScatterDataProxy *proxy)
+{
+ delete m_data;
+ m_data = proxy;
+
+ QObject::connect(m_data, &QScatterDataProxy::arrayReset,
+ this, &Scatter3DController::handleArrayReset);
+ QObject::connect(m_data, &QScatterDataProxy::itemsAdded,
+ this, &Scatter3DController::handleItemsAdded);
+ QObject::connect(m_data, &QScatterDataProxy::itemsChanged,
+ this, &Scatter3DController::handleItemsChanged);
+ QObject::connect(m_data, &QScatterDataProxy::itemsRemoved,
+ this, &Scatter3DController::handleItemsRemoved);
+ QObject::connect(m_data, &QScatterDataProxy::itemsInserted,
+ this, &Scatter3DController::handleItemsInserted);
+
+ adjustValueAxisRange();
+ m_isDataDirty = true;
+}
+
+QScatterDataProxy *Scatter3DController::dataProxy()
+{
+ return m_data;
+}
+
+void Scatter3DController::handleArrayReset()
+{
+ setSlicingActive(false);
+ adjustValueAxisRange();
+ m_isDataDirty = true;
+}
+
+void Scatter3DController::handleItemsAdded(int startIndex, int count)
+{
+ Q_UNUSED(startIndex)
+ Q_UNUSED(count)
+ // TODO should dirty only affected values?
+ adjustValueAxisRange();
+ m_isDataDirty = true;
+}
+
+void Scatter3DController::handleItemsChanged(int startIndex, int count)
+{
+ Q_UNUSED(startIndex)
+ Q_UNUSED(count)
+ // TODO should dirty only affected values?
+ adjustValueAxisRange();
+ m_isDataDirty = true;
+}
+
+void Scatter3DController::handleItemsRemoved(int startIndex, int count)
+{
+ Q_UNUSED(startIndex)
+ Q_UNUSED(count)
+ // TODO should dirty only affected values?
+ adjustValueAxisRange();
+ m_isDataDirty = true;
+}
+
+void Scatter3DController::handleItemsInserted(int startIndex, int count)
+{
+ Q_UNUSED(startIndex)
+ Q_UNUSED(count)
+ // TODO should dirty only affected values?
+ adjustValueAxisRange();
+ m_isDataDirty = true;
+}
+
+void Scatter3DController::handleAxisAutoAdjustRangeChangedInOrientation(
+ QAbstractAxis::AxisOrientation orientation, bool autoAdjust)
+{
+ Q_UNUSED(orientation)
+ Q_UNUSED(autoAdjust)
+ adjustValueAxisRange();
+}
+
+void Scatter3DController::setObjectType(QDataVis::MeshStyle style, bool smooth)
+{
+ QString objFile;
+ if (style == QDataVis::Spheres) {
+ if (smooth)
+ objFile = QStringLiteral(":/defaultMeshes/sphereSmooth");
+ else
+ objFile = QStringLiteral(":/defaultMeshes/sphere");
+ } else {
+ if (smooth)
+ objFile = QStringLiteral(":/defaultMeshes/dotSmooth");
+ else
+ objFile = QStringLiteral(":/defaultMeshes/dot");
+ }
+ Abstract3DController::setMeshFileName(objFile);
+}
+
+void Scatter3DController::setSelectionMode(QDataVis::SelectionMode mode)
+{
+ if (mode > QDataVis::ModeItem) {
+ qWarning("Unsupported selection mode.");
+ return;
+ }
+ // Disable zoom if selection mode changes
+ setSlicingActive(false);
+ Abstract3DController::setSelectionMode(mode);
+}
+
+QPoint Scatter3DController::mousePosition()
+{
+ return m_mousePos;
+}
+
+void Scatter3DController::adjustValueAxisRange()
+{
+ if (m_data) {
+ QVector3D limits = m_data->dptr()->limitValues();
+ QValueAxis *valueAxis = static_cast<QValueAxis *>(m_axisX);
+ if (valueAxis && valueAxis->isAutoAdjustRange()) {
+ if (limits.x() > 0)
+ valueAxis->dptr()->setRange(-limits.x(), limits.x());
+ else
+ valueAxis->dptr()->setRange(-1.0, 1.0); // Only zero value values in data set, set range to default.
+ }
+
+ valueAxis = static_cast<QValueAxis *>(m_axisY);
+ if (valueAxis && valueAxis->isAutoAdjustRange()) {
+ if (limits.y() > 0)
+ valueAxis->dptr()->setRange(-limits.y(), limits.y());
+ else
+ valueAxis->dptr()->setRange(-1.0, 1.0); // Only zero value values in data set, set range to default.
+ }
+
+ valueAxis = static_cast<QValueAxis *>(m_axisZ);
+ if (valueAxis && valueAxis->isAutoAdjustRange()) {
+ if (limits.z() > 0)
+ valueAxis->dptr()->setRange(-limits.z(), limits.z());
+ else
+ valueAxis->dptr()->setRange(-1.0, 1.0); // Only zero value values in data set, set range to default.
+ }
+ }
+}
+
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/engine/scatter3dcontroller_p.h b/src/datavis3d/engine/scatter3dcontroller_p.h
new file mode 100644
index 00000000..437664b7
--- /dev/null
+++ b/src/datavis3d/engine/scatter3dcontroller_p.h
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Q3DSCATTERCONTROLLER_p_H
+#define Q3DSCATTERCONTROLLER_p_H
+
+#include "datavis3dglobal_p.h"
+#include "abstract3dcontroller_p.h"
+
+//#define DISPLAY_RENDER_SPEED
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class Scatter3DRenderer;
+class QScatterDataProxy;
+
+struct Scatter3DChangeBitField {
+ bool slicingActiveChanged : 1;
+
+ Scatter3DChangeBitField() :
+ slicingActiveChanged(true)
+ {
+ }
+};
+
+class QT_DATAVIS3D_EXPORT Scatter3DController : public Abstract3DController
+{
+ Q_OBJECT
+
+private:
+ Scatter3DChangeBitField m_changeTracker;
+
+ // Interaction
+ MouseState m_mouseState;
+ QPoint m_mousePos;
+ bool m_isSlicingActivated;
+
+ // Rendering
+ Scatter3DRenderer *m_renderer;
+ QScatterDataProxy *m_data;
+
+public:
+ explicit Scatter3DController(QRect rect);
+ ~Scatter3DController();
+
+ void initializeOpenGL();
+
+ MouseState mouseState();
+ QPoint mousePosition();
+
+ bool isSlicingActive();
+ void setSlicingActive(bool isSlicing);
+
+ QMatrix4x4 calculateViewMatrix(int zoom, int viewPortWidth, int viewPortHeight,
+ bool showUnder = false);
+
+ // Object type
+ void setObjectType(QDataVis::MeshStyle style, bool smooth = false);
+
+ // Change selection mode
+ void setSelectionMode(QDataVis::SelectionMode mode);
+
+#if defined(Q_OS_ANDROID)
+ void mouseDoubleClickEvent(QMouseEvent *event);
+ void touchEvent(QTouchEvent *event);
+#endif
+ void mousePressEvent(QMouseEvent *event, const QPoint &mousePos);
+ void mouseReleaseEvent(QMouseEvent *event, const QPoint &mousePos);
+ void mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos);
+ void wheelEvent(QWheelEvent *event);
+
+ // Sets the data proxy. Assumes ownership of the data proxy. Deletes old proxy.
+ void setDataProxy(QScatterDataProxy *proxy);
+ QScatterDataProxy *dataProxy();
+
+ void synchDataToRenderer();
+
+ virtual void handleAxisAutoAdjustRangeChangedInOrientation(QAbstractAxis::AxisOrientation orientation, bool autoAdjust);
+
+public slots:
+ void handleArrayReset();
+ void handleItemsAdded(int startIndex, int count);
+ void handleItemsChanged(int startIndex, int count);
+ void handleItemsRemoved(int startIndex, int count);
+ void handleItemsInserted(int startIndex, int count);
+
+signals:
+ void slicingActiveChanged(bool isSlicing);
+
+private:
+ void adjustValueAxisRange();
+
+ Q_DISABLE_COPY(Scatter3DController)
+};
+
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/engine/scatter3drenderer.cpp b/src/datavis3d/engine/scatter3drenderer.cpp
new file mode 100644
index 00000000..d8d5da9a
--- /dev/null
+++ b/src/datavis3d/engine/scatter3drenderer.cpp
@@ -0,0 +1,1648 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "scatter3drenderer_p.h"
+#include "scatter3dcontroller_p.h"
+#include "camerahelper_p.h"
+#include "shaderhelper_p.h"
+#include "objecthelper_p.h"
+#include "texturehelper_p.h"
+#include "utils_p.h"
+
+#include <QMatrix4x4>
+#include <QMouseEvent>
+#include <QThread>
+#include <qmath.h>
+#include <QDebug>
+
+// Commenting this draws the shadow map with perspective projection. Otherwise it's drawn in
+// orthographic projection.
+//#define USE_WIDER_SHADOWS
+
+// You can verify that depth buffer drawing works correctly by uncommenting this.
+// You should see the scene from where the light is
+//#define SHOW_DEPTH_TEXTURE_SCENE
+
+#ifdef DISPLAY_RENDER_SPEED
+#include <QTime>
+#endif
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+//#define USE_UNIFORM_SCALING // Scale x and z uniformly, or based on autoscaled values
+
+#define DISPLAY_FULL_DATA_ON_SELECTION // Append selection value text with row and column labels
+
+const GLfloat aspectRatio = 2.0f; // Forced ratio of x and z to y. Dynamic will make it look odd.
+// TODO: Make margin modifiable?
+const GLfloat backgroundMargin = 1.1f; // Margin for background (1.1f = make it 10% larger to avoid items being drawn inside background)
+const GLfloat gridLineWidth = 0.005f;
+static QVector3D selectionSkipColor = QVector3D(255, 255, 255); // Selection texture's background color
+
+Scatter3DRenderer::Scatter3DRenderer(Scatter3DController *controller)
+ : Abstract3DRenderer(controller),
+ m_controller(controller),
+ m_selectedItem(0),
+ m_previouslySelectedItem(0),
+ m_xFlipped(false),
+ m_zFlipped(false),
+ m_yFlipped(false),
+ m_updateLabels(false),
+ m_dotShader(0),
+ m_depthShader(0),
+ m_selectionShader(0),
+ m_backgroundShader(0),
+ m_labelShader(0),
+ m_dotObj(0),
+ m_backgroundObj(0),
+ m_gridLineObj(0),
+ m_labelObj(0),
+ m_bgrTexture(0),
+ m_depthTexture(0),
+ m_selectionTexture(0),
+ m_depthFrameBuffer(0),
+ m_selectionFrameBuffer(0),
+ m_selectionDepthBuffer(0),
+ m_shadowQualityToShader(33.3f),
+ m_heightNormalizer(1.0f),
+ m_scaleFactor(0),
+ m_selection(selectionSkipColor),
+ m_areaSize(QSizeF(0.0f, 0.0f)),
+ m_hasHeightAdjustmentChanged(true),
+ m_dotSizeScale(1.0f)
+ #ifdef DISPLAY_RENDER_SPEED
+ , m_isFirstFrame(true),
+ m_numFrames(0)
+ #endif
+{
+ //qDebug() << __FUNCTION__;
+ m_dummyRenderItem.setRenderer(this);
+ initializeOpenGLFunctions();
+ initializeOpenGL();
+}
+
+Scatter3DRenderer::~Scatter3DRenderer()
+{
+ //qDebug() << __FUNCTION__;
+ m_textureHelper->glDeleteFramebuffers(1, &m_selectionFrameBuffer);
+ m_textureHelper->glDeleteRenderbuffers(1, &m_selectionDepthBuffer);
+ m_textureHelper->deleteTexture(&m_selectionTexture);
+ m_textureHelper->glDeleteFramebuffers(1, &m_depthFrameBuffer);
+ m_textureHelper->deleteTexture(&m_bgrTexture);
+ delete m_dotShader;
+ delete m_depthShader;
+ delete m_selectionShader;
+ delete m_backgroundShader;
+ delete m_dotObj;
+ delete m_backgroundObj;
+ delete m_gridLineObj;
+ delete m_textureHelper;
+}
+
+void Scatter3DRenderer::initializeOpenGL()
+{
+ //qDebug() << __FUNCTION__;
+ m_textureHelper = new TextureHelper();
+ m_drawer->initializeOpenGL();
+
+ // Initialize shaders
+ handleShadowQualityChange();
+
+ initLabelShaders(QStringLiteral(":/shaders/vertexLabel"),
+ QStringLiteral(":/shaders/fragmentLabel"));
+
+#if !defined(QT_OPENGL_ES_2)
+ // Init depth shader (for shadows). Init in any case, easier to handle shadow activation if done via api.
+ initDepthShader();
+#endif
+
+ // Init selection shader
+ initSelectionShader();
+
+ // Load grid line mesh
+ loadGridLineMesh();
+
+ // Load label mesh
+ loadLabelMesh();
+
+ // Set OpenGL features
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_LESS);
+ glEnable(GL_CULL_FACE);
+ glCullFace(GL_BACK);
+
+#if !defined(QT_OPENGL_ES_2)
+ glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
+ glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
+ glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
+#endif
+
+ // Set view port
+ glViewport(m_mainViewPort.x(), m_mainViewPort.y(),
+ m_mainViewPort.width(), m_mainViewPort.height());
+
+ // Resize in case we've missed resize events
+ // Resize calls initSelectionBuffer and initDepthBuffer, so they don't need to be called here
+ handleResize();
+
+ // Load background mesh (we need to be initialized first)
+ loadBackgroundMesh();
+
+ Abstract3DRenderer::initializeOpenGL();
+}
+
+void Scatter3DRenderer::updateDataModel(QScatterDataProxy *dataProxy)
+{
+ const QScatterDataArray &dataArray = *dataProxy->array();
+ calculateSceneScalingFactors();
+ int dataSize = dataArray.size();
+ m_renderItemArray.resize(dataSize);
+ for (int i = 0; i < dataSize ; i++) {
+ qreal value = dataArray.at(i).position().y();
+ m_renderItemArray[i].setValue(value);
+ m_renderItemArray[i].setPosition(dataArray.at(i).position());
+ //m_renderItemArray[i].setHeight(value / m_heightNormalizer);
+ //m_renderItemArray[i].setItemLabel(dataArray.at(i).label());
+ calculateTranslation(m_renderItemArray[i]);
+ m_renderItemArray[i].setRenderer(this);
+ }
+ m_dotSizeScale = (GLfloat)qBound(0.01, (qreal)(2.0f / qSqrt((qreal)dataSize)), 0.1);
+
+ Abstract3DRenderer::updateDataModel(dataProxy);
+}
+
+void Scatter3DRenderer::render(CameraHelper *camera, const GLuint defaultFboHandle)
+{
+ //qDebug() << __FUNCTION__;
+
+#ifdef DISPLAY_RENDER_SPEED
+ // For speed computation
+ if (m_isFirstFrame) {
+ m_lastFrameTime.start();
+ m_isFirstFrame = false;
+ }
+
+ // Measure speed (as milliseconds per frame)
+ m_numFrames++;
+ if (m_lastFrameTime.elapsed() >= 1000) { // print only if last measurement was more than 1s ago
+ qDebug() << qreal(m_lastFrameTime.elapsed()) / qreal(m_numFrames) << "ms/frame (=" << qreal(m_numFrames) << "fps)";
+ m_numFrames = 0;
+ m_lastFrameTime.restart();
+ }
+#endif
+
+ if (defaultFboHandle) {
+ glDepthMask(true);
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_LESS);
+ glEnable(GL_CULL_FACE);
+ glCullFace(GL_BACK);
+ }
+
+ QVector3D clearColor = Utils::vectorFromColor(m_cachedTheme.m_windowColor);
+ glClearColor(clearColor.x(), clearColor.y(), clearColor.z(), 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ if (m_hasHeightAdjustmentChanged) {
+ // Set initial camera position. Also update if height adjustment has changed.
+ camera->setDefaultCameraOrientation(QVector3D(0.0f, 0.0f, 6.0f + zComp),
+ QVector3D(0.0f, 0.0f, zComp),
+ QVector3D(0.0f, 1.0f, 0.0f));
+ m_hasHeightAdjustmentChanged = false;
+ }
+
+ // Draw bars scene
+ drawScene(camera, defaultFboHandle);
+}
+
+void Scatter3DRenderer::drawScene(CameraHelper *camera,
+ const GLuint defaultFboHandle)
+{
+ //qDebug() << __FUNCTION__;
+ GLfloat backgroundRotation = 0;
+
+ // Specify viewport
+ glViewport(m_mainViewPort.x(), m_mainViewPort.y(),
+ m_mainViewPort.width(), m_mainViewPort.height());
+
+ // Set up projection matrix
+ QMatrix4x4 projectionMatrix;
+ projectionMatrix.perspective(45.0f, (GLfloat)m_mainViewPort.width()
+ / (GLfloat)m_mainViewPort.height(), 0.1f, 100.0f);
+
+ // Calculate view matrix
+ QMatrix4x4 viewMatrix = m_controller->calculateViewMatrix(
+ m_cachedZoomLevel * m_autoScaleAdjustment,
+ m_mainViewPort.width(),
+ m_mainViewPort.height(),
+ true);
+
+ // Calculate label flipping
+ if (viewMatrix.row(0).x() > 0)
+ m_zFlipped = false;
+ else
+ m_zFlipped = true;
+ if (viewMatrix.row(0).z() <= 0)
+ m_xFlipped = false;
+ else
+ m_xFlipped = true;
+
+ // Check if we're viewing the scene from below
+ if (viewMatrix.row(2).y() < 0)
+ m_yFlipped = true;
+ else
+ m_yFlipped = false;
+
+ // Calculate background rotation
+ if (!m_zFlipped && !m_xFlipped)
+ backgroundRotation = 270.0f;
+ else if (!m_zFlipped && m_xFlipped)
+ backgroundRotation = 180.0f;
+ else if (m_zFlipped && m_xFlipped)
+ backgroundRotation = 90.0f;
+ else if (m_zFlipped && !m_xFlipped)
+ backgroundRotation = 0.0f;
+
+ // Get light position (rotate light with camera, a bit above it (as set in defaultLightPos))
+ QVector3D lightPos = camera->calculateLightPosition(defaultLightPos);
+
+ // Map adjustment direction to model matrix scaling
+ // TODO: Let's use these for testing the autoscaling of dots based on their number
+ GLfloat heightMultiplier = m_dotSizeScale; //1.0f;
+ GLfloat widthMultiplier = m_dotSizeScale; //1.0f;
+ GLfloat depthMultiplier = m_dotSizeScale; //1.0f;
+ GLfloat heightScaler = 0.0f;
+ GLfloat widthScaler = 0.0f;
+ GLfloat depthScaler = 0.0f;
+ // switch (m_adjustDirection) {
+ // case Q3DMaps::AdjustHeight:
+ // widthMultiplier = 0.0f;
+ // heightMultiplier = 1.0f;
+ // depthMultiplier = 0.0f;
+ // widthScaler = m_barThickness.x() / m_scaleFactor;
+ // heightScaler = 0.0f;
+ // depthScaler = m_barThickness.z() / m_scaleFactor;
+ // break;
+ // case Q3DMaps::AdjustWidth:
+ // widthMultiplier = 1.0f;
+ // heightMultiplier = 0.0f;
+ // depthMultiplier = 0.0f;
+ // widthScaler = 0.0f;
+ // heightScaler = m_barThickness.y() / m_scaleFactor;
+ // depthScaler = m_barThickness.z() / m_scaleFactor;
+ // break;
+ // case Q3DMaps::AdjustDepth:
+ // widthMultiplier = 0.0f;
+ // heightMultiplier = 0.0f;
+ // depthMultiplier = 1.0f;
+ // widthScaler = m_barThickness.x() / m_scaleFactor;
+ // heightScaler = m_barThickness.y() / m_scaleFactor;
+ // depthScaler = 0.0f;
+ // break;
+ // case Q3DMaps::AdjustRadius:
+ // widthMultiplier = 1.0f;
+ // heightMultiplier = 0.0f;
+ // depthMultiplier = 1.0f;
+ // widthScaler = 0.0f;
+ // heightScaler = m_barThickness.y() / m_scaleFactor;
+ // depthScaler = 0.0f;
+ // break;
+ // case Q3DMaps::AdjustAll:
+ // widthMultiplier = 1.0f;
+ // heightMultiplier = 1.0f;
+ // depthMultiplier = 1.0f;
+ // widthScaler = 0.0f;
+ // heightScaler = 0.0f;
+ // depthScaler = 0.0f;
+ // break;
+ // }
+
+ // Introduce regardless of shadow quality to simplify logic
+ QMatrix4x4 depthViewMatrix;
+ QMatrix4x4 depthProjectionMatrix;
+
+#if !defined(QT_OPENGL_ES_2)
+ if (m_cachedShadowQuality > QDataVis::ShadowNone) {
+ // Render scene into a depth texture for using with shadow mapping
+ // Bind depth shader
+ m_depthShader->bind();
+
+ // Set viewport for depth map rendering. Must match texture size. Larger values give smoother shadows.
+ glViewport(m_mainViewPort.x(), m_mainViewPort.y(),
+ m_mainViewPort.width() * m_cachedShadowQuality,
+ m_mainViewPort.height() * m_cachedShadowQuality);
+
+ // Enable drawing to framebuffer
+ glBindFramebuffer(GL_FRAMEBUFFER, m_depthFrameBuffer);
+ glClear(GL_DEPTH_BUFFER_BIT);
+
+ // Set front face culling to reduce self-shadowing issues
+ glCullFace(GL_FRONT);
+
+ // Get the depth view matrix
+ // It may be possible to hack lightPos here if we want to make some tweaks to shadow
+ QVector3D depthLightPos = camera->calculateLightPosition(
+ defaultLightPos, 0.0f, 1.0f / m_autoScaleAdjustment);
+ depthViewMatrix.lookAt(depthLightPos, QVector3D(0.0f, 0.0f, zComp),
+ QVector3D(0.0f, 1.0f, 0.0f));
+ // TODO: Why does depthViewMatrix.column(3).y() goes to zero when we're directly above? That causes the scene to be not drawn from above -> must be fixed
+ //qDebug() << lightPos << depthViewMatrix << depthViewMatrix.column(3);
+ // Set the depth projection matrix
+#ifndef USE_WIDER_SHADOWS
+ // Use this for perspective shadows
+ depthProjectionMatrix.perspective(15.0f, (GLfloat)m_mainViewPort.width()
+ / (GLfloat)m_mainViewPort.height(), 3.0f, 100.0f);
+#else
+ // Use these for orthographic shadows
+ //depthProjectionMatrix.ortho(-aspectRatio * 2.0f, aspectRatio * 2.0f,
+ // -m_heightNormalizer * 2.0f, m_heightNormalizer * 2.0f,
+ // 0.0f, 100.0f);
+ GLfloat testAspectRatio = (GLfloat)m_mainViewPort.width() / (GLfloat)m_mainViewPort.height();
+ depthProjectionMatrix.ortho(-testAspectRatio * 2.0f, testAspectRatio * 2.0f,
+ -m_heightNormalizer * 2.0f, m_heightNormalizer * 2.0f,
+ 0.0f, 100.0f);
+#endif
+ // Draw bars to depth buffer
+ for (int bar = 0; bar < m_renderItemArray.size(); bar++) {
+ const ScatterRenderItem &item = m_renderItemArray.at(bar);
+ if (!item.value())
+ continue;
+
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+
+ modelMatrix.translate(item.translation().x(),
+ item.translation().y(),
+ item.translation().z());
+ modelMatrix.scale(QVector3D(widthMultiplier + widthScaler,
+ heightMultiplier + heightScaler,
+ depthMultiplier + depthScaler));
+ //modelMatrix.scale(QVector3D(widthMultiplier * item.size() + widthScaler,
+ // heightMultiplier * item.size() + heightScaler,
+ // depthMultiplier * item.size() + depthScaler));
+
+ MVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
+
+ m_depthShader->setUniformValue(m_depthShader->MVP(), MVPMatrix);
+
+ // 1st attribute buffer : vertices
+ glEnableVertexAttribArray(m_depthShader->posAtt());
+ glBindBuffer(GL_ARRAY_BUFFER, m_dotObj->vertexBuf());
+ glVertexAttribPointer(m_depthShader->posAtt(), 3, GL_FLOAT, GL_FALSE, 0, (void *)0);
+
+ // Index buffer
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_dotObj->elementBuf());
+
+ // Draw the triangles
+ glDrawElements(GL_TRIANGLES, m_dotObj->indexCount(), GL_UNSIGNED_SHORT, (void *)0);
+
+ // Free buffers
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ glDisableVertexAttribArray(m_depthShader->posAtt());
+ }
+
+ // Disable drawing to framebuffer (= enable drawing to screen)
+ glBindFramebuffer(GL_FRAMEBUFFER, defaultFboHandle);
+
+ // Reset culling to normal
+ glCullFace(GL_BACK);
+
+ // Release depth shader
+ m_depthShader->release();
+
+ // Revert to original viewport
+ glViewport(m_mainViewPort.x(), m_mainViewPort.y(),
+ m_mainViewPort.width(), m_mainViewPort.height());
+
+#if 0 // Use this if you want to see what is being drawn to the framebuffer
+ // You'll also have to comment out GL_COMPARE_R_TO_TEXTURE -line in texturehelper (if using it)
+ m_labelShader->bind();
+ glEnable(GL_TEXTURE_2D);
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 viewmatrix;
+ viewmatrix.lookAt(QVector3D(0.0f, 0.0f, 2.5f + zComp),
+ QVector3D(0.0f, 0.0f, zComp),
+ QVector3D(0.0f, 1.0f, 0.0f));
+ modelMatrix.translate(0.0, 0.0, zComp);
+ QMatrix4x4 MVPMatrix = projectionMatrix * viewmatrix * modelMatrix;
+ m_labelShader->setUniformValue(m_labelShader->MVP(), MVPMatrix);
+ m_drawer->drawObject(m_labelShader, m_labelObj,
+ m_depthTexture);
+ glDisable(GL_TEXTURE_2D);
+ m_labelShader->release();
+#endif
+ }
+#endif
+
+ // Skip selection mode drawing if we have no selection mode
+ if (m_cachedSelectionMode > QDataVis::ModeNone) {
+ // Bind selection shader
+ m_selectionShader->bind();
+
+ // Draw bars to selection buffer
+ glBindFramebuffer(GL_FRAMEBUFFER, m_selectionFrameBuffer);
+ glEnable(GL_DEPTH_TEST); // Needed, otherwise the depth render buffer is not used
+ glClearColor(selectionSkipColor.x() / 255, selectionSkipColor.y() / 255,
+ selectionSkipColor.z() / 255, 1.0f); // Set clear color to white (= skipColor)
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Needed for clearing the frame buffer
+ glDisable(GL_DITHER); // disable dithering, it may affect colors if enabled
+ GLint barIdxRed = 0;
+ GLint barIdxGreen = 0;
+ GLint barIdxBlue = 0;
+ for (int bar = 0; bar < m_renderItemArray.size(); bar++, barIdxRed++) {
+ const ScatterRenderItem &item = m_renderItemArray.at(bar);
+ if (!item.value())
+ continue;
+
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+
+ modelMatrix.translate(item.translation().x(),
+ item.translation().y(),
+ item.translation().z());
+ modelMatrix.scale(QVector3D(widthMultiplier + widthScaler,
+ heightMultiplier + heightScaler,
+ depthMultiplier + depthScaler));
+ //modelMatrix.scale(QVector3D(widthMultiplier * item.size() + widthScaler,
+ // heightMultiplier * item.size() + heightScaler,
+ // depthMultiplier * item.size() + depthScaler));
+
+ MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
+
+ if (barIdxRed > 0 && barIdxRed % 256 == 0) {
+ barIdxRed = 0;
+ barIdxGreen++;
+ }
+ if (barIdxGreen > 0 && barIdxGreen % 256 == 0) {
+ barIdxGreen = 0;
+ barIdxBlue++;
+ }
+ if (barIdxBlue > 255)
+ qFatal("Too many objects");
+
+ QVector3D barColor = QVector3D((GLfloat)barIdxRed / 255.0f,
+ (GLfloat)barIdxGreen / 255.0f,
+ (GLfloat)barIdxBlue / 255.0f);
+
+ m_selectionShader->setUniformValue(m_selectionShader->MVP(), MVPMatrix);
+ m_selectionShader->setUniformValue(m_selectionShader->color(), barColor);
+
+ // 1st attribute buffer : vertices
+ glEnableVertexAttribArray(m_selectionShader->posAtt());
+ glBindBuffer(GL_ARRAY_BUFFER, m_dotObj->vertexBuf());
+ glVertexAttribPointer(m_selectionShader->posAtt(), 3, GL_FLOAT, GL_FALSE, 0, (void *)0);
+
+ // Index buffer
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_dotObj->elementBuf());
+
+ // Draw the triangles
+ glDrawElements(GL_TRIANGLES, m_dotObj->indexCount(), GL_UNSIGNED_SHORT, (void *)0);
+
+ // Free buffers
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ glDisableVertexAttribArray(m_selectionShader->posAtt());
+ }
+ glEnable(GL_DITHER);
+
+ // Read color under cursor
+ if (Scatter3DController::MouseOnScene == m_controller->mouseState())
+ m_selection = Utils::getSelection(m_controller->mousePosition(),
+ m_cachedBoundingRect.height());
+
+ QMutexLocker locker(&m_mutex);
+ if (m_isSelectionPointRequestActive) {
+ m_isSelectionPointRequestActive = false;
+ m_selection = Utils::getSelection(m_selectionPointRequest,
+ m_cachedBoundingRect.height());
+ emit selectionUpdated(m_selection);
+ }
+ locker.unlock();
+
+ glBindFramebuffer(GL_FRAMEBUFFER, defaultFboHandle);
+
+ // Release selection shader
+ m_selectionShader->release();
+
+#if 0 // Use this if you want to see what is being drawn to the framebuffer
+ m_labelShader->bind();
+ glDisable(GL_DEPTH_TEST);
+ glEnable(GL_TEXTURE_2D);
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 viewmatrix;
+ viewmatrix.lookAt(QVector3D(0.0f, 0.0f, 2.0f + zComp),
+ QVector3D(0.0f, 0.0f, zComp),
+ QVector3D(0.0f, 1.0f, 0.0f));
+ modelMatrix.translate(0.0, 0.0, zComp);
+ QMatrix4x4 MVPMatrix = projectionMatrix * viewmatrix * modelMatrix;
+ m_labelShader->setUniformValue(m_labelShader->MVP(), MVPMatrix);
+ m_drawer->drawObject(m_labelShader, m_labelObj,
+ m_selectionTexture);
+ glDisable(GL_TEXTURE_2D);
+ m_labelShader->release();
+#endif
+ }
+
+ // Bind bar shader
+ m_dotShader->bind();
+
+ // Enable texture
+ glEnable(GL_TEXTURE_2D);
+
+ // Draw bars
+ bool barSelectionFound = false;
+ for (int bar = 0; bar < m_renderItemArray.size(); bar++) {
+ ScatterRenderItem &item = m_renderItemArray[bar];
+ if (!item.value())
+ continue;
+
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+ QMatrix4x4 depthMVPMatrix;
+ QMatrix4x4 itModelMatrix;
+
+ modelMatrix.translate(item.translation().x(),
+ item.translation().y(),
+ item.translation().z());
+ modelMatrix.scale(QVector3D(widthMultiplier + widthScaler,
+ heightMultiplier + heightScaler,
+ depthMultiplier + depthScaler));
+ //modelMatrix.scale(QVector3D(widthMultiplier * item.size() + widthScaler,
+ // heightMultiplier * item.size() + heightScaler,
+ // depthMultiplier * item.size() + depthScaler));
+ itModelMatrix.scale(QVector3D(widthMultiplier + widthScaler,
+ heightMultiplier + heightScaler,
+ depthMultiplier + depthScaler));
+ //itModelMatrix.scale(QVector3D(widthMultiplier * item.size() + widthScaler,
+ // heightMultiplier * item.size() + heightScaler,
+ // depthMultiplier * item.size() + depthScaler));
+
+#ifdef SHOW_DEPTH_TEXTURE_SCENE
+ MVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
+#else
+ MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
+#endif
+ depthMVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
+
+ QVector3D baseColor = Utils::vectorFromColor(m_cachedTheme.m_baseColor);
+ QVector3D heightColor =
+ Utils::vectorFromColor(m_cachedTheme.m_heightColor) * item.translation().y();
+
+ QVector3D barColor = baseColor + heightColor;
+
+ GLfloat lightStrength = m_cachedTheme.m_lightStrength;
+ if (m_cachedSelectionMode > QDataVis::ModeNone) {
+ Scatter3DController::SelectionType selectionType = isSelected(bar, m_selection);
+ switch (selectionType) {
+ case Scatter3DController::SelectionItem: {
+ barColor = Utils::vectorFromColor(m_cachedTheme.m_highlightBarColor);
+ lightStrength = m_cachedTheme.m_highlightLightStrength;
+ // Insert data to ScatterRenderItem. We have no ownership, don't delete the previous one
+ m_selectedItem = &item;
+ barSelectionFound = true;
+ break;
+ }
+ case Scatter3DController::SelectionNone: {
+ // Current bar is not selected, nor on a row or column
+ // do nothing
+ break;
+ }
+ default: {
+ // Unsupported selection mode
+ // do nothing
+ break;
+ }
+ }
+ }
+
+ // Set shader bindings
+ m_dotShader->setUniformValue(m_dotShader->lightP(), lightPos);
+ m_dotShader->setUniformValue(m_dotShader->view(), viewMatrix);
+ m_dotShader->setUniformValue(m_dotShader->model(), modelMatrix);
+ m_dotShader->setUniformValue(m_dotShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ m_dotShader->setUniformValue(m_dotShader->MVP(), MVPMatrix);
+ m_dotShader->setUniformValue(m_dotShader->color(), barColor);
+ m_dotShader->setUniformValue(m_dotShader->ambientS(), m_cachedTheme.m_ambientStrength);
+
+#if !defined(QT_OPENGL_ES_2)
+ if (m_cachedShadowQuality > QDataVis::ShadowNone) {
+ // Set shadow shader bindings
+ m_dotShader->setUniformValue(m_dotShader->shadowQ(), m_shadowQualityToShader);
+ m_dotShader->setUniformValue(m_dotShader->depth(), depthMVPMatrix);
+ m_dotShader->setUniformValue(m_dotShader->lightS(), lightStrength / 10.0f);
+
+ // Draw the object
+ m_drawer->drawObject(m_dotShader, m_dotObj, 0, m_depthTexture);
+ } else
+#endif
+ {
+ // Set shadowless shader bindings
+ m_dotShader->setUniformValue(m_dotShader->lightS(), lightStrength);
+
+ // Draw the object
+ m_drawer->drawObject(m_dotShader, m_dotObj);
+ }
+ }
+
+ // Release bar shader
+ m_dotShader->release();
+
+ // Bind background shader
+ m_backgroundShader->bind();
+
+ glCullFace(GL_BACK);
+
+ // Draw background
+ if (m_cachedIsBackgroundEnabled && m_backgroundObj) {
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+ QMatrix4x4 depthMVPMatrix;
+ QMatrix4x4 itModelMatrix;
+
+ modelMatrix.translate(0.0f, 0.0f, zComp);
+#ifndef USE_UNIFORM_SCALING // Use this if we want to use autoscaling for x and z
+ modelMatrix.scale(
+ QVector3D(
+ (aspectRatio * backgroundMargin * m_areaSize.width()) / m_scaleFactor,
+ backgroundMargin,
+ (aspectRatio * backgroundMargin * m_areaSize.height()) / m_scaleFactor));
+#else // ..and this if we want uniform scaling based on largest dimension
+ modelMatrix.scale(QVector3D((aspectRatio * backgroundMargin),
+ backgroundMargin,
+ (aspectRatio * backgroundMargin)));
+#endif
+ // We can copy modelMatrix to itModelMatrix as it has not been translated
+ itModelMatrix = modelMatrix;
+ // If we're viewing from below, background object must be flipped
+ if (m_yFlipped) {
+ modelMatrix.rotate(180.0f, 1.0, 0.0, 0.0);
+ modelMatrix.rotate(270.0f - backgroundRotation, 0.0f, 1.0f, 0.0f);
+ } else {
+ modelMatrix.rotate(backgroundRotation, 0.0f, 1.0f, 0.0f);
+ }
+
+#ifdef SHOW_DEPTH_TEXTURE_SCENE
+ MVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
+#else
+ MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
+#endif
+ depthMVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
+
+ QVector3D backgroundColor = Utils::vectorFromColor(m_cachedTheme.m_backgroundColor);
+
+ // Set shader bindings
+ m_backgroundShader->setUniformValue(m_backgroundShader->lightP(), lightPos);
+ m_backgroundShader->setUniformValue(m_backgroundShader->view(), viewMatrix);
+ m_backgroundShader->setUniformValue(m_backgroundShader->model(), modelMatrix);
+ m_backgroundShader->setUniformValue(m_backgroundShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ m_backgroundShader->setUniformValue(m_backgroundShader->MVP(), MVPMatrix);
+ m_backgroundShader->setUniformValue(m_backgroundShader->color(), backgroundColor);
+ m_backgroundShader->setUniformValue(m_backgroundShader->ambientS(),
+ m_cachedTheme.m_ambientStrength * 2.0f);
+
+#if !defined(QT_OPENGL_ES_2)
+ if (m_cachedShadowQuality > QDataVis::ShadowNone) {
+ // Set shadow shader bindings
+ m_backgroundShader->setUniformValue(m_backgroundShader->shadowQ(),
+ m_shadowQualityToShader);
+ m_backgroundShader->setUniformValue(m_backgroundShader->depth(), depthMVPMatrix);
+ m_backgroundShader->setUniformValue(m_backgroundShader->lightS(),
+ m_cachedTheme.m_lightStrength / 10.0f);
+
+ // Draw the object
+ m_drawer->drawObject(m_backgroundShader, m_backgroundObj, 0, m_depthTexture);
+ } else
+#endif
+ {
+ // Set shadowless shader bindings
+ m_backgroundShader->setUniformValue(m_backgroundShader->lightS(),
+ m_cachedTheme.m_lightStrength);
+
+ // Draw the object
+ m_drawer->drawObject(m_backgroundShader, m_backgroundObj);
+ }
+ }
+
+ // Release background shader
+ m_backgroundShader->release();
+
+ // Disable textures
+ glDisable(GL_TEXTURE_2D);
+
+ // Draw grid lines
+#ifdef USE_UNIFORM_SCALING
+ AxisRenderCache *axisCacheMax;
+ if (m_axisCacheZ.max() > m_axisCacheX.max())
+ axisCacheMax = &m_axisCacheZ;
+ else
+ axisCacheMax = &m_axisCacheX;
+#endif
+
+ if (m_cachedIsGridEnabled && m_heightNormalizer) {
+ // Bind bar shader
+ m_dotShader->bind();
+
+ // Set unchanging shader bindings
+ QVector3D barColor = Utils::vectorFromColor(m_cachedTheme.m_gridLine);
+ m_dotShader->setUniformValue(m_dotShader->lightP(), lightPos);
+ m_dotShader->setUniformValue(m_dotShader->view(), viewMatrix);
+ m_dotShader->setUniformValue(m_dotShader->color(), barColor);
+ m_dotShader->setUniformValue(m_dotShader->ambientS(), m_cachedTheme.m_ambientStrength);
+
+ // Floor lines: rows (= Z)
+ if (m_axisCacheZ.segmentCount() > 0) {
+#ifndef USE_UNIFORM_SCALING
+ GLfloat lineStep = aspectRatio * m_axisCacheZ.subSegmentStep();
+ GLfloat linePos = aspectRatio * m_axisCacheZ.min(); // Start line
+ int lastSegment = m_axisCacheZ.subSegmentCount() * m_axisCacheZ.segmentCount();
+#else
+ GLfloat lineStep = aspectRatio * axisCacheMax->subSegmentStep();
+ GLfloat linePos = -aspectRatio * m_scaleFactor; // Start line
+ int lastSegment = axisCacheMax->subSegmentCount() * axisCacheMax->segmentCount();
+#endif
+
+ for (int segment = 0; segment <= lastSegment; segment++) {
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+ QMatrix4x4 depthMVPMatrix;
+ QMatrix4x4 itModelMatrix;
+
+ if (m_yFlipped) {
+ modelMatrix.translate(0.0f,
+ backgroundMargin,
+ linePos / m_scaleFactor + zComp);
+ } else {
+ modelMatrix.translate(0.0f,
+ -backgroundMargin,
+ linePos / m_scaleFactor + zComp);
+ }
+#ifndef USE_UNIFORM_SCALING // Use this if we want to use autoscaling for x and z
+ modelMatrix.scale(
+ QVector3D(
+ (aspectRatio * backgroundMargin * m_areaSize.width()) / m_scaleFactor,
+ gridLineWidth, gridLineWidth));
+ itModelMatrix.scale(
+ QVector3D(
+ (aspectRatio * backgroundMargin * m_areaSize.width()) / m_scaleFactor,
+ gridLineWidth, gridLineWidth));
+#else // ..and this if we want uniform scaling based on largest dimension
+ modelMatrix.scale(QVector3D((aspectRatio * backgroundMargin),
+ gridLineWidth, gridLineWidth));
+ itModelMatrix.scale(QVector3D(aspectRatio * backgroundMargin,
+ gridLineWidth, gridLineWidth));
+#endif
+
+ // If we're viewing from below, grid line object must be flipped
+ if (m_yFlipped)
+ modelMatrix.rotate(180.0f, 1.0, 0.0, 0.0);
+
+ MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
+ depthMVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
+
+ // Set the rest of the shader bindings
+ m_dotShader->setUniformValue(m_dotShader->model(), modelMatrix);
+ m_dotShader->setUniformValue(m_dotShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ m_dotShader->setUniformValue(m_dotShader->MVP(), MVPMatrix);
+
+#if !defined(QT_OPENGL_ES_2)
+ if (m_cachedShadowQuality > QDataVis::ShadowNone) {
+ // Set shadow shader bindings
+ m_dotShader->setUniformValue(m_dotShader->shadowQ(), m_shadowQualityToShader);
+ m_dotShader->setUniformValue(m_dotShader->depth(), depthMVPMatrix);
+ m_dotShader->setUniformValue(m_dotShader->lightS(),
+ m_cachedTheme.m_lightStrength / 10.0f);
+
+ // Draw the object
+ m_drawer->drawObject(m_dotShader, m_gridLineObj, 0, m_depthTexture);
+ } else
+#endif
+ {
+ // Set shadowless shader bindings
+ m_dotShader->setUniformValue(m_dotShader->lightS(),
+ m_cachedTheme.m_lightStrength);
+
+ // Draw the object
+ m_drawer->drawObject(m_dotShader, m_gridLineObj);
+ }
+ linePos += lineStep;
+ }
+ }
+
+ // Floor lines: columns (= X)
+ if (m_axisCacheX.segmentCount() > 0) {
+#ifndef USE_UNIFORM_SCALING
+ GLfloat lineStep = aspectRatio * m_axisCacheX.subSegmentStep();
+ GLfloat linePos = aspectRatio * m_axisCacheX.min();
+ int lastSegment = m_axisCacheX.subSegmentCount() * m_axisCacheX.segmentCount();
+#else
+ GLfloat lineStep = aspectRatio * axisCacheMax->subSegmentStep();
+ GLfloat linePos = -aspectRatio * m_scaleFactor;
+ int lastSegment = axisCacheMax->subSegmentCount() * axisCacheMax->segmentCount();
+#endif
+
+ for (int segment = 0; segment <= lastSegment; segment++) {
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+ QMatrix4x4 depthMVPMatrix;
+ QMatrix4x4 itModelMatrix;
+
+ if (m_yFlipped) {
+ modelMatrix.translate(linePos / m_scaleFactor,
+ backgroundMargin,
+ zComp);
+ } else {
+ modelMatrix.translate(linePos / m_scaleFactor,
+ -backgroundMargin,
+ zComp);
+ }
+#ifndef USE_UNIFORM_SCALING // Use this if we want to use autoscaling for x and z
+ modelMatrix.scale(
+ QVector3D(
+ gridLineWidth, gridLineWidth,
+ (aspectRatio * backgroundMargin * m_areaSize.height()) / m_scaleFactor));
+ itModelMatrix.scale(
+ QVector3D(
+ gridLineWidth, gridLineWidth,
+ (aspectRatio * backgroundMargin * m_areaSize.height()) / m_scaleFactor));
+#else // ..and this if we want uniform scaling based on largest dimension
+ modelMatrix.scale(QVector3D(gridLineWidth, gridLineWidth,
+ aspectRatio * backgroundMargin));
+ itModelMatrix.scale(QVector3D(gridLineWidth, gridLineWidth,
+ aspectRatio * backgroundMargin));
+#endif
+
+ // If we're viewing from below, grid line object must be flipped
+ if (m_yFlipped)
+ modelMatrix.rotate(180.0f, 1.0, 0.0, 0.0);
+
+ MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
+ depthMVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
+
+ // Set the rest of the shader bindings
+ m_dotShader->setUniformValue(m_dotShader->model(), modelMatrix);
+ m_dotShader->setUniformValue(m_dotShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ m_dotShader->setUniformValue(m_dotShader->MVP(), MVPMatrix);
+
+#if !defined(QT_OPENGL_ES_2)
+ if (m_cachedShadowQuality > QDataVis::ShadowNone) {
+ // Set shadow shader bindings
+ m_dotShader->setUniformValue(m_dotShader->shadowQ(), m_shadowQualityToShader);
+ m_dotShader->setUniformValue(m_dotShader->depth(), depthMVPMatrix);
+ m_dotShader->setUniformValue(m_dotShader->lightS(),
+ m_cachedTheme.m_lightStrength / 10.0f);
+
+ // Draw the object
+ m_drawer->drawObject(m_dotShader, m_gridLineObj, 0, m_depthTexture);
+ } else
+#endif
+ {
+ // Set shadowless shader bindings
+ m_dotShader->setUniformValue(m_dotShader->lightS(), m_cachedTheme.m_lightStrength);
+
+ // Draw the object
+ m_drawer->drawObject(m_dotShader, m_gridLineObj);
+ }
+ linePos += lineStep;
+ }
+ }
+
+ // Wall lines: back wall
+ if (m_axisCacheY.segmentCount() > 0) {
+ GLfloat lineStep = m_axisCacheY.subSegmentStep();
+ GLfloat linePos = m_axisCacheY.min();
+ int lastSegment = m_axisCacheY.subSegmentCount() * m_axisCacheY.segmentCount();
+
+ for (int segment = 0; segment <= lastSegment; segment++) {
+#ifndef USE_UNIFORM_SCALING // Use this if we want to use autoscaling for x and z
+ GLfloat lineZTrans = (aspectRatio * backgroundMargin * m_areaSize.height())
+ / m_scaleFactor;
+#else // ..and this if we want uniform scaling based on largest dimension
+ GLfloat lineZTrans = aspectRatio * backgroundMargin;
+#endif
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+ QMatrix4x4 depthMVPMatrix;
+ QMatrix4x4 itModelMatrix;
+
+ if (!m_zFlipped)
+ lineZTrans = -lineZTrans;
+
+ modelMatrix.translate(0.0f,
+ linePos / m_heightNormalizer,
+ lineZTrans + zComp);
+#ifndef USE_UNIFORM_SCALING // Use this if we want to use autoscaling for x and z
+ modelMatrix.scale(
+ QVector3D(
+ (aspectRatio * backgroundMargin * m_areaSize.width() / m_scaleFactor),
+ gridLineWidth, gridLineWidth));
+ itModelMatrix.scale(
+ QVector3D(
+ (aspectRatio * backgroundMargin * m_areaSize.width() / m_scaleFactor),
+ gridLineWidth, gridLineWidth));
+#else // ..and this if we want uniform scaling based on largest dimension
+ modelMatrix.scale(QVector3D((aspectRatio * backgroundMargin),
+ gridLineWidth, gridLineWidth));
+ itModelMatrix.scale(QVector3D(aspectRatio * backgroundMargin,
+ gridLineWidth, gridLineWidth));
+#endif
+
+ MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
+ depthMVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
+
+ // Set the rest of the shader bindings
+ m_dotShader->setUniformValue(m_dotShader->model(), modelMatrix);
+ m_dotShader->setUniformValue(m_dotShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ m_dotShader->setUniformValue(m_dotShader->MVP(), MVPMatrix);
+
+#if !defined(QT_OPENGL_ES_2)
+ if (m_cachedShadowQuality > QDataVis::ShadowNone) {
+ // Set shadow shader bindings
+ m_dotShader->setUniformValue(m_dotShader->shadowQ(), m_shadowQualityToShader);
+ m_dotShader->setUniformValue(m_dotShader->depth(), depthMVPMatrix);
+ m_dotShader->setUniformValue(m_dotShader->lightS(),
+ m_cachedTheme.m_lightStrength / 10.0f);
+
+ // Draw the object
+ m_drawer->drawObject(m_dotShader, m_gridLineObj, 0, m_depthTexture);
+ } else
+#endif
+ {
+ // Set shadowless shader bindings
+ m_dotShader->setUniformValue(m_dotShader->lightS(), m_cachedTheme.m_lightStrength);
+
+ // Draw the object
+ m_drawer->drawObject(m_dotShader, m_gridLineObj);
+ }
+ linePos += lineStep;
+ }
+
+ // Wall lines: side wall
+ linePos = m_axisCacheY.min();
+ lastSegment = m_axisCacheY.subSegmentCount() * m_axisCacheY.segmentCount();
+
+ for (int segment = 0; segment <= lastSegment; segment++) {
+#ifndef USE_UNIFORM_SCALING // Use this if we want to use autoscaling for x and z
+ GLfloat lineXTrans = (aspectRatio * backgroundMargin * m_areaSize.width())
+ / m_scaleFactor;
+#else // ..and this if we want uniform scaling based on largest dimension
+ GLfloat lineXTrans = aspectRatio * backgroundMargin;
+#endif
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+ QMatrix4x4 depthMVPMatrix;
+ QMatrix4x4 itModelMatrix;
+
+ if (!m_xFlipped)
+ lineXTrans = -lineXTrans;
+
+ modelMatrix.translate(lineXTrans,
+ linePos / m_heightNormalizer,
+ zComp);
+#ifndef USE_UNIFORM_SCALING // Use this if we want to use autoscaling for x and z
+ modelMatrix.scale(
+ QVector3D(
+ gridLineWidth, gridLineWidth,
+ (aspectRatio * backgroundMargin * m_areaSize.height()) / m_scaleFactor));
+ itModelMatrix.scale(
+ QVector3D(
+ gridLineWidth, gridLineWidth,
+ (aspectRatio * backgroundMargin * m_areaSize.height()) / m_scaleFactor));
+
+#else // ..and this if we want uniform scaling based on largest dimension
+ modelMatrix.scale(QVector3D(gridLineWidth, gridLineWidth,
+ (aspectRatio * backgroundMargin)));
+ itModelMatrix.scale(QVector3D(gridLineWidth, gridLineWidth,
+ aspectRatio * backgroundMargin));
+
+#endif
+ MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
+ depthMVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
+
+ // Set the rest of the shader bindings
+ m_dotShader->setUniformValue(m_dotShader->model(), modelMatrix);
+ m_dotShader->setUniformValue(m_dotShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ m_dotShader->setUniformValue(m_dotShader->MVP(), MVPMatrix);
+
+#if !defined(QT_OPENGL_ES_2)
+ if (m_cachedShadowQuality > QDataVis::ShadowNone) {
+ // Set shadow shader bindings
+ m_dotShader->setUniformValue(m_dotShader->shadowQ(), m_shadowQualityToShader);
+ m_dotShader->setUniformValue(m_dotShader->depth(), depthMVPMatrix);
+ m_dotShader->setUniformValue(m_dotShader->lightS(),
+ m_cachedTheme.m_lightStrength / 10.0f);
+
+ // Draw the object
+ m_drawer->drawObject(m_dotShader, m_gridLineObj, 0, m_depthTexture);
+ } else
+#endif
+ {
+ // Set shadowless shader bindings
+ m_dotShader->setUniformValue(m_dotShader->lightS(), m_cachedTheme.m_lightStrength);
+
+ // Draw the object
+ m_drawer->drawObject(m_dotShader, m_gridLineObj);
+ }
+ linePos += lineStep;
+ }
+ }
+
+ // Release bar shader
+ m_dotShader->release();
+ }
+
+ // Handle selection clearing and selection label drawing
+ if (!barSelectionFound) {
+ // We have no ownership, don't delete. Just NULL the pointer.
+ m_selectedItem = NULL;
+ } else {
+ // Print value of selected bar
+ m_labelShader->bind();
+ glDisable(GL_DEPTH_TEST);
+ glEnable(GL_TEXTURE_2D);
+ if (m_cachedLabelTransparency > QDataVis::TransparencyNone) {
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ }
+#ifndef DISPLAY_FULL_DATA_ON_SELECTION
+ // Draw just the value string of the selected bar
+ if (m_previouslySelectedBar != m_selectedBar || m_updateLabels) {
+ m_drawer->generateLabelTexture(m_selectedBar);
+ m_previouslySelectedBar = m_selectedBar;
+ }
+
+ m_drawer->drawLabel(*m_selectedBar, m_selectedBar->labelItem(),
+ viewMatrix, projectionMatrix,
+ QVector3D(0.0f, m_yAdjustment, zComp),
+ QVector3D(0.0f, 0.0f, 0.0f), m_selectedBar->height(),
+ m_cachedSelectionMode, m_labelShader,
+ m_labelObj, m_camera, true);
+#else
+ // Draw the value string followed by row label and column label
+ LabelItem &labelItem = m_selectedItem->selectionLabel();
+ if (m_previouslySelectedItem != m_selectedItem || m_updateLabels
+ || !labelItem.textureId()) {
+ QString labelText = m_selectedItem->label();
+ // TODO More elaborate label?
+ m_drawer->generateLabelItem(labelItem, labelText);
+ m_previouslySelectedItem = m_selectedItem;
+ }
+
+ m_drawer->drawLabel(*m_selectedItem, labelItem, viewMatrix, projectionMatrix,
+ QVector3D(0.0f, 0.0f, zComp),
+ QVector3D(0.0f, 0.0f, 0.0f), m_selectedItem->height(),
+ m_cachedSelectionMode, m_labelShader,
+ m_labelObj, camera, true, false, Drawer::LabelMid);
+#endif
+ glDisable(GL_TEXTURE_2D);
+ if (m_cachedLabelTransparency > QDataVis::TransparencyNone)
+ glDisable(GL_BLEND);
+ glEnable(GL_DEPTH_TEST);
+
+ // Release label shader
+ m_labelShader->release();
+
+ // Reset label update flag; they should have been updated when we get here
+ m_updateLabels = false;
+ }
+
+ // Draw axis labels
+ // TODO: Calculations done temporarily here. Should be done when calculating lines to avoid
+ // extra for -loops?
+ // Bind label shader
+ m_labelShader->bind();
+
+ glEnable(GL_TEXTURE_2D);
+ if (m_cachedLabelTransparency > QDataVis::TransparencyNone) {
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ }
+
+ // Z Labels
+ if (m_axisCacheZ.segmentCount() > 0) {
+#ifndef USE_UNIFORM_SCALING
+ GLfloat posStep = aspectRatio * m_axisCacheZ.segmentStep();
+ GLfloat labelPos = aspectRatio * m_axisCacheZ.min();
+ int lastSegment = m_axisCacheZ.segmentCount();
+#else
+ GLfloat posStep = aspectRatio * axisCacheMax->segmentStep();
+ GLfloat labelPos = -aspectRatio * m_scaleFactor;
+ int lastSegment = axisCacheMax->segmentCount();
+#endif
+ int labelNbr = 0;
+ for (int segment = 0; segment <= lastSegment; segment++) {
+#ifndef USE_UNIFORM_SCALING // Use this if we want to use autoscaling for x and z
+ if (m_axisCacheZ.labelItems().size() > labelNbr) {
+ GLfloat labelXTrans = (aspectRatio * backgroundMargin * m_areaSize.width())
+ / m_scaleFactor;
+#else // ..and this if we want uniform scaling based on largest dimension
+ if (axisCacheMax->labelItems().size() > labelNbr) {
+ GLfloat labelXTrans = aspectRatio * backgroundMargin;
+#endif
+ GLfloat labelYTrans = -backgroundMargin;
+ GLfloat rotLabelX = -90.0f;
+ GLfloat rotLabelY = 0.0f;
+ GLfloat rotLabelZ = 0.0f;
+ Qt::AlignmentFlag alignment = Qt::AlignRight;
+ if (m_zFlipped)
+ rotLabelY = 180.0f;
+ if (m_xFlipped) {
+ labelXTrans = -labelXTrans;
+ alignment = Qt::AlignLeft;
+ }
+ if (m_yFlipped) {
+ rotLabelZ += 180.0f;
+ rotLabelY += 180.0f;
+ labelYTrans = -labelYTrans;
+ }
+ QVector3D labelTrans = QVector3D(labelXTrans,
+ labelYTrans,
+ labelPos / m_scaleFactor + zComp);
+
+
+ // Draw the label here
+ m_dummyRenderItem.setTranslation(labelTrans);
+#ifndef USE_UNIFORM_SCALING
+ const LabelItem &axisLabelItem = *m_axisCacheZ.labelItems().at(labelNbr);
+#else
+ const LabelItem &axisLabelItem = *axisCacheMax->labelItems().at(labelNbr);
+#endif
+
+ m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix,
+ QVector3D(0.0f, 0.0f, zComp),
+ QVector3D(rotLabelX, rotLabelY, rotLabelZ),
+ 0, m_cachedSelectionMode,
+ m_labelShader, m_labelObj, camera, true, true, Drawer::LabelMid,
+ alignment);
+ }
+ labelNbr++;
+ labelPos += posStep;
+ }
+ }
+ // X Labels
+ if (m_axisCacheX.segmentCount() > 0) {
+#ifndef USE_UNIFORM_SCALING
+ GLfloat posStep = aspectRatio * m_axisCacheX.segmentStep();
+ GLfloat labelPos = aspectRatio * m_axisCacheX.min();
+ int lastSegment = m_axisCacheX.segmentCount();
+#else
+ GLfloat posStep = aspectRatio * axisCacheMax->segmentStep();
+ GLfloat labelPos = -aspectRatio * m_scaleFactor;
+ int lastSegment = axisCacheMax->segmentCount();
+#endif
+ int labelNbr = 0;
+ for (int segment = 0; segment <= lastSegment; segment++) {
+#ifndef USE_UNIFORM_SCALING // Use this if we want to use autoscaling for x and z
+ if (m_axisCacheX.labelItems().size() > labelNbr) {
+ GLfloat labelZTrans = (aspectRatio * backgroundMargin * m_areaSize.height())
+ / m_scaleFactor;
+#else // ..and this if we want uniform scaling based on largest dimension
+ if (axisCacheMax->labelItems().size() > labelNbr) {
+ GLfloat labelZTrans = aspectRatio * backgroundMargin;
+#endif
+ GLfloat labelYTrans = -backgroundMargin;
+ GLfloat rotLabelX = -90.0f;
+ GLfloat rotLabelY = 90.0f;
+ GLfloat rotLabelZ = 0.0f;
+ Qt::AlignmentFlag alignment = Qt::AlignLeft;
+ if (m_xFlipped)
+ rotLabelY = -90.0f;
+ if (m_zFlipped) {
+ labelZTrans = -labelZTrans;
+ alignment = Qt::AlignRight;
+ }
+ if (m_yFlipped) {
+ rotLabelZ += 180.0f;
+ rotLabelY += 180.0f;
+ labelYTrans = -labelYTrans;
+ }
+ QVector3D labelTrans = QVector3D(labelPos / m_scaleFactor,
+ labelYTrans,
+ labelZTrans + zComp);
+
+ // Draw the label here
+ m_dummyRenderItem.setTranslation(labelTrans);
+#ifndef USE_UNIFORM_SCALING
+ const LabelItem &axisLabelItem = *m_axisCacheX.labelItems().at(labelNbr);
+#else
+ const LabelItem &axisLabelItem = *axisCacheMax->labelItems().at(labelNbr);
+#endif
+
+ m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix,
+ QVector3D(0.0f, 0.0f, zComp),
+ QVector3D(rotLabelX, rotLabelY, rotLabelZ),
+ 0, m_cachedSelectionMode,
+ m_labelShader, m_labelObj, camera, true, true, Drawer::LabelMid,
+ alignment);
+ }
+ labelNbr++;
+ labelPos += posStep;
+ }
+ }
+ // Y Labels
+ if (m_axisCacheY.segmentCount() > 0) {
+ GLfloat posStep = m_axisCacheY.segmentStep();
+ GLfloat labelPos = m_axisCacheY.min();
+ int labelNbr = 0;
+ for (int segment = 0; segment <= m_axisCacheY.segmentCount(); segment++) {
+ if (m_axisCacheY.labelItems().size() > labelNbr) {
+#ifndef USE_UNIFORM_SCALING // Use this if we want to use autoscaling for x and z
+ GLfloat labelXTrans = (aspectRatio * backgroundMargin * m_areaSize.width())
+ / m_scaleFactor;
+ GLfloat labelZTrans = (aspectRatio * backgroundMargin * m_areaSize.height())
+ / m_scaleFactor;
+#else // ..and this if we want uniform scaling based on largest dimension
+ GLfloat labelXTrans = aspectRatio * backgroundMargin;
+ GLfloat labelZTrans = labelXTrans;
+#endif
+ GLfloat labelYTrans = labelPos / m_heightNormalizer;
+ GLfloat rotLabelX = 0.0f;
+ GLfloat rotLabelY = -90.0f;
+ GLfloat rotLabelZ = 0.0f;
+ Qt::AlignmentFlag alignment = Qt::AlignLeft;
+ if (!m_xFlipped) {
+ labelXTrans = -labelXTrans;
+ rotLabelY = 90.0f;
+ }
+ if (m_zFlipped) {
+ labelZTrans = -labelZTrans;
+ alignment = Qt::AlignRight;
+ }
+
+ const LabelItem &axisLabelItem = *m_axisCacheY.labelItems().at(labelNbr);
+
+ // Back wall
+ QVector3D labelTrans = QVector3D(labelXTrans, labelYTrans, labelZTrans + zComp);
+
+ // Draw the label here
+ m_dummyRenderItem.setTranslation(labelTrans);
+ m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix,
+ QVector3D(0.0f, 0.0f, zComp),
+ QVector3D(rotLabelX, rotLabelY, rotLabelZ),
+ 0, m_cachedSelectionMode,
+ m_labelShader, m_labelObj, camera, true, true, Drawer::LabelMid,
+ alignment);
+
+ // Side wall
+ if (m_xFlipped)
+ alignment = Qt::AlignLeft;
+ else
+ alignment = Qt::AlignRight;
+ if (m_zFlipped)
+ rotLabelY = 180.0f;
+ else
+ rotLabelY = 0.0f;
+
+ labelTrans = QVector3D(-labelXTrans, labelYTrans, -labelZTrans + zComp);
+
+ // Draw the label here
+ m_dummyRenderItem.setTranslation(labelTrans);
+ m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix,
+ QVector3D(0.0f, 0.0f, zComp),
+ QVector3D(rotLabelX, rotLabelY, rotLabelZ),
+ 0, m_cachedSelectionMode,
+ m_labelShader, m_labelObj, camera, true, true, Drawer::LabelMid,
+ alignment);
+ }
+ labelNbr++;
+ labelPos += posStep;
+ }
+ }
+ glDisable(GL_TEXTURE_2D);
+ if (m_cachedLabelTransparency > QDataVis::TransparencyNone)
+ glDisable(GL_BLEND);
+
+ // Release label shader
+ m_labelShader->release();
+}
+
+void Scatter3DRenderer::requestSelectionAtPoint(const QPoint &point)
+{
+ //qDebug() << __FUNCTION__;
+ QMutexLocker locker(&m_mutex);
+ m_selectionPointRequest.setX(point.x());
+ m_selectionPointRequest.setY(point.y());
+ m_isSelectionPointRequestActive = true;
+}
+
+void Scatter3DRenderer::handleResize()
+{
+ //qDebug() << __FUNCTION__;
+ if (m_cachedBoundingRect.width() == 0 || m_cachedBoundingRect.height() == 0)
+ return;
+
+ // Set view port
+ m_mainViewPort = QRect(0, 0, m_cachedBoundingRect.width(), m_cachedBoundingRect.height());
+
+ Abstract3DRenderer::handleResize();
+}
+
+void Scatter3DRenderer::updateMeshFileName(const QString &objFileName)
+{
+ Abstract3DRenderer::updateMeshFileName(objFileName);
+ loadBarMesh();
+}
+
+void Scatter3DRenderer::updateBackgroundEnabled(bool enable)
+{
+ if (enable != m_cachedIsBackgroundEnabled) {
+ Abstract3DRenderer::updateBackgroundEnabled(enable);
+ loadBarMesh(); // Load changed bar type
+ }
+}
+
+void Scatter3DRenderer::updateShadowQuality(QDataVis::ShadowQuality quality)
+{
+ qDebug() << "Scatter3DRenderer::setShadowQuality" << quality;
+ m_cachedShadowQuality = quality;
+ switch (quality) {
+ case QDataVis::ShadowLow:
+ m_shadowQualityToShader = 33.3f;
+ break;
+ case QDataVis::ShadowMedium:
+ m_shadowQualityToShader = 100.0f;
+ break;
+ case QDataVis::ShadowHigh:
+ m_shadowQualityToShader = 200.0f;
+ break;
+ default:
+ m_shadowQualityToShader = 0.0f;
+ break;
+ }
+#if !defined(QT_OPENGL_ES_2)
+ if (m_cachedShadowQuality > QDataVis::ShadowNone) {
+ // Re-init shaders
+ if (!m_cachedTheme.m_uniformColor) {
+ initShaders(QStringLiteral(":/shaders/vertexShadow"),
+ QStringLiteral(":/shaders/fragmentShadowNoTexColorOnY"));
+ } else {
+ initShaders(QStringLiteral(":/shaders/vertexShadow"),
+ QStringLiteral(":/shaders/fragmentShadowNoTex"));
+ }
+ initBackgroundShaders(QStringLiteral(":/shaders/vertexShadow"),
+ QStringLiteral(":/shaders/fragmentShadowNoTex"));
+ } else {
+ // Re-init shaders
+ if (!m_cachedTheme.m_uniformColor) {
+ initShaders(QStringLiteral(":/shaders/vertex"),
+ QStringLiteral(":/shaders/fragmentColorOnY"));
+ } else {
+ initShaders(QStringLiteral(":/shaders/vertex"),
+ QStringLiteral(":/shaders/fragment"));
+ }
+ initBackgroundShaders(QStringLiteral(":/shaders/vertex"),
+ QStringLiteral(":/shaders/fragment"));
+ }
+ // Re-init depth buffer
+ updateDepthBuffer();
+#else
+ if (!m_cachedTheme.m_uniformColor) {
+ initShaders(QStringLiteral(":/shaders/vertexES2"),
+ QStringLiteral(":/shaders/fragmentColorOnYES2"));
+ } else {
+ initShaders(QStringLiteral(":/shaders/vertexES2"),
+ QStringLiteral(":/shaders/fragmentES2"));
+ }
+ initBackgroundShaders(QStringLiteral(":/shaders/vertexES2"),
+ QStringLiteral(":/shaders/fragmentES2"));
+#endif
+}
+
+void Scatter3DRenderer::loadBarMesh()
+{
+ //qDebug() << __FUNCTION__;
+ QString objectFileName = m_cachedObjFile;
+ if (m_dotObj)
+ delete m_dotObj;
+ m_dotObj = new ObjectHelper(objectFileName);
+ m_dotObj->load();
+}
+
+void Scatter3DRenderer::loadBackgroundMesh()
+{
+ //qDebug() << __FUNCTION__;
+ if (m_backgroundObj)
+ delete m_backgroundObj;
+ m_backgroundObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/background"));
+ m_backgroundObj->load();
+}
+
+void Scatter3DRenderer::loadGridLineMesh()
+{
+ //qDebug() << __FUNCTION__;
+ if (m_gridLineObj)
+ delete m_gridLineObj;
+ m_gridLineObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/bar"));
+ m_gridLineObj->load();
+}
+
+void Scatter3DRenderer::loadLabelMesh()
+{
+ //qDebug() << __FUNCTION__;
+ if (m_labelObj)
+ delete m_labelObj;
+ m_labelObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/label"));
+ m_labelObj->load();
+}
+
+void Scatter3DRenderer::updateTextures()
+{
+ //qDebug() << __FUNCTION__;
+ // Drawer has changed; this flag needs to be checked when checking if we need to update labels
+ m_updateLabels = true;
+}
+
+void Scatter3DRenderer::updateAxisRange(QAbstractAxis::AxisOrientation orientation,
+ qreal min, qreal max)
+{
+ Abstract3DRenderer::updateAxisRange(orientation, min, max);
+}
+
+void Scatter3DRenderer::calculateTranslation(ScatterRenderItem &item)
+{
+ //qDebug() << __FUNCTION__;
+
+ // Origin should be in the center of scene, ie. both positive and negative values are drawn
+ // above background
+
+ // We need to normalize translations
+ GLfloat xTrans = (aspectRatio * item.position().x()) / m_scaleFactor;
+ GLfloat zTrans = (aspectRatio * item.position().z()) / m_scaleFactor;
+ GLfloat yTrans = item.position().y() / m_heightNormalizer;
+ item.setTranslation(QVector3D(xTrans, yTrans, zTrans + zComp));
+ //qDebug() << item.translation();
+}
+
+void Scatter3DRenderer::calculateSceneScalingFactors()
+{
+ m_heightNormalizer = (GLfloat)m_axisCacheY.max();
+ // TODO: Get rid of m_areaSize and use m_axisCaches directly?
+ m_areaSize.setHeight(m_axisCacheZ.max());
+ m_areaSize.setWidth(m_axisCacheX.max());
+ m_scaleFactor = qMax(m_areaSize.width(), m_areaSize.height());
+ //qDebug() << m_heightNormalizer << m_areaSize << m_scaleFactor << m_axisCacheY.max() << m_axisCacheX.max() << m_axisCacheZ.max();
+}
+
+Scatter3DController::SelectionType Scatter3DRenderer::isSelected(GLint bar,
+ const QVector3D &selection)
+{
+ //qDebug() << __FUNCTION__;
+ GLubyte barIdxRed = 0;
+ GLubyte barIdxGreen = 0;
+ GLubyte barIdxBlue = 0;
+ //static QVector3D prevSel = selection; // TODO: For debugging
+ Scatter3DController::SelectionType isSelectedType = Scatter3DController::SelectionNone;
+
+ if (selection == selectionSkipColor)
+ return isSelectedType; // skip window
+
+ if (bar <= 255) {
+ barIdxRed = bar;
+ } else if (bar <= 65535) {
+ barIdxGreen = bar / 256;
+ barIdxRed = bar % 256;
+ } else {
+ barIdxBlue = bar / 65535;
+ barIdxGreen = bar % 65535;
+ barIdxRed = bar % 256;
+ }
+
+ QVector3D current = QVector3D(barIdxRed, barIdxGreen, barIdxBlue);
+
+ // TODO: For debugging
+ //if (selection != prevSel) {
+ // qDebug() << selection.x() << selection .y() << selection.z();
+ // prevSel = selection;
+ //}
+
+ if (current == selection)
+ isSelectedType = Scatter3DController::SelectionItem;
+
+ return isSelectedType;
+}
+
+QRect Scatter3DRenderer::mainViewPort()
+{
+ //qDebug() << __FUNCTION__;
+ return m_mainViewPort;
+}
+
+void Scatter3DRenderer::initShaders(const QString &vertexShader, const QString &fragmentShader)
+{
+ //qDebug() << __FUNCTION__;
+ if (m_dotShader)
+ delete m_dotShader;
+ m_dotShader = new ShaderHelper(this, vertexShader, fragmentShader);
+ m_dotShader->initialize();
+}
+
+void Scatter3DRenderer::initSelectionShader()
+{
+ //qDebug() << __FUNCTION__;
+ if (m_selectionShader)
+ delete m_selectionShader;
+ m_selectionShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexSelection"),
+ QStringLiteral(":/shaders/fragmentSelection"));
+ m_selectionShader->initialize();
+}
+
+void Scatter3DRenderer::initSelectionBuffer()
+{
+ //qDebug() << __FUNCTION__;
+ if (m_selectionTexture)
+ m_textureHelper->deleteTexture(&m_selectionTexture);
+
+ m_selectionTexture = m_textureHelper->createSelectionTexture(m_mainViewPort.size(),
+ m_selectionFrameBuffer,
+ m_selectionDepthBuffer);
+}
+
+#if !defined(QT_OPENGL_ES_2)
+void Scatter3DRenderer::initDepthShader()
+{
+ //qDebug() << __FUNCTION__;
+ if (m_depthShader)
+ delete m_depthShader;
+ m_depthShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexDepth"),
+ QStringLiteral(":/shaders/fragmentDepth"));
+ m_depthShader->initialize();
+}
+
+void Scatter3DRenderer::updateDepthBuffer()
+{
+ //qDebug() << __FUNCTION__;
+ if (m_depthTexture) {
+ m_textureHelper->deleteTexture(&m_depthTexture);
+ m_depthTexture = 0;
+ }
+
+ if (m_cachedShadowQuality > QDataVis::ShadowNone) {
+ m_depthTexture = m_textureHelper->createDepthTexture(m_mainViewPort.size(),
+ m_depthFrameBuffer,
+ m_cachedShadowQuality);
+ if (!m_depthTexture) {
+ switch (m_cachedShadowQuality) {
+ case QDataVis::ShadowHigh:
+ qWarning("Creating high quality shadows failed. Changing to medium quality.");
+ (void)m_controller->setShadowQuality(QDataVis::ShadowMedium);
+ break;
+ case QDataVis::ShadowMedium:
+ qWarning("Creating medium quality shadows failed. Changing to low quality.");
+ (void)m_controller->setShadowQuality(QDataVis::ShadowLow);
+ break;
+ case QDataVis::ShadowLow:
+ qWarning("Creating low quality shadows failed. Switching shadows off.");
+ (void)m_controller->setShadowQuality(QDataVis::ShadowNone);
+ break;
+ default:
+ // You'll never get here
+ break;
+ }
+ }
+ }
+}
+#endif
+
+void Scatter3DRenderer::initBackgroundShaders(const QString &vertexShader,
+ const QString &fragmentShader)
+{
+ //qDebug() << __FUNCTION__;
+ if (m_backgroundShader)
+ delete m_backgroundShader;
+ m_backgroundShader = new ShaderHelper(this, vertexShader, fragmentShader);
+ m_backgroundShader->initialize();
+}
+
+void Scatter3DRenderer::initLabelShaders(const QString &vertexShader, const QString &fragmentShader)
+{
+ //qDebug() << __FUNCTION__;
+ if (m_labelShader)
+ delete m_labelShader;
+ m_labelShader = new ShaderHelper(this, vertexShader, fragmentShader);
+ m_labelShader->initialize();
+}
+
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/engine/scatter3drenderer_p.h b/src/datavis3d/engine/scatter3drenderer_p.h
new file mode 100644
index 00000000..45054db4
--- /dev/null
+++ b/src/datavis3d/engine/scatter3drenderer_p.h
@@ -0,0 +1,178 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef Q3DSCATTERRENDERER_P_H
+#define Q3DSCATTERRENDERER_P_H
+
+#include <QtCore/QSize>
+#include <QtCore/QObject>
+#include <QtGui/QOpenGLFunctions>
+#include <QtGui/QFont>
+#include <QTime>
+#include <QWindow>
+#include <QMutex>
+
+#include "datavis3dglobal_p.h"
+#include "scatter3dcontroller_p.h"
+#include "abstract3drenderer_p.h"
+#include "qscatterdataproxy.h"
+#include "scatterrenderitem_p.h"
+
+//#define DISPLAY_RENDER_SPEED
+
+class QPoint;
+class QSizeF;
+class QOpenGLShaderProgram;
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class ShaderHelper;
+class ObjectHelper;
+class TextureHelper;
+class LabelItem;
+class CameraHelper;
+class QAbstractAxisPrivate;
+
+class QT_DATAVIS3D_EXPORT Scatter3DRenderer : public Abstract3DRenderer
+{
+ Q_OBJECT
+
+private:
+ // TODO: Filter to the set of attributes to be moved to the model object.
+ // * All GL rendering only related attribs should be moved out of this public set.
+ // * All attribs that are modifiable from QML need to e in this set.
+
+ Scatter3DController *m_controller;
+
+ // Mutex for sharing resources between render and main threads.
+ // TODO: this mutex needs to go, too
+ QMutex m_mutex;
+
+ // Internal state
+ ScatterRenderItem *m_selectedItem; // points to renderitem array
+ ScatterRenderItem *m_previouslySelectedItem; // points to renderitem array
+ bool m_xFlipped;
+ bool m_zFlipped;
+ bool m_yFlipped;
+ QRect m_mainViewPort;
+ bool m_updateLabels;
+ ShaderHelper *m_dotShader;
+ ShaderHelper *m_depthShader;
+ ShaderHelper *m_selectionShader;
+ ShaderHelper *m_backgroundShader;
+ ShaderHelper *m_labelShader;
+ ObjectHelper *m_dotObj;
+ ObjectHelper *m_backgroundObj;
+ ObjectHelper *m_gridLineObj;
+ ObjectHelper *m_labelObj;
+ TextureHelper *m_textureHelper;
+ GLuint m_bgrTexture;
+ GLuint m_depthTexture;
+ GLuint m_selectionTexture;
+ GLuint m_depthFrameBuffer;
+ GLuint m_selectionFrameBuffer;
+ GLuint m_selectionDepthBuffer;
+ GLfloat m_shadowQualityToShader;
+ GLfloat m_heightNormalizer;
+ GLfloat m_scaleFactor;
+ QVector3D m_selection;
+ QSizeF m_areaSize;
+ GLfloat m_dotSizeScale;
+
+ QPoint m_selectionPointRequest;
+ bool m_isSelectionPointRequestActive;
+
+ bool m_hasHeightAdjustmentChanged;
+ ScatterRenderItem m_dummyRenderItem;
+
+ ScatterRenderItemArray m_renderItemArray;
+
+#ifdef DISPLAY_RENDER_SPEED
+ bool m_isFirstFrame;
+ QTime m_lastFrameTime;
+ GLint m_numFrames;
+#endif
+
+public:
+ explicit Scatter3DRenderer(Scatter3DController *controller);
+ ~Scatter3DRenderer();
+
+ void updateDataModel(QScatterDataProxy *dataProxy);
+ void render(CameraHelper *camera, const GLuint defaultFboHandle);
+
+ QRect mainViewPort();
+
+public slots:
+ void updateBackgroundEnabled(bool enable);
+ void updateMeshFileName(const QString &objFileName);
+
+ // Overloaded from abstract renderer
+ virtual void updateAxisRange(QAbstractAxis::AxisOrientation orientation, qreal min, qreal max);
+
+ // Requests that upon next render pass the column and row under the given point is inspected for selection.
+ // Only one request can be queued per render pass at this point. New request will override any pending requests.
+ // After inspection the selectionUpdated signal is emitted.
+ virtual void requestSelectionAtPoint(const QPoint &point);
+
+signals:
+ void selectionUpdated(QVector3D selection);
+
+private:
+ virtual void initializeOpenGL();
+ virtual void initShaders(const QString &vertexShader, const QString &fragmentShader);
+ virtual void updateShadowQuality(QDataVis::ShadowQuality quality);
+ virtual void updateTextures();
+
+ void drawScene(CameraHelper *camera, const GLuint defaultFboHandle);
+ void handleResize();
+
+ void loadBarMesh();
+ void loadBackgroundMesh();
+ void loadGridLineMesh();
+ void loadLabelMesh();
+ void initSelectionShader();
+ void initBackgroundShaders(const QString &vertexShader, const QString &fragmentShader);
+ void initLabelShaders(const QString &vertexShader, const QString &fragmentShader);
+ void initSelectionBuffer();
+#if !defined(QT_OPENGL_ES_2)
+ void initDepthShader();
+ void updateDepthBuffer();
+#endif
+ void calculateTranslation(ScatterRenderItem &item);
+ void calculateSceneScalingFactors();
+ Scatter3DController::SelectionType isSelected(GLint bar, const QVector3D &selection);
+
+ Q_DISABLE_COPY(Scatter3DRenderer)
+
+ friend class ScatterRenderItem;
+};
+
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/engine/shaders/colorOnY_ES2.frag b/src/datavis3d/engine/shaders/colorOnY_ES2.frag
index dd7c0cf3..68c8ac39 100644
--- a/src/datavis3d/engine/shaders/colorOnY_ES2.frag
+++ b/src/datavis3d/engine/shaders/colorOnY_ES2.frag
@@ -31,5 +31,6 @@ void main() {
materialAmbientColor +
materialDiffuseColor * lightStrength * (cosTheta * cosTheta) / (distance * distance) +
materialSpecularColor * lightStrength * (cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha) / (distance * distance);
+ gl_FragColor.a = 1.0;
}
diff --git a/src/datavis3d/engine/shaders/selection.frag b/src/datavis3d/engine/shaders/selection.frag
index 1658b316..099c87a1 100644
--- a/src/datavis3d/engine/shaders/selection.frag
+++ b/src/datavis3d/engine/shaders/selection.frag
@@ -2,5 +2,6 @@ uniform highp vec3 color_mdl;
void main() {
gl_FragColor.rgb = color_mdl;
+ gl_FragColor.a = 1.0;
}
diff --git a/src/datavis3d/engine/shaders/surface.frag b/src/datavis3d/engine/shaders/surface.frag
new file mode 100644
index 00000000..9fe7f45b
--- /dev/null
+++ b/src/datavis3d/engine/shaders/surface.frag
@@ -0,0 +1,39 @@
+#version 120
+
+varying highp vec2 UV;
+varying highp vec3 coords_mdl;
+varying highp vec3 position_wrld;
+varying highp vec3 normal_cmr;
+varying highp vec3 eyeDirection_cmr;
+varying highp vec3 lightDirection_cmr;
+
+uniform sampler2D textureSampler;
+uniform highp vec3 lightPosition_wrld;
+uniform highp float lightStrength;
+uniform highp float ambientStrength;
+
+void main() {
+ highp vec2 gradientUV = vec2(0.5, (coords_mdl.y + 1.0) / 2.0);
+ highp vec3 materialDiffuseColor = texture2D(textureSampler, gradientUV).xyz;
+ highp vec3 materialAmbientColor = vec3(ambientStrength, ambientStrength, ambientStrength) * materialDiffuseColor;
+ highp vec3 materialSpecularColor = vec3(1.0, 1.0, 1.0);
+
+ highp float distance = length(lightPosition_wrld - position_wrld);
+
+ highp vec3 n = normalize(normal_cmr);
+ highp vec3 l = normalize(lightDirection_cmr);
+ highp float cosTheta = clamp(dot(n, l), 0.0, 1.0);
+
+ highp vec3 E = normalize(eyeDirection_cmr);
+ highp vec3 R = reflect(-l, n);
+ highp float cosAlpha = clamp(dot(E, R), 0.0, 1.0);
+
+// gl_FragColor.rgb = materialDiffuseColor;
+ gl_FragColor.rgb =
+ materialAmbientColor +
+ materialDiffuseColor * lightStrength * pow(cosTheta, 2) / distance +
+ materialSpecularColor * lightStrength * pow(cosAlpha, 10) / distance;
+ gl_FragColor.a = 1.0;
+// gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
+}
+
diff --git a/src/datavis3d/engine/shaders/surface.vert b/src/datavis3d/engine/shaders/surface.vert
new file mode 100644
index 00000000..cbfb7569
--- /dev/null
+++ b/src/datavis3d/engine/shaders/surface.vert
@@ -0,0 +1,30 @@
+#version 120
+
+attribute highp vec3 vertexPosition_mdl;
+attribute highp vec2 vertexUV;
+attribute highp vec3 vertexNormal_mdl;
+
+uniform highp mat4 MVP;
+uniform highp mat4 V;
+uniform highp mat4 M;
+uniform highp mat4 itM;
+uniform highp vec3 lightPosition_wrld;
+
+varying highp vec2 UV;
+varying highp vec3 position_wrld;
+varying highp vec3 normal_cmr;
+varying highp vec3 eyeDirection_cmr;
+varying highp vec3 lightDirection_cmr;
+varying highp vec3 coords_mdl;
+
+void main() {
+ gl_Position = MVP * vec4(vertexPosition_mdl, 1.0);
+ coords_mdl = vertexPosition_mdl;
+ position_wrld = (M * vec4(vertexPosition_mdl, 1.0)).xyz;
+ vec3 vertexPosition_cmr = (V * M * vec4(vertexPosition_mdl, 1.0)).xyz;
+ eyeDirection_cmr = vec3(0.0, 0.0, 0.0) - vertexPosition_cmr;
+ vec3 lightPosition_cmr = (V * vec4(lightPosition_wrld, 1.0)).xyz;
+ lightDirection_cmr = lightPosition_cmr + eyeDirection_cmr;
+ normal_cmr = (V * itM * vec4(vertexNormal_mdl, 0.0)).xyz;
+ UV = vertexUV;
+}
diff --git a/src/datavis3d/engine/shaders/surfaceFlat.frag b/src/datavis3d/engine/shaders/surfaceFlat.frag
new file mode 100644
index 00000000..eb398582
--- /dev/null
+++ b/src/datavis3d/engine/shaders/surfaceFlat.frag
@@ -0,0 +1,38 @@
+#version 150
+
+varying highp vec2 UV;
+varying highp vec3 coords_mdl;
+varying highp vec3 position_wrld;
+flat in highp vec3 normal_cmr;
+varying highp vec3 eyeDirection_cmr;
+varying highp vec3 lightDirection_cmr;
+
+uniform sampler2D textureSampler;
+uniform highp vec3 lightPosition_wrld;
+uniform highp float lightStrength;
+uniform highp float ambientStrength;
+
+void main() {
+ highp vec2 gradientUV = vec2(0.5, (coords_mdl.y + 1.0) / 2.0);
+ highp vec3 materialDiffuseColor = texture2D(textureSampler, gradientUV).xyz;
+ highp vec3 materialAmbientColor = vec3(ambientStrength, ambientStrength, ambientStrength) * materialDiffuseColor;
+ highp vec3 materialSpecularColor = vec3(1.0, 1.0, 1.0);
+
+ highp float distance = length(lightPosition_wrld - position_wrld);
+
+ highp vec3 n = normalize(normal_cmr);
+ highp vec3 l = normalize(lightDirection_cmr);
+ highp float cosTheta = clamp(dot(n, l), 0.0, 1.0);
+
+ highp vec3 E = normalize(eyeDirection_cmr);
+ highp vec3 R = reflect(-l, n);
+ highp float cosAlpha = clamp(dot(E, R), 0.0, 1.0);
+
+// gl_FragColor.rgb = materialDiffuseColor;
+ gl_FragColor.rgb =
+ materialAmbientColor +
+ materialDiffuseColor * lightStrength * pow(cosTheta, 2) / distance +
+ materialSpecularColor * lightStrength * pow(cosAlpha, 10) / distance;
+ gl_FragColor.a = 1.0;
+}
+
diff --git a/src/datavis3d/engine/shaders/surfaceFlat.vert b/src/datavis3d/engine/shaders/surfaceFlat.vert
new file mode 100644
index 00000000..24c9b9a3
--- /dev/null
+++ b/src/datavis3d/engine/shaders/surfaceFlat.vert
@@ -0,0 +1,30 @@
+#version 150
+
+attribute highp vec3 vertexPosition_mdl;
+attribute highp vec2 vertexUV;
+attribute highp vec3 vertexNormal_mdl;
+
+uniform highp mat4 MVP;
+uniform highp mat4 V;
+uniform highp mat4 M;
+uniform highp mat4 itM;
+uniform highp vec3 lightPosition_wrld;
+
+varying highp vec2 UV;
+varying highp vec3 position_wrld;
+flat out highp vec3 normal_cmr;
+varying highp vec3 eyeDirection_cmr;
+varying highp vec3 lightDirection_cmr;
+varying highp vec3 coords_mdl;
+
+void main() {
+ gl_Position = MVP * vec4(vertexPosition_mdl, 1.0);
+ coords_mdl = vertexPosition_mdl;
+ position_wrld = (M * vec4(vertexPosition_mdl, 1.0)).xyz;
+ vec3 vertexPosition_cmr = (V * M * vec4(vertexPosition_mdl, 1.0)).xyz;
+ eyeDirection_cmr = vec3(0.0, 0.0, 0.0) - vertexPosition_cmr;
+ vec3 lightPosition_cmr = (V * vec4(lightPosition_wrld, 1.0)).xyz;
+ lightDirection_cmr = lightPosition_cmr + eyeDirection_cmr;
+ normal_cmr = (V * itM * vec4(vertexNormal_mdl, 0.0)).xyz;
+ UV = vertexUV;
+}
diff --git a/src/datavis3d/engine/shaders/surfaceGrid.frag b/src/datavis3d/engine/shaders/surfaceGrid.frag
new file mode 100644
index 00000000..20b923fb
--- /dev/null
+++ b/src/datavis3d/engine/shaders/surfaceGrid.frag
@@ -0,0 +1,16 @@
+varying highp vec2 UV;
+varying highp vec2 coords_mdl;
+varying highp vec3 position_wrld;
+varying highp vec3 normal_cmr;
+varying highp vec3 eyeDirection_cmr;
+varying highp vec3 lightDirection_cmr;
+
+uniform highp vec3 lightPosition_wrld;
+uniform highp vec3 color_mdl;
+uniform highp float lightStrength;
+uniform highp float ambientStrength;
+
+void main() {
+ gl_FragColor.rgb = color_mdl;
+}
+
diff --git a/src/datavis3d/engine/shaders/surfaceGrid.vert b/src/datavis3d/engine/shaders/surfaceGrid.vert
new file mode 100644
index 00000000..efb40862
--- /dev/null
+++ b/src/datavis3d/engine/shaders/surfaceGrid.vert
@@ -0,0 +1,26 @@
+attribute highp vec3 vertexPosition_mdl;
+attribute highp vec2 vertexUV;
+attribute highp vec3 vertexNormal_mdl;
+
+uniform highp mat4 MVP;
+uniform highp mat4 V;
+uniform highp mat4 M;
+uniform highp mat4 itM;
+uniform highp vec3 lightPosition_wrld;
+
+varying highp vec3 position_wrld;
+varying highp vec3 normal_cmr;
+varying highp vec3 eyeDirection_cmr;
+varying highp vec3 lightDirection_cmr;
+varying highp vec2 coords_mdl;
+
+void main() {
+ gl_Position = MVP * vec4(vertexPosition_mdl, 1.0);
+ coords_mdl = vertexPosition_mdl.xy;
+ position_wrld = (M * vec4(vertexPosition_mdl, 1.0)).xyz;
+ vec3 vertexPosition_cmr = (V * M * vec4(vertexPosition_mdl, 1.0)).xyz;
+ eyeDirection_cmr = vec3(0.0, 0.0, 0.0) - vertexPosition_cmr;
+ vec3 lightPosition_cmr = (V * vec4(lightPosition_wrld, 1.0)).xyz;
+ lightDirection_cmr = lightPosition_cmr + eyeDirection_cmr;
+ normal_cmr = (V * itM * vec4(vertexNormal_mdl, 0.0)).xyz;
+}
diff --git a/src/datavis3d/engine/surface3dcontroller.cpp b/src/datavis3d/engine/surface3dcontroller.cpp
new file mode 100644
index 00000000..2915c993
--- /dev/null
+++ b/src/datavis3d/engine/surface3dcontroller.cpp
@@ -0,0 +1,211 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "surface3dcontroller_p.h"
+#include "surface3drenderer_p.h"
+#include "camerahelper_p.h"
+
+#include <QMatrix4x4>
+#include <QMouseEvent>
+
+#include <QDebug>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+Surface3dController::Surface3dController(QRect rect)
+ : Abstract3DController(rect),
+ m_mouseState(MouseNone),
+ m_mousePos(QPoint(0, 0)),
+ m_renderer(0),
+ m_isInitialized(false),
+ m_smoothSurface(false),
+ m_surfaceGrid(true)
+{
+}
+
+Surface3dController::~Surface3dController()
+{
+}
+
+void Surface3dController::initializeOpenGL()
+{
+ // Initialization is called multiple times when Qt Quick components are used
+ if (m_isInitialized)
+ return;
+
+ m_renderer = new Surface3dRenderer(this);
+ m_isInitialized = true;
+}
+
+void Surface3dController::synchDataToRenderer()
+{
+ // TODO: Implement
+}
+
+void Surface3dController::render(const GLuint defaultFboHandle)
+{
+ if (!m_isInitialized)
+ return;
+
+ m_renderer->render(m_cameraHelper, defaultFboHandle);
+}
+
+void Surface3dController::handleAxisAutoAdjustRangeChangedInOrientation(QAbstractAxis::AxisOrientation orientation, bool autoAdjust)
+{
+ Q_UNUSED(orientation)
+ Q_UNUSED(autoAdjust)
+
+ // TODO: Implement!
+}
+
+QMatrix4x4 Surface3dController::calculateViewMatrix(int zoom, int viewPortWidth, int viewPortHeight, bool showUnder)
+{
+ return m_cameraHelper->calculateViewMatrix(m_mousePos,
+ zoom,
+ viewPortWidth,
+ viewPortHeight,
+ showUnder);
+}
+
+void Surface3dController::setWidth(const int width)
+{
+ qDebug() << "Surface3dController::setWidth";
+ m_renderer->setWidth(width);
+}
+
+void Surface3dController::setHeight(const int height)
+{
+ qDebug() << "Surface3dController::setHeight";
+ m_renderer->setHeight(height);
+}
+
+void Surface3dController::setSmoothSurface(bool enable)
+{
+ m_smoothSurface = enable;
+ emit smoothStatusChanged(m_smoothSurface);
+}
+
+bool Surface3dController::smoothSurface()
+{
+ return m_smoothSurface;
+}
+
+void Surface3dController::setSurfaceGrid(bool enable)
+{
+ m_surfaceGrid = enable;
+ emit surfaceGridChanged(m_surfaceGrid);
+}
+
+bool Surface3dController::surfaceGrid()
+{
+ return m_surfaceGrid;
+}
+
+
+#if defined(Q_OS_ANDROID)
+void Surface3dController::mouseDoubleClickEvent(QMouseEvent *event)
+{
+}
+void touchEvent(QTouchEvent *event)
+{
+}
+#endif
+
+void Surface3dController::mousePressEvent(QMouseEvent *event, const QPoint &mousePos)
+{
+ if (Qt::LeftButton == event->button()) {
+ m_mousePos = mousePos;
+ emit leftMousePressed();
+ } else if (Qt::RightButton == event->button()) {
+ #if !defined(Q_OS_ANDROID)
+ m_mouseState = Abstract3DController::MouseRotating;
+ #else
+ m_mouseState = Abstract3DController::MouseOnScene;
+ #endif
+ // update mouse positions to prevent jumping when releasing or repressing a button
+ m_mousePos = mousePos; //event->pos();
+ }
+ m_cameraHelper->updateMousePos(m_mousePos);
+}
+
+void Surface3dController::mouseReleaseEvent(QMouseEvent *event, const QPoint &mousePos)
+{
+ Q_UNUSED(event)
+ if (Abstract3DController::MouseRotating == m_mouseState) {
+ // update mouse positions to prevent jumping when releasing or repressing a button
+ m_mousePos = mousePos; //event->pos();
+ m_cameraHelper->updateMousePos(mousePos); //event->pos());
+ }
+ m_mouseState = Abstract3DController::MouseNone;
+}
+
+void Surface3dController::mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos)
+{
+ Q_UNUSED(event)
+ if (Abstract3DController::MouseRotating == m_mouseState)
+ m_mousePos = mousePos; //event->pos();
+}
+
+void Surface3dController::wheelEvent(QWheelEvent *event)
+{
+ Q_UNUSED(event)
+}
+
+QPoint Surface3dController::mousePosition()
+{
+ return m_mousePos;
+}
+
+
+// TODO: abstract renderer should have accessor for Drawer instead
+Drawer *Surface3dController::drawer()
+{
+ if (m_renderer)
+ return m_renderer->drawer();
+ else
+ return 0;
+}
+
+void Surface3dController::setSegmentCount(GLint segmentCount, GLfloat step, GLfloat minimum)
+{
+ m_segmentCount = segmentCount;
+ m_segmentStep = step;
+ m_segmentMinimum = minimum;
+
+ emit segmentCountChanged(m_segmentCount, m_segmentStep, m_segmentMinimum);
+}
+
+void Surface3dController::setGradientColorAt(qreal pos, const QColor &color)
+{
+ Theme t = theme();
+ t.m_surfaceGradient.setColorAt(pos, color);
+ emit themeChanged(t);
+}
+
+// TODO: Temp
+void Surface3dController::setData(QList<qreal> series, int width, int depth)
+{
+ m_series = series;
+ m_dataWidth = width;
+ m_dataDepth = depth;
+
+ m_renderer->setXZStuff(width, depth);
+ m_renderer->setSeries(series);
+}
+
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/engine/surface3dcontroller_p.h b/src/datavis3d/engine/surface3dcontroller_p.h
new file mode 100644
index 00000000..d8c36d08
--- /dev/null
+++ b/src/datavis3d/engine/surface3dcontroller_p.h
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef SURFACE3DCONTROLLER_P_H
+#define SURFACE3DCONTROLLER_P_H
+
+#include "abstract3dcontroller_p.h"
+#include "datavis3dglobal_p.h"
+
+#include <QLinearGradient>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class Surface3dRenderer;
+
+class QT_DATAVIS3D_EXPORT Surface3dController : public Abstract3DController
+{
+ Q_OBJECT
+
+private:
+ Surface3dRenderer *m_renderer;
+ bool m_isInitialized;
+ QList<qreal> m_series; // TODO: TEMP
+ int m_dataWidth;
+ int m_dataDepth;
+ bool m_smoothSurface;
+ bool m_surfaceGrid;
+
+ GLint m_segmentCount;
+ GLfloat m_segmentStep;
+ GLfloat m_segmentMinimum;
+
+ // Interaction
+ MouseState m_mouseState;
+ QPoint m_mousePos;
+ QDataVis::SelectionMode m_selectionMode;
+
+public:
+ explicit Surface3dController(QRect rect);
+ ~Surface3dController();
+
+ void initializeOpenGL();
+ void synchDataToRenderer();
+ void render(const GLuint defaultFboHandle = 0);
+
+ QPoint mousePosition();
+
+ QMatrix4x4 calculateViewMatrix(int zoom, int viewPortWidth, int viewPortHeight, bool showUnder = false);
+
+ void setWidth(const int width);
+ void setHeight(const int height);
+
+ // Enable or disable the smoothes of the surface
+ void setSmoothSurface(bool enable);
+ bool smoothSurface();
+
+ // Enable or disable the grid on the surface
+ void setSurfaceGrid(bool enable);
+ bool surfaceGrid();
+
+ void setGradientColorAt(qreal pos, const QColor &color);
+
+ // Set segment count and step. Note; segmentCount * step should be the maximum possible value of data
+ // set. Minimum is the absolute minimum possible value a bar can have. This is especially
+ // important to set if values can be negative.
+ void setSegmentCount(GLint segmentCount, GLfloat step, GLfloat minimum = 0.0f);
+
+ //TODO: Temp solution
+ void setData(QList<qreal> series, int width, int depth);
+
+#if defined(Q_OS_ANDROID)
+ void mouseDoubleClickEvent(QMouseEvent *event);
+ void touchEvent(QTouchEvent *event);
+#endif
+ void mousePressEvent(QMouseEvent *event, const QPoint &mousePos);
+ void mouseReleaseEvent(QMouseEvent *event, const QPoint &mousePos);
+ void mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos);
+ void wheelEvent(QWheelEvent *event);
+
+ // TODO: abstract renderer should have accessor for Drawer instead
+ virtual Drawer *drawer();
+ virtual void handleAxisAutoAdjustRangeChangedInOrientation(QAbstractAxis::AxisOrientation orientation, bool autoAdjust);
+
+signals:
+ void smoothStatusChanged(bool enable);
+ void surfaceGridChanged(bool enable);
+ void segmentCountChanged(GLint segmentCount, GLfloat step, GLfloat minimum);
+ void leftMousePressed();
+
+private:
+ Q_DISABLE_COPY(Surface3dController)
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif // SURFACE3DCONTROLLER_P_H
diff --git a/src/datavis3d/engine/surface3drenderer.cpp b/src/datavis3d/engine/surface3drenderer.cpp
new file mode 100644
index 00000000..c66bd291
--- /dev/null
+++ b/src/datavis3d/engine/surface3drenderer.cpp
@@ -0,0 +1,894 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "surface3dcontroller_p.h"
+#include "surface3drenderer_p.h"
+#include "camerahelper_p.h"
+#include "shaderhelper_p.h"
+#include "objecthelper_p.h"
+#include "surfaceobject_p.h"
+#include "texturehelper_p.h"
+#include "theme_p.h"
+#include "utils_p.h"
+#include "drawer_p.h"
+
+#include <QMatrix4x4>
+#include <QMouseEvent>
+#include <qmath.h>
+
+#include <QLinearGradient>
+#include <QPainter>
+
+#include <QDebug>
+
+static const int ID_TO_RGBA_MASK = 0xff;
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+Surface3dRenderer::Surface3dRenderer(Surface3dController *controller)
+ : QObject(controller),
+ m_controller(controller),
+ m_mousePressed(MouseNone),
+ m_mousePos(QPoint(0, 0)),
+ m_isGridEnabled(true),
+ m_isBackgroundEnabled(true),
+ m_shadowQuality(QDataVis::ShadowLow),
+ m_labelTransparency(QDataVis::TransparencyFromTheme),
+ m_font(QFont(QStringLiteral("Arial"))),
+ m_hasNegativeValues(false),
+ m_segmentYCount(0),
+ m_segmentYStep(0.0f),
+ m_segmentXCount(0),
+ m_segmentZCount(0),
+ m_backgroundShader(0),
+ m_surfaceShader(0),
+ m_surfaceGridShader(0),
+ m_selectionShader(0),
+ m_isInitialized(false),
+ m_yRange(0.0f), // m_heightNormalizer
+ m_yAdjustment(0.0f),
+ m_xLength(0.0f),
+ m_zLength(0.0f),
+ m_maxDimension(0.0f),
+ m_scaleFactor(0.0f),
+ m_scaleX(0.0f),
+ m_scaleZ(0.0f),
+ m_maxSceneSize(40.0),
+ m_backgroundObj(0),
+ m_gridLineObj(0),
+ m_surfaceObj(0),
+ m_depthTexture(0),
+ m_depthFrameBuffer(0),
+ m_selectionFrameBuffer(0),
+ m_selectionDepthBuffer(0),
+ m_gradientTexture(0),
+ m_selectionTexture(0),
+ m_selectionResultTexture(0),
+ m_shadowQualityToShader(33.3f),
+ m_querySelection(false),
+ m_drawer(new Drawer(m_cachedTheme, m_font, m_labelTransparency))
+{
+ // Listen to changes in the controller
+ QObject::connect(m_controller, &Surface3dController::smoothStatusChanged, this,
+ &Surface3dRenderer::updateSmoothStatus);
+ QObject::connect(m_controller, &Surface3dController::surfaceGridChanged, this,
+ &Surface3dRenderer::updateSurfaceGridStatus);
+ QObject::connect(m_controller, &Surface3dController::segmentCountChanged, this,
+ &Surface3dRenderer::updateSegmentCount);
+ QObject::connect(m_controller, &Surface3dController::themeChanged, this,
+ &Surface3dRenderer::updateTheme);
+ QObject::connect(m_controller, &Surface3dController::leftMousePressed, this,
+ &Surface3dRenderer::getSelection);
+
+ m_cachedSmoothSurface = m_controller->smoothSurface();
+ updateSurfaceGridStatus(m_controller->surfaceGrid());
+ updateTheme(m_controller->theme());
+
+ initializeOpenGL();
+}
+
+Surface3dRenderer::~Surface3dRenderer()
+{
+ qDebug() << "Surface3dRenderer::~Surface3dRenderer()";
+ m_textureHelper->glDeleteFramebuffers(1, &m_depthFrameBuffer);
+ m_textureHelper->glDeleteRenderbuffers(1, &m_selectionDepthBuffer);
+ m_textureHelper->glDeleteFramebuffers(1, &m_selectionFrameBuffer);
+
+ m_textureHelper->deleteTexture(&m_depthTexture);
+ m_textureHelper->deleteTexture(&m_gradientTexture);
+ m_textureHelper->deleteTexture(&m_selectionTexture);
+ m_textureHelper->deleteTexture(&m_selectionResultTexture);
+
+ delete m_backgroundShader;
+ delete m_selectionShader;
+ delete m_surfaceShader;
+ delete m_surfaceGridShader;
+
+ delete m_backgroundObj;
+ delete m_surfaceObj;
+ delete m_textureHelper;
+ delete m_drawer;
+}
+
+void Surface3dRenderer::initializeOpenGL()
+{
+ // Initialization is called multiple times when Qt Quick components are used
+ if (m_isInitialized)
+ return;
+
+ initializeOpenGLFunctions();
+
+ m_textureHelper = new TextureHelper();
+ m_drawer->initializeOpenGL();
+
+ // Initialize shaders
+#if !defined(QT_OPENGL_ES_2)
+ if (m_shadowQuality > QDataVis::ShadowNone) {
+ initBackgroundShaders(QStringLiteral(":/shaders/vertexShadow"),
+ QStringLiteral(":/shaders/fragmentShadowNoTex"));
+ } else {
+ initBackgroundShaders(QStringLiteral(":/shaders/vertex"),
+ QStringLiteral(":/shaders/fragment"));
+ }
+#else
+ initBackgroundShaders(QStringLiteral(":/shaders/vertexES2"),
+ QStringLiteral(":/shaders/fragmentES2"));
+#endif
+
+ initSurfaceShaders();
+
+ // Init selection shader
+ initSelectionShaders();
+
+ // Load grid line mesh
+ loadGridLineMesh();
+
+ // Load label mesh
+ //loadLabelMesh();
+
+ // Set OpenGL features
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_LESS);
+ glEnable(GL_CULL_FACE);
+ glCullFace(GL_BACK);
+
+#if !defined(QT_OPENGL_ES_2)
+ glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
+ glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
+ glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
+#endif
+
+ // Set view port
+ glViewport(m_sliceViewPort.x(), m_sliceViewPort.y(),
+ m_sliceViewPort.width(), m_sliceViewPort.height());
+
+ // Set initialized -flag
+ m_isInitialized = true;
+
+ // Resize in case we've missed resize events
+ // Resize calls initSelectionBuffer and initDepthBuffer, so they don't need to be called here
+ handleResize();
+
+ // Load background mesh (we need to be initialized first)
+ loadBackgroundMesh();
+
+ //loadSurfaceObj();
+}
+
+void Surface3dRenderer::render(CameraHelper *camera, const GLuint defaultFboHandle)
+{
+ if (!m_isInitialized)
+ return;
+
+ if (defaultFboHandle) {
+ glDepthMask(true);
+ glEnable(GL_DEPTH_TEST);
+ glDepthFunc(GL_LESS);
+ glEnable(GL_CULL_FACE);
+ glCullFace(GL_BACK);
+ }
+
+ QVector3D clearColor = Utils::vectorFromColor(m_cachedTheme.m_windowColor);
+ glClearColor(clearColor.x(), clearColor.y(), clearColor.z(), 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ // TODO: bars have m_hasHeightAdjustmentChanged, which is always true!
+ // Set initial camera position
+ // X must be 0 for rotation to work - we can use "setCameraRotation" for setting it later
+ camera->setDefaultCameraOrientation(QVector3D(0.0f, 0.0f, 6.0f + zComp),
+ QVector3D(0.0f, 0.0f, zComp),
+ QVector3D(0.0f, 1.0f, 0.0f));
+
+ drawScene(camera, defaultFboHandle);
+}
+
+void Surface3dRenderer::drawScene(CameraHelper *camera, const GLuint defaultFboHandle)
+{
+ //qDebug() << "Surface3dRenderer::drawScene";
+
+ GLfloat backgroundRotation = 0;
+
+ // Specify viewport
+ glViewport(m_mainViewPort.x(), m_mainViewPort.y(),
+ m_mainViewPort.width(), m_mainViewPort.height());
+
+ // Set up projection matrix
+ QMatrix4x4 projectionMatrix;
+ projectionMatrix.perspective(45.0f, (GLfloat)m_mainViewPort.width()
+ / (GLfloat)m_mainViewPort.height(), 0.1f, 100.0f);
+
+ // Calculate view matrix
+ QMatrix4x4 viewMatrix = m_controller->calculateViewMatrix(
+ 100.0f, //TODO: m_zoomLevel * m_autoScaleAdjustment
+ m_mainViewPort.width(),
+ m_mainViewPort.height(),
+ m_hasNegativeValues);
+
+ // calculate background rotation based on view matrix rotation
+ if (viewMatrix.row(0).x() > 0 && viewMatrix.row(0).z() <= 0)
+ backgroundRotation = 270.0f;
+ else if (viewMatrix.row(0).x() > 0 && viewMatrix.row(0).z() > 0)
+ backgroundRotation = 180.0f;
+ else if (viewMatrix.row(0).x() <= 0 && viewMatrix.row(0).z() > 0)
+ backgroundRotation = 90.0f;
+ else if (viewMatrix.row(0).x() <= 0 && viewMatrix.row(0).z() <= 0)
+ backgroundRotation = 0.0f;
+
+ QVector3D lightPos = camera->calculateLightPosition(defaultLightPos);
+
+ QMatrix4x4 depthViewMatrix;
+ QMatrix4x4 depthProjectionMatrix;
+ depthProjectionMatrix = projectionMatrix; // TODO
+ depthViewMatrix.lookAt(lightPos, QVector3D(0.0f, -m_yAdjustment, zComp),
+ QVector3D(0.0f, 1.0f, 0.0f)); // TODO: Move
+
+ // Enable texturing
+ glEnable(GL_TEXTURE_2D);
+
+ //
+ // Do the surface drawing
+ //
+
+ if (m_querySelection && m_surfaceObj) {
+ m_selectionShader->bind();
+ glBindFramebuffer(GL_FRAMEBUFFER, m_selectionFrameBuffer);
+ glEnable(GL_DEPTH_TEST); // Needed, otherwise the depth render buffer is not used
+ glClearColor(0, 0, 0, 0);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Needed for clearing the frame buffer
+ glDisable(GL_DITHER); // disable dithering, it may affect colors if enabled
+
+ glDisable(GL_CULL_FACE);
+
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+
+ modelMatrix.translate(0.0f, 1.0f - m_yAdjustment, zComp);
+ modelMatrix.scale(QVector3D(m_xLength / m_scaleFactor,
+ 1.0f,
+ m_zLength / m_scaleFactor));
+
+ MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
+
+ m_selectionShader->setUniformValue(m_selectionShader->MVP(), MVPMatrix);
+
+ // Activate texture
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, m_selectionTexture);
+ m_selectionShader->setUniformValue(m_selectionShader->texture(), 0);
+
+ // 1st attribute buffer : vertices
+ glEnableVertexAttribArray(m_selectionShader->posAtt());
+ glBindBuffer(GL_ARRAY_BUFFER, m_surfaceObj->vertexBuf());
+ glVertexAttribPointer(m_selectionShader->posAtt(), 3, GL_FLOAT, GL_FALSE, 0, (void *)0);
+
+ // 3rd attribute buffer : UVs
+ glEnableVertexAttribArray(m_selectionShader->uvAtt());
+ glBindBuffer(GL_ARRAY_BUFFER, m_surfaceObj->uvBuf());
+ glVertexAttribPointer(m_selectionShader->uvAtt(), 2, GL_FLOAT, GL_FALSE, 0, (void *)0);
+
+ // Index buffer
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_surfaceObj->elementBuf());
+
+ // Draw the triangles
+ glDrawElements(GL_TRIANGLES, m_surfaceObj->indexCount(), m_surfaceObj->indicesType(), (void *)0);
+ //m_drawer->drawObject(m_selectionShader, m_surfaceObj, m_selectionTexture, 0);
+
+ // Free buffers
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ glDisableVertexAttribArray(m_selectionShader->uvAtt());
+ glDisableVertexAttribArray(m_selectionShader->posAtt());
+
+ glEnable(GL_DITHER);
+
+ m_querySelection = false;
+
+ QPoint point = m_controller->mousePosition();
+ GLubyte pixel[4] = {0};
+ glReadPixels(point.x(), height() - point.y(), 1, 1,
+ GL_RGBA, GL_UNSIGNED_BYTE, (void *)pixel);
+ //uint id = pixel[0] + pixel[1] * 256 + pixel[2] * 65536 + pixel[3] * 16777216;
+
+ qDebug() << "pixel = " << pixel[0] << ", " << pixel[1] << ", " << pixel[2] << ", " << pixel[3];
+
+ glBindFramebuffer(GL_FRAMEBUFFER, defaultFboHandle);
+
+ // Release selection shader
+ m_selectionShader->release();
+ }
+
+ if (m_surfaceObj) {
+ m_surfaceShader->bind();
+ // m_selectionShader->bind(); // IFDEF print selection
+
+ // For surface we can see climpses from underneath
+ glDisable(GL_CULL_FACE);
+
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+ QMatrix4x4 depthMVPMatrix;
+ QMatrix4x4 itModelMatrix;
+
+ modelMatrix.translate(0.0f, 1.0f - m_yAdjustment, zComp);
+ modelMatrix.scale(QVector3D(m_xLength / m_scaleFactor,
+ 1.0f,
+ m_zLength / m_scaleFactor));
+ itModelMatrix.scale(QVector3D(m_xLength / m_scaleFactor,
+ 1.0f,
+ m_zLength / m_scaleFactor));
+
+#ifdef SHOW_DEPTH_TEXTURE_SCENE
+ MVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
+#else
+ MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
+#endif
+ // TODO Check the usage?
+ depthMVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
+
+ // Set shader bindings
+ m_surfaceShader->setUniformValue(m_surfaceShader->lightP(), lightPos);
+ m_surfaceShader->setUniformValue(m_surfaceShader->view(), viewMatrix);
+ m_surfaceShader->setUniformValue(m_surfaceShader->model(), modelMatrix);
+ m_surfaceShader->setUniformValue(m_surfaceShader->nModel(), itModelMatrix.inverted().transposed());
+ m_surfaceShader->setUniformValue(m_surfaceShader->MVP(), MVPMatrix);
+ //m_selectionShader->setUniformValue(m_selectionShader->MVP(), MVPMatrix); // IFDEF print selection
+ m_surfaceShader->setUniformValue(m_surfaceShader->ambientS(), m_cachedTheme.m_ambientStrength);
+
+ //IF QT_OPENGL_ES_2 TODO
+ // Shadow quality etc.
+ //m_backgroundShader->setUniformValue(m_backgroundShader->shadowQ(), m_shadowQualityToShader);
+ //m_backgroundShader->setUniformValue(m_backgroundShader->depth(), depthMVPMatrix);
+ m_surfaceShader->setUniformValue(m_surfaceShader->lightS(),
+ m_cachedTheme.m_lightStrength * 2.0f);
+
+ m_drawer->drawObject(m_surfaceShader, m_surfaceObj, m_gradientTexture, m_depthTexture);
+ //m_drawer->drawObject(m_selectionShader, m_surfaceObj, m_selectionTexture, 0); // IFDEF print selection
+
+ m_surfaceShader->release();
+ //m_selectionShader->release(); // IFDEF print selection
+
+ if (m_cachedSurfaceGridOn) {
+ // Draw the grid over the surface
+ glPolygonOffset(1.0f, 1.0f);
+ glEnable(GL_POLYGON_OFFSET_FILL);
+
+ m_surfaceGridShader->bind();
+
+ QVector3D gridColor = Utils::vectorFromColor(QColor(Qt::white));
+ // Set shader bindings
+ m_surfaceGridShader->setUniformValue(m_surfaceGridShader->view(), viewMatrix);
+ m_surfaceGridShader->setUniformValue(m_surfaceGridShader->model(), modelMatrix);
+ m_surfaceGridShader->setUniformValue(m_surfaceGridShader->nModel(), itModelMatrix.inverted().transposed());
+ m_surfaceGridShader->setUniformValue(m_surfaceGridShader->MVP(), MVPMatrix);
+ m_surfaceGridShader->setUniformValue(m_surfaceGridShader->color(), gridColor);
+ //m_surfaceGridShader->setUniformValue(m_surfaceGridShader->ambientS(), m_theme->m_ambientStrength);
+ m_drawer->drawSurfaceGrid(m_surfaceGridShader, m_surfaceObj);
+
+ m_surfaceGridShader->release();
+
+ glPolygonOffset(0.0f, 0.0f);
+ glDisable(GL_POLYGON_OFFSET_FILL);
+ }
+ }
+
+ // Bind background shader
+ m_backgroundShader->bind();
+
+ if (m_hasNegativeValues)
+ glDisable(GL_CULL_FACE);
+ else
+ glCullFace(GL_BACK);
+
+ // Draw background
+ if (m_isBackgroundEnabled && m_backgroundObj) {
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+ QMatrix4x4 depthMVPMatrix;
+ QMatrix4x4 itModelMatrix;
+
+ modelMatrix.translate(0.0f, 1.0f - m_yAdjustment, zComp);
+ modelMatrix.scale(QVector3D(m_xLength / m_scaleFactor,
+ 1.0f,
+ m_zLength / m_scaleFactor));
+ modelMatrix.rotate(backgroundRotation, 0.0f, 1.0f, 0.0f);
+ itModelMatrix.scale(QVector3D(m_xLength / m_scaleFactor,
+ 1.0f,
+ m_zLength / m_scaleFactor));
+
+#ifdef SHOW_DEPTH_TEXTURE_SCENE
+ MVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
+#else
+ MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
+#endif
+ depthMVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
+
+ QVector3D backgroundColor = Utils::vectorFromColor(m_cachedTheme.m_backgroundColor);
+
+ // Set shader bindings
+ m_backgroundShader->setUniformValue(m_backgroundShader->lightP(), lightPos);
+ m_backgroundShader->setUniformValue(m_backgroundShader->view(), viewMatrix);
+ m_backgroundShader->setUniformValue(m_backgroundShader->model(), modelMatrix);
+ m_backgroundShader->setUniformValue(m_backgroundShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ m_backgroundShader->setUniformValue(m_backgroundShader->MVP(), MVPMatrix);
+ m_backgroundShader->setUniformValue(m_backgroundShader->color(), backgroundColor);
+ m_backgroundShader->setUniformValue(m_backgroundShader->ambientS(),
+ m_cachedTheme.m_ambientStrength * 2.0f);
+
+#if !defined(QT_OPENGL_ES_2)
+ if (m_shadowQuality > QDataVis::ShadowNone) {
+ // Set shadow shader bindings
+ m_backgroundShader->setUniformValue(m_backgroundShader->shadowQ(),
+ m_shadowQualityToShader);
+ m_backgroundShader->setUniformValue(m_backgroundShader->depth(), depthMVPMatrix);
+ m_backgroundShader->setUniformValue(m_backgroundShader->lightS(),
+ m_cachedTheme.m_lightStrength / 10.0f);
+
+ // Draw the object
+ m_drawer->drawObject(m_backgroundShader, m_backgroundObj, 0, m_depthTexture);
+ } else
+#endif
+ {
+ // Set shadowless shader bindings
+ m_backgroundShader->setUniformValue(m_backgroundShader->lightS(),
+ m_cachedTheme.m_lightStrength);
+
+ // Draw the object
+ m_drawer->drawObject(m_backgroundShader, m_backgroundObj);
+ }
+ }
+
+ // Release background shader
+ m_backgroundShader->release();
+
+ // Disable textures
+ glDisable(GL_TEXTURE_2D);
+
+ // Reset culling
+ if (m_hasNegativeValues) {
+ glEnable(GL_CULL_FACE);
+ glCullFace(GL_BACK);
+ }
+}
+
+void Surface3dRenderer::updateSegmentCount(GLint segmentCount, GLfloat step, GLfloat minimum)
+{
+ m_segmentYCount = segmentCount;
+ m_segmentYStep = step;
+ if (segmentCount > 0 && step > 0.0) {
+ m_yRange = m_segmentYCount * m_segmentYStep;
+ m_yAdjustment = 2.0f - ((m_yRange - minimum) / m_yRange); // TODO: to function
+ }
+
+ qDebug() << "m_yAdjustment = " << m_yAdjustment;
+}
+
+void Surface3dRenderer::setXZStuff(GLint segmentXCount, GLint segmentZCount)
+{
+ m_segmentXCount = segmentXCount;
+ m_segmentZCount = segmentZCount;
+
+ // TODO: Invent "idiotproof" max scene size formula..
+ // This seems to work ok if spacing is not negative (and row/column or column/row ratio is not too high)
+ m_maxSceneSize = 2 * qSqrt(segmentXCount * segmentZCount);
+
+ calculateSceneScalingFactors();
+}
+
+void Surface3dRenderer::updateTheme(Theme theme)
+{
+ m_cachedTheme.setFromTheme(theme);
+
+ // Update things depending from the theme
+ updateSurfaceGradient();
+}
+
+void Surface3dRenderer::updateSurfaceGradient()
+{
+ QImage image(QSize(4, 100), QImage::Format_RGB32);
+ QPainter pmp(&image);
+ pmp.setBrush(QBrush(m_cachedTheme.m_surfaceGradient));
+ pmp.setPen(Qt::NoPen);
+ pmp.drawRect(0, 0, 4, 100);
+
+ // QImage image(QStringLiteral("C:\\Users\\misalmel\\Work\\gerrit\\qtdatavis3d_2\\grid.png"));
+
+ if (m_gradientTexture) {
+ m_textureHelper->deleteTexture(&m_gradientTexture);
+ m_gradientTexture = 0;
+ }
+
+ m_gradientTexture = m_textureHelper->create2DTexture(image, false, true);
+}
+
+void Surface3dRenderer::updateSelectionTexture()
+{
+ // Create the selection ID image. Each grid corner gets 2x2 pixel area of
+ // ID color so that each vertex (data point) has 4x4 pixel area of ID color
+ // TODO: power of two thing for ES
+ int idImageWidth = (m_segmentXCount - 1) * 4;
+ int idImageHeight = (m_segmentZCount - 1) * 4;
+ int stride = idImageWidth * 4 * sizeof(uchar); // 4 = number of color components (rgba)
+
+ uchar *bits = new uchar[idImageWidth * idImageHeight * 4 * sizeof(uchar)];
+ uint id = 1;
+ for (int i = 0; i < idImageHeight; i += 4) {
+ for (int j = 0; j < idImageWidth; j += 4) {
+ int p = (i * idImageWidth + j) * 4;
+ uchar r, g, b, a;
+ idToRGBA(id, &r, &g, &b, &a);
+ fillIdCorner(&bits[p], r, g, b, a, stride);
+
+ idToRGBA(id + 1, &r, &g, &b, &a);
+ fillIdCorner(&bits[p + 8], r, g, b, a, stride);
+
+ idToRGBA(id + m_segmentXCount, &r, &g, &b, &a);
+ fillIdCorner(&bits[p + 2 * stride], r, g, b, a, stride);
+
+ idToRGBA(id + m_segmentXCount + 1, &r, &g, &b, &a);
+ fillIdCorner(&bits[p + 2 * stride + 8], r, g, b, a, stride);
+
+ id++;
+ }
+ id++;
+ }
+
+ // Use this to save the ID image to file
+ //QImage image(bits, idImageWidth, idImageHeight, QImage::Format_ARGB32);
+ //image.save("C:\\Users\\misalmel\\Work\\gerrit\\qtdatavis3d_2\\selection.png");
+
+ // If old texture exists, delete it
+ if (m_selectionTexture) {
+ m_textureHelper->deleteTexture(&m_selectionTexture);
+ m_selectionTexture = 0;
+ }
+
+ // Move the ID image (bits) to the texture
+ m_selectionTexture = m_textureHelper->create2DTexture(bits, idImageWidth, idImageHeight);
+
+ // Release the temp bits allocation
+ delete bits;
+
+ // Create the result selection texture and buffers
+ if (m_selectionResultTexture) {
+ m_textureHelper->deleteTexture(&m_selectionResultTexture);
+ m_selectionResultTexture = 0;
+ }
+
+ m_selectionResultTexture = m_textureHelper->createSelectionTexture(m_mainViewPort.size(),
+ m_selectionFrameBuffer,
+ m_selectionDepthBuffer);
+}
+
+void Surface3dRenderer::fillIdCorner(uchar *p, uchar r, uchar g, uchar b, uchar a, int stride)
+{
+ p[0] = r;
+ p[1] = g;
+ p[2] = b;
+ p[3] = a;
+ p[4] = r;
+ p[5] = g;
+ p[6] = b;
+ p[7] = a;
+ p[stride + 0] = r;
+ p[stride + 1] = g;
+ p[stride + 2] = b;
+ p[stride + 3] = a;
+ p[stride + 4] = r;
+ p[stride + 5] = g;
+ p[stride + 6] = b;
+ p[stride + 7] = a;
+}
+
+void Surface3dRenderer::idToRGBA(uint id, uchar *r, uchar *g, uchar *b, uchar *a)
+{
+ *r = id & ID_TO_RGBA_MASK;
+ *g = (id >> 8) & ID_TO_RGBA_MASK;
+ *b = (id >> 16) & ID_TO_RGBA_MASK;
+ *a = (id >> 24) & ID_TO_RGBA_MASK;
+}
+
+void Surface3dRenderer::getSelection()
+{
+ qDebug() << "Surface3dRenderer::getSelection";
+ m_querySelection = true;
+}
+
+void Surface3dRenderer::setSeries(QList<qreal> series)
+{
+ m_series = series;
+
+ // TODO temp solution
+ if (!m_surfaceObj)
+ loadSurfaceObj();
+
+ if (m_cachedSmoothSurface)
+ m_surfaceObj->setUpSmoothData(series, m_segmentXCount, m_segmentZCount, m_yRange, true);
+ else
+ m_surfaceObj->setUpData(series, m_segmentXCount, m_segmentZCount, m_yRange, true);
+
+ updateSelectionTexture();
+}
+
+void Surface3dRenderer::calculateSceneScalingFactors()
+{
+ // Calculate scene scaling and translation factors
+ // m_rowWidth = ((m_columnCount + 1) * m_barSpacing.width()) / 2.0f;
+ // m_columnDepth = ((m_rowCount + 1) * m_barSpacing.height()) / 2.0f;
+ // m_maxDimension = qMax(m_rowWidth, m_columnDepth);
+ // m_scaleFactor = qMin((m_columnCount * (m_maxDimension / m_maxSceneSize)),
+ // (m_rowCount * (m_maxDimension / m_maxSceneSize)));
+ // m_scaleX = m_barThickness.width() / m_scaleFactor;
+ // m_scaleZ = m_barThickness.height() / m_scaleFactor;
+
+ m_xLength = m_segmentXCount;
+ m_zLength = m_segmentZCount;
+ m_maxDimension = qMax(m_xLength, m_zLength);
+ m_scaleFactor = qMin((m_segmentXCount * (m_maxDimension / m_maxSceneSize)),
+ (m_segmentZCount * (m_maxDimension / m_maxSceneSize)));
+ m_scaleX = 1.0f / m_scaleFactor; // TODO: correspondance to m_barThickness
+ m_scaleZ = 1.0f / m_scaleFactor; // TODO: correspondance to m_barThickness
+
+ //qDebug() << "m_scaleX" << m_scaleX << "m_scaleFactor" << m_scaleFactor;
+ //qDebug() << "m_scaleZ" << m_scaleZ << "m_scaleFactor" << m_scaleFactor;
+ //qDebug() << "m_rowWidth:" << m_rowWidth << "m_columnDepth:" << m_columnDepth << "m_maxDimension:" << m_maxDimension;
+}
+
+void Surface3dRenderer::updateSmoothStatus(bool enable)
+{
+ m_cachedSmoothSurface = enable;
+
+ if (!m_surfaceObj)
+ return;
+
+ if (m_cachedSmoothSurface)
+ m_surfaceObj->setUpSmoothData(m_series, m_segmentXCount, m_segmentZCount, m_yRange, true);
+ else
+ m_surfaceObj->setUpData(m_series, m_segmentXCount, m_segmentZCount, m_yRange, true);
+
+ initSurfaceShaders();
+}
+
+void Surface3dRenderer::updateSurfaceGridStatus(bool enable)
+{
+ m_cachedSurfaceGridOn = enable;
+}
+
+void Surface3dRenderer::loadBackgroundMesh()
+{
+ if (!m_isInitialized)
+ return;
+
+ if (m_backgroundObj)
+ delete m_backgroundObj;
+ if (m_hasNegativeValues)
+ m_backgroundObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/negativeBackground"));
+ else
+ m_backgroundObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/background"));
+ m_backgroundObj->load();
+}
+
+void Surface3dRenderer::loadSurfaceObj()
+{
+ if (!m_isInitialized)
+ return;
+
+ if (m_surfaceObj)
+ delete m_surfaceObj;
+ m_surfaceObj = new SurfaceObject();
+ //m_surfaceObj->setUpData();
+}
+
+void Surface3dRenderer::loadGridLineMesh()
+{
+ if (m_gridLineObj)
+ delete m_gridLineObj;
+ m_gridLineObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/bar"));
+ m_gridLineObj->load();
+}
+
+const QSize Surface3dRenderer::size()
+{
+ return m_boundingRect.size();
+}
+
+const QRect Surface3dRenderer::boundingRect()
+{
+ return m_boundingRect;
+}
+
+void Surface3dRenderer::setBoundingRect(const QRect boundingRect)
+{
+ m_boundingRect = boundingRect;
+ handleResize();
+}
+
+void Surface3dRenderer::setWidth(const int width)
+{
+ m_boundingRect.setWidth(width);
+ handleResize();
+}
+
+int Surface3dRenderer::width()
+{
+ return m_boundingRect.width();
+}
+
+void Surface3dRenderer::setHeight(const int height)
+{
+ m_boundingRect.setHeight(height);
+ handleResize();
+}
+
+int Surface3dRenderer::height()
+{
+ return m_boundingRect.height();
+}
+
+void Surface3dRenderer::setX(const int x)
+{
+ m_boundingRect.setX(x);
+}
+
+int Surface3dRenderer::x()
+{
+ return m_boundingRect.x();
+}
+
+void Surface3dRenderer::setY(const int y)
+{
+ m_boundingRect.setY(y);
+}
+
+int Surface3dRenderer::y()
+{
+ return m_boundingRect.y();
+}
+
+void Surface3dRenderer::handleResize()
+{
+ if (!m_isInitialized)
+ return;
+
+ qDebug() << "Surface3dRenderer::handleResize " << width() << "x" << height();
+
+ m_mainViewPort = QRect(0, 0, width(), height());
+ m_sliceViewPort = QRect(0, 0, width(), height());
+
+#if !defined(QT_OPENGL_ES_2)
+ // Re-init depth buffer
+ updateDepthBuffer();
+#endif
+}
+
+#if !defined(QT_OPENGL_ES_2)
+void Surface3dRenderer::updateDepthBuffer()
+{
+ if (m_depthTexture) {
+ m_textureHelper->deleteTexture(&m_depthTexture);
+ m_depthTexture = 0;
+ }
+
+ // TODO: bars uses some m_cachedShadowQuality
+ if (m_shadowQuality > QDataVis::ShadowNone && !m_mainViewPort.size().isEmpty()) {
+ m_depthTexture = m_textureHelper->createDepthTexture(m_mainViewPort.size(),
+ m_depthFrameBuffer,
+ m_shadowQuality);
+ if (!m_depthTexture) {
+ qDebug() << "Failed to create m_depthTexture";
+ // switch (m_shadowQuality) {
+ // case ShadowHigh:
+ // qWarning("Creating high quality shadows failed. Changing to medium quality.");
+ // (void)setShadowQuality(ShadowMedium);
+ // break;
+ // case ShadowMedium:
+ // qWarning("Creating medium quality shadows failed. Changing to low quality.");
+ // (void)setShadowQuality(ShadowLow);
+ // break;
+ // case ShadowLow:
+ // qWarning("Creating low quality shadows failed. Switching shadows off.");
+ // (void)setShadowQuality(ShadowNone);
+ // break;
+ // default:
+ // // You'll never get here
+ // break;
+ // }
+ }
+ }
+}
+#endif
+
+void Surface3dRenderer::initBackgroundShaders(const QString &vertexShader,
+ const QString &fragmentShader)
+{
+ if (m_backgroundShader)
+ delete m_backgroundShader;
+ m_backgroundShader = new ShaderHelper(this, vertexShader, fragmentShader);
+ m_backgroundShader->initialize();
+}
+
+void Surface3dRenderer::initSelectionShaders()
+{
+ if (m_selectionShader)
+ delete m_selectionShader;
+ m_selectionShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexLabel"),
+ QStringLiteral(":/shaders/fragmentLabel"));
+ m_selectionShader->initialize();
+}
+
+void Surface3dRenderer::initSurfaceShaders()
+{
+ if (m_surfaceShader)
+ delete m_surfaceShader;
+ if (m_cachedSmoothSurface) {
+ m_surfaceShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexSurface"),
+ QStringLiteral(":/shaders/fragmentSurface"));
+ } else {
+ m_surfaceShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexSurfaceFlat"),
+ QStringLiteral(":/shaders/fragmentSurfaceFlat"));
+ }
+ m_surfaceShader->initialize();
+
+ if (m_surfaceGridShader)
+ delete m_surfaceGridShader;
+ m_surfaceGridShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexSurfaceGrid"),
+ QStringLiteral(":/shaders/fragmentSurfaceGrid"));
+ m_surfaceGridShader->initialize();
+}
+
+QT_DATAVIS3D_END_NAMESPACE
+
+
+//p = 90;
+//qDebug() << "rgba = " << bits[p + 0] << ", " << bits[p + 1] << ", " <<
+// bits[p + 2] << ", " << bits[p + 3];
+//p += 4;
+//qDebug() << "rgba = " << bits[p + 0] << ", " << bits[p + 1] << ", " <<
+// bits[p + 2] << ", " << bits[p + 3];
+//p += 4;
+//qDebug() << "rgba = " << bits[p + 0] << ", " << bits[p + 1] << ", " <<
+// bits[p + 2] << ", " << bits[p + 3];
+//p += 4;
+//qDebug() << "rgba = " << bits[p + 0] << ", " << bits[p + 1] << ", " <<
+// bits[p + 2] << ", " << bits[p + 3];
+//p += 4;
+//qDebug() << "rgba = " << bits[p + 0] << ", " << bits[p + 1] << ", " <<
+// bits[p + 2] << ", " << bits[p + 3];
+//p += 4;
+
diff --git a/src/datavis3d/engine/surface3drenderer_p.h b/src/datavis3d/engine/surface3drenderer_p.h
new file mode 100644
index 00000000..f2fb120a
--- /dev/null
+++ b/src/datavis3d/engine/surface3drenderer_p.h
@@ -0,0 +1,189 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef SURFACE3DRENDERER_P_H
+#define SURFACE3DRENDERER_P_H
+
+#include <QtCore/QSize>
+#include <QtCore/QObject>
+#include <QtGui/QOpenGLFunctions>
+#include <QtGui/QFont>
+#include <QLinearGradient>
+#include <QWindow>
+
+#include "datavis3dglobal_p.h"
+#include "surface3dcontroller_p.h"
+
+class QOpenGLShaderProgram;
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class ShaderHelper;
+class ObjectHelper;
+class SurfaceObject;
+class TextureHelper;
+class Theme;
+class Drawer;
+class CameraHelper;
+
+class QT_DATAVIS3D_EXPORT Surface3dRenderer : public QObject, protected QOpenGLFunctions
+{
+ Q_OBJECT
+
+public:
+ enum MousePressType {
+ MouseNone = 0,
+ MouseOnScene,
+ MouseOnOverview,
+ MouseOnZoom,
+ MouseRotating,
+ MouseOnPinch
+ };
+
+ Surface3dController *m_controller;
+
+ // Interaction related parameters // TODO: Moved to controller
+ MousePressType m_mousePressed;
+ QPoint m_mousePos;
+ QDataVis::SelectionMode m_selectionMode;
+
+ // Visual parameters
+ QRect m_boundingRect;
+ Theme m_cachedTheme;
+ QDataVis::LabelTransparency m_labelTransparency;
+ QFont m_font;
+ bool m_isGridEnabled;
+ bool m_isBackgroundEnabled;
+ QDataVis::ShadowQuality m_shadowQuality;
+ bool m_hasNegativeValues;
+
+private:
+ // Data parameters
+ QList<qreal> m_series; // TODO: TEMP
+ GLint m_segmentYCount;
+ GLfloat m_segmentYStep;
+ GLint m_segmentXCount;
+ GLint m_segmentZCount;
+
+ // Internal attributes purely related to how the scene is drawn with GL.
+ QRect m_mainViewPort;
+ QRect m_sliceViewPort;
+ ShaderHelper *m_backgroundShader;
+ ShaderHelper *m_surfaceShader;
+ ShaderHelper *m_surfaceGridShader;
+ ShaderHelper *m_selectionShader;
+ TextureHelper *m_textureHelper;
+ bool m_isInitialized;
+ GLfloat m_yRange; // m_heightNormalizer
+ GLfloat m_yAdjustment;
+ GLfloat m_xLength;
+ GLfloat m_zLength;
+ GLfloat m_maxDimension;
+ GLfloat m_scaleFactor;
+ GLfloat m_scaleX;
+ GLfloat m_scaleZ;
+ GLfloat m_maxSceneSize;
+ ObjectHelper *m_backgroundObj;
+ ObjectHelper *m_gridLineObj;
+ SurfaceObject *m_surfaceObj;
+ GLuint m_depthTexture;
+ GLuint m_depthFrameBuffer;
+ GLuint m_selectionFrameBuffer;
+ GLuint m_selectionDepthBuffer;
+ GLuint m_gradientTexture;
+ GLuint m_selectionTexture;
+ GLuint m_selectionResultTexture;
+ GLfloat m_shadowQualityToShader;
+ bool m_querySelection;
+ bool m_cachedSmoothSurface;
+ bool m_cachedSurfaceGridOn;
+
+ Drawer *m_drawer;
+
+public:
+ explicit Surface3dRenderer(Surface3dController *controller);
+ ~Surface3dRenderer();
+
+ void initializeOpenGL();
+ void render(CameraHelper *camera, const GLuint defaultFboHandle = 0);
+
+ // TODO: Not thread-safe, needs rethinking how axes create labels
+ Drawer *drawer() { return m_drawer; }
+
+public slots:
+ void updateTheme(Theme theme);
+ void updateSmoothStatus(bool enable);
+ void updateSurfaceGridStatus(bool enable);
+ void updateSurfaceGradient();
+ void updateSegmentCount(GLint segmentCount, GLfloat step, GLfloat minimum = 0.0f);
+
+ void getSelection();
+
+public:
+ // Size
+ const QSize size();
+ const QRect boundingRect();
+ void setBoundingRect(const QRect boundingRect);
+ void setWidth(const int width);
+ int width();
+ void setHeight(const int height);
+ int height();
+ void setX(const int x);
+ int x();
+ void setY(const int y);
+ int y();
+
+ void handleResize();
+
+#if !defined(QT_OPENGL_ES_2)
+ void updateDepthBuffer();
+#endif
+ void loadBackgroundMesh();
+ void loadGridLineMesh();
+ void loadSurfaceObj();
+
+ // TODO: temp
+ void setXZStuff(GLint segmentXCount, GLint segmentZCount);
+ void setSeries(QList<qreal> series);
+
+private:
+ void drawScene(CameraHelper *camera, const GLuint defaultFboHandle);
+ void calculateSceneScalingFactors();
+ void initBackgroundShaders(const QString &vertexShader, const QString &fragmentShader);
+ void initSelectionShaders();
+ void initSurfaceShaders();
+ void updateSelectionTexture();
+ void idToRGBA(uint id, uchar *r, uchar *g, uchar *b, uchar *a);
+ void fillIdCorner(uchar *p, uchar r, uchar g, uchar b, uchar a, int stride);
+
+ Q_DISABLE_COPY(Surface3dRenderer)
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif // SURFACE3DRENDERER_P_H
diff --git a/src/datavis3d/engine/theme.cpp b/src/datavis3d/engine/theme.cpp
index 4a258b67..7b2cb210 100644
--- a/src/datavis3d/engine/theme.cpp
+++ b/src/datavis3d/engine/theme.cpp
@@ -1,41 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
@@ -46,7 +23,7 @@
#include <stdio.h>
#endif
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVIS3D_BEGIN_NAMESPACE
Theme::Theme()
: m_baseColor(QColor(Qt::gray)),
@@ -60,21 +37,32 @@ Theme::Theme()
m_highlightBarColor(QColor(Qt::red)),
m_highlightRowColor(QColor(Qt::darkRed)),
m_highlightColumnColor(QColor(Qt::darkMagenta)),
+ m_surfaceGradient(QLinearGradient(1, 100, 0, 0)),
m_lightStrength(4.0f),
m_ambientStrength(0.3f),
m_highlightLightStrength(8.0f),
m_uniformColor(true)
{
+ // Default values for surface gradient
+ m_surfaceGradient.setColorAt(0.0, Qt::green);
+ m_surfaceGradient.setColorAt(0.5, Qt::yellow);
+ m_surfaceGradient.setColorAt(1.0, Qt::red);
}
Theme::~Theme()
{
}
-void Theme::useTheme(ColorTheme theme)
+QDataVis::ColorTheme Theme::colorTheme()
+{
+ return m_colorTheme;
+}
+
+void Theme::useColorTheme(QDataVis::ColorTheme colorTheme)
{
- switch (theme) {
- case ThemeSystem: {
+ m_colorTheme = colorTheme;
+ switch (colorTheme) {
+ case QDataVis::ThemeSystem: {
#ifdef Q_OS_WIN
DWORD colorHighlight;
colorHighlight = GetSysColor(COLOR_HIGHLIGHT);
@@ -157,7 +145,7 @@ void Theme::useTheme(ColorTheme theme)
qDebug("ThemeSystem");
break;
}
- case ThemeBlueCerulean: {
+ case QDataVis::ThemeBlueCerulean: {
m_baseColor = QColor(QRgb(0xc7e85b));
m_heightColor = QColor(QRgb(0xee7392));
m_depthColor = QColor(QRgb(0x1cb54f));
@@ -176,7 +164,7 @@ void Theme::useTheme(ColorTheme theme)
qDebug("ThemeBlueCerulean");
break;
}
- case ThemeBlueIcy: {
+ case QDataVis::ThemeBlueIcy: {
m_baseColor = QRgb(0x3daeda);
m_heightColor = QRgb(0x2fa3b4);
m_depthColor = QColor(QRgb(0x2685bf));
@@ -195,7 +183,7 @@ void Theme::useTheme(ColorTheme theme)
qDebug("ThemeBlueIcy");
break;
}
- case ThemeBlueNcs: {
+ case QDataVis::ThemeBlueNcs: {
m_baseColor = QColor(QRgb(0x1db0da));
m_heightColor = QColor(QRgb(0x398ca3));
m_depthColor = QColor(QRgb(0x1341a6));
@@ -214,7 +202,7 @@ void Theme::useTheme(ColorTheme theme)
qDebug("ThemeBlueNcs");
break;
}
- case ThemeBrownSand: {
+ case QDataVis::ThemeBrownSand: {
m_baseColor = QColor(QRgb(0xb39b72));
m_heightColor = QColor(QRgb(0x494345));
m_depthColor = QColor(QRgb(0xb3b376));
@@ -233,7 +221,7 @@ void Theme::useTheme(ColorTheme theme)
qDebug("ThemeBrownSand");
break;
}
- case ThemeDark: {
+ case QDataVis::ThemeDark: {
m_baseColor = QColor(QRgb(0x38ad6b)); // charts: series color 1
m_heightColor = QColor(QRgb(0xbf593e)); // charts: series color 5
m_depthColor = QColor(QRgb(0x3c84a7)); // charts: series color 2
@@ -252,7 +240,7 @@ void Theme::useTheme(ColorTheme theme)
qDebug("ThemeDark");
break;
}
- case ThemeHighContrast: {
+ case QDataVis::ThemeHighContrast: {
m_baseColor = QColor(QRgb(0x202020));
m_heightColor = QColor(QRgb(0xff4a41));
m_depthColor = QColor(QRgb(0x596a74));
@@ -271,7 +259,7 @@ void Theme::useTheme(ColorTheme theme)
qDebug("ThemeHighContrast");
break;
}
- case ThemeLight: {
+ case QDataVis::ThemeLight: {
m_baseColor = QColor(QRgb(0x209fdf));
m_heightColor = QColor(QRgb(0xbf593e));
m_depthColor = QColor(QRgb(0x99ca53));
@@ -295,4 +283,25 @@ void Theme::useTheme(ColorTheme theme)
}
}
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
+void Theme::setFromTheme(Theme &theme)
+{
+ m_colorTheme = theme.m_colorTheme;
+ m_baseColor = theme.m_baseColor;
+ m_heightColor = theme.m_heightColor;
+ m_depthColor = theme.m_depthColor;
+ m_backgroundColor = theme.m_backgroundColor;
+ m_windowColor = theme.m_windowColor;
+ m_textColor = theme.m_textColor;
+ m_textBackgroundColor = theme.m_textBackgroundColor;
+ m_gridLine = theme.m_gridLine;
+ m_highlightBarColor = theme.m_highlightBarColor;
+ m_highlightRowColor = theme.m_highlightRowColor;
+ m_highlightColumnColor = theme.m_highlightColumnColor;
+ m_surfaceGradient = theme.m_surfaceGradient;
+ m_lightStrength = theme.m_lightStrength;
+ m_ambientStrength = theme.m_ambientStrength;
+ m_highlightLightStrength = theme.m_highlightLightStrength;
+ m_uniformColor = theme.m_uniformColor;
+}
+
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/engine/theme_p.h b/src/datavis3d/engine/theme_p.h
index 234d4709..31c47941 100644
--- a/src/datavis3d/engine/theme_p.h
+++ b/src/datavis3d/engine/theme_p.h
@@ -1,41 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
@@ -43,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the Qt API. It exists purely as an
+// This file is not part of the QtDataVis3D API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -52,13 +29,13 @@
#ifndef THEME_P_H
#define THEME_P_H
-#include "QtDataVis3D/qdatavis3dglobal.h"
-#include "QtDataVis3D/qdatavis3namespace.h"
+#include "datavis3dglobal_p.h"
#include "q3dbars.h"
+#include <QLinearGradient>
class QColor;
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVIS3D_BEGIN_NAMESPACE
class Theme
{
@@ -66,14 +43,21 @@ public:
explicit Theme();
~Theme();
- void useTheme(ColorTheme theme);
+ void useColorTheme(QDataVis::ColorTheme theme);
+ QDataVis::ColorTheme colorTheme();
+ void setFromTheme(Theme &theme);
private:
- friend class Bars3dShared;
- friend class Q3DMaps;
- friend class Q3DMapsPrivate;
+ friend class Abstract3DController;
+ friend class Abstract3DRenderer;
+ friend class Bars3dRenderer;
+ friend class Maps3DController;
+ friend class Surface3dRenderer;
+ friend class Surface3dController;
+ friend class Scatter3DRenderer;
friend class Drawer;
+ QDataVis::ColorTheme m_colorTheme;
QColor m_baseColor;
QColor m_heightColor;
QColor m_depthColor;
@@ -85,12 +69,13 @@ private:
QColor m_highlightBarColor;
QColor m_highlightRowColor;
QColor m_highlightColumnColor;
+ QLinearGradient m_surfaceGradient;
float m_lightStrength;
float m_ambientStrength;
float m_highlightLightStrength;
bool m_uniformColor;
};
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
+QT_DATAVIS3D_END_NAMESPACE
#endif
diff --git a/src/datavis3d/global/datavis3dglobal_p.h b/src/datavis3d/global/datavis3dglobal_p.h
new file mode 100644
index 00000000..d556c5e1
--- /dev/null
+++ b/src/datavis3d/global/datavis3dglobal_p.h
@@ -0,0 +1,52 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef DATAVIS3DGLOBAL_P_H
+#define DATAVIS3DGLOBAL_P_H
+
+#include "qdatavis3dglobal.h"
+#include "qdatavis3denums.h"
+#include <QOpenGLFunctions>
+#include <QVector3D>
+#include <QDebug>
+
+//#define ROTATE_ZOOM_SELECTION
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+// Constants used in several files
+// Compensation for z position; move all objects to positive z, as shader can't handle negative values correctly
+const GLfloat zComp = 10.0f;
+// Default light position. To have shadows working correctly, light should be as far as camera, or a bit further
+// y position is added to the minimum height (or can be thought to be that much above or below the camera)
+const QVector3D defaultLightPos = QVector3D(0.0f, 0.5f, zComp);
+const GLfloat defaultRatio = 1.0f / 1.6f; // default aspect ratio 16:10
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif // DATAVIS3DGLOBAL_P_H
diff --git a/src/datavis3d/global/global.pri b/src/datavis3d/global/global.pri
index 56cb9f8f..7292bbd6 100644
--- a/src/datavis3d/global/global.pri
+++ b/src/datavis3d/global/global.pri
@@ -1,5 +1,4 @@
-INCLUDEPATH += $$PWD
-VPATH += $$PWD
HEADERS += \
- global/qdatavis3dglobal.h \
- global/qdatavis3namespace.h
+ $$PWD/qdatavis3dglobal.h \
+ $$PWD/qdatavis3denums.h \
+ $$PWD/datavis3dglobal_p.h
diff --git a/src/datavis3d/global/qdatavis3denums.h b/src/datavis3d/global/qdatavis3denums.h
new file mode 100644
index 00000000..a6384508
--- /dev/null
+++ b/src/datavis3d/global/qdatavis3denums.h
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#ifndef QDATAVIS3DENUMS_H
+#define QDATAVIS3DENUMS_H
+
+#include <QtDataVis3D/qdatavis3dglobal.h>
+#include <QObject>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class QT_DATAVIS3D_EXPORT QDataVis : public QObject
+{
+ Q_OBJECT
+ Q_ENUMS(MeshStyle)
+ Q_ENUMS(CameraPreset)
+ Q_ENUMS(ColorTheme)
+ Q_ENUMS(SelectionMode)
+ Q_ENUMS(ShadowQuality)
+ Q_ENUMS(LabelTransparency)
+
+public:
+
+ enum MeshStyle {
+ Bars = 0,
+ Pyramids,
+ Cones,
+ Cylinders,
+ BevelBars,
+ Spheres,
+ Dots
+ };
+
+ enum CameraPreset {
+ NoPreset = -1,
+ PresetFrontLow = 0,
+ PresetFront,
+ PresetFrontHigh,
+ PresetLeftLow,
+ PresetLeft,
+ PresetLeftHigh,
+ PresetRightLow,
+ PresetRight,
+ PresetRightHigh,
+ PresetBehindLow,
+ PresetBehind,
+ PresetBehindHigh,
+ PresetIsometricLeft,
+ PresetIsometricLeftHigh,
+ PresetIsometricRight,
+ PresetIsometricRightHigh,
+ PresetDirectlyAbove,
+ PresetDirectlyAboveCW45,
+ PresetDirectlyAboveCCW45,
+ PresetFrontBelow, // These work only for graphs including negative values.
+ PresetLeftBelow, // They act as Preset...Low for positive-only values.
+ PresetRightBelow,
+ PresetBehindBelow,
+ PresetDirectlyBelow
+ };
+
+ enum ColorTheme {
+ ThemeDefault = -1,
+ ThemeSystem = 0,
+ ThemeBlueCerulean,
+ ThemeBlueIcy,
+ ThemeBlueNcs,
+ ThemeBrownSand,
+ ThemeDark,
+ ThemeHighContrast,
+ ThemeLight
+ };
+
+ enum SelectionMode {
+ ModeNone = 0,
+ ModeItem,
+ ModeItemAndRow, // From here onwards used for Q3DBars only
+ ModeItemAndColumn,
+ ModeItemRowAndColumn,
+ ModeZoomRow,
+ ModeZoomColumn
+ };
+
+ enum ShadowQuality {
+ ShadowNone = 0,
+ ShadowLow = 1,
+ ShadowMedium = 3,
+ ShadowHigh = 5
+ };
+
+ enum LabelTransparency {
+ TransparencyNone = 0, // Full solid, using colors from theme
+ TransparencyFromTheme, // Use colors and transparencies from theme
+ TransparencyNoBackground // Draw just text on transparent background
+ };
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/global/qdatavis3dglobal.h b/src/datavis3d/global/qdatavis3dglobal.h
index 7dad9374..5e2e88b1 100644
--- a/src/datavis3d/global/qdatavis3dglobal.h
+++ b/src/datavis3d/global/qdatavis3dglobal.h
@@ -4,17 +4,15 @@
** All rights reserved.
** For any questions to Digia, please use contact form at http://qt.digia.com
**
-** This file is part of QtDataVis3D.
+** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE$
-** Licensees holding valid Qt Commercial licenses may use this file in
-** accordance with the Qt Commercial License Agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia.
**
** If you have questions regarding the use of this file, please use
** contact form at http://qt.digia.com
-** $QT_END_LICENSE$
**
****************************************************************************/
@@ -23,68 +21,47 @@
#include <qglobal.h>
-//#define ROTATE_ZOOM_SELECTION
-
-#define QTENTERPRISE_DATAVIS3D_VERSION_STR "0.0.1"
+#define QT_DATAVIS3D_VERSION_STR "0.0.1"
/*
- QTENTERPRISE_DATAVIS3D_VERSION is (major << 16) + (minor << 8) + patch.
+ QT_DATAVIS3D_VERSION is (major << 16) + (minor << 8) + patch.
*/
-#define QTENTERPRISE_DATAVIS3D_VERSION 0x000001
+#define QT_DATAVIS3D_VERSION 0x000001
/*
- can be used like #if (QTENTERPRISE_DATAVIS3D_VERSION >= QTENTERPRISE_DATAVIS3D_VERSION_CHECK(1, 1, 0))
+ can be used like #if (QT_DATAVIS3D_VERSION >= QT_DATAVIS3D_VERSION_CHECK(1, 1, 0))
*/
-#define QTENTERPRISE_DATAVIS3D_VERSION_CHECK(major, minor, patch) ((major<<16)|(minor<<8)|(patch))
+#define QT_DATAVIS3D_VERSION_CHECK(major, minor, patch) ((major<<16)|(minor<<8)|(patch))
-#if defined(QTENTERPRISE_DATAVIS3D_LIBRARY)
-# define QTENTERPRISE_DATAVIS3D_EXPORT Q_DECL_EXPORT
+#if defined(QT_DATAVIS3D_LIBRARY)
+# define QT_DATAVIS3D_EXPORT Q_DECL_EXPORT
#else
-# define QTENTERPRISE_DATAVIS3D_EXPORT Q_DECL_IMPORT
+# define QT_DATAVIS3D_EXPORT Q_DECL_IMPORT
#endif
-#if defined(BUILD_PRIVATE_UNIT_TESTS) && defined(QTENTERPRISE_DATAVIS3D_LIBRARY)
-# define QTENTERPRISE_DATAVIS3D_AUTOTEST_EXPORT Q_DECL_EXPORT
-#elif defined(BUILD_PRIVATE_UNIT_TESTS) && !defined(QTENTERPRISE_DATAVIS3D_LIBRARY)
-# define QTENTERPRISE_DATAVIS3D_AUTOTEST_EXPORT Q_DECL_IMPORT
+#if defined(BUILD_PRIVATE_UNIT_TESTS) && defined(QT_DATAVIS3D_LIBRARY)
+# define QT_DATAVIS3D_AUTOTEST_EXPORT Q_DECL_EXPORT
+#elif defined(BUILD_PRIVATE_UNIT_TESTS) && !defined(QT_DATAVIS3D_LIBRARY)
+# define QT_DATAVIS3D_AUTOTEST_EXPORT Q_DECL_IMPORT
#else
-# define QTENTERPRISE_DATAVIS3D_AUTOTEST_EXPORT
+# define QT_DATAVIS3D_AUTOTEST_EXPORT
#endif
-#ifdef QTENTERPRISE_DATAVIS3D_STATICLIB
-# undef QTENTERPRISE_DATAVIS3D_EXPORT
-# undef QTENTERPRISE_DATAVIS3D_AUTOTEST_EXPORT
-# define QTENTERPRISE_DATAVIS3D_EXPORT
-# define QTENTERPRISE_DATAVIS3D_AUTOTEST_EXPORT
+#ifdef QT_DATAVIS3D_STATICLIB
+# undef QT_DATAVIS3D_EXPORT
+# undef QT_DATAVIS3D_AUTOTEST_EXPORT
+# define QT_DATAVIS3D_EXPORT
+# define QT_DATAVIS3D_AUTOTEST_EXPORT
#endif
-#define QTENTERPRISE_DATAVIS3D_NAMESPACE QtDataVis3D
+#define QT_DATAVIS3D_NAMESPACE QtDataVis3D
-#ifdef QTENTERPRISE_DATAVIS3D_NAMESPACE
-# define QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE namespace QTENTERPRISE_DATAVIS3D_NAMESPACE {
-# define QTENTERPRISE_DATAVIS3D_END_NAMESPACE }
-# define QTENTERPRISE_DATAVIS3D_USE_NAMESPACE using namespace QTENTERPRISE_DATAVIS3D_NAMESPACE;
+#ifdef QT_DATAVIS3D_NAMESPACE
+# define QT_DATAVIS3D_BEGIN_NAMESPACE namespace QT_DATAVIS3D_NAMESPACE {
+# define QT_DATAVIS3D_END_NAMESPACE }
+# define QT_DATAVIS3D_USE_NAMESPACE using namespace QT_DATAVIS3D_NAMESPACE;
#else
-# define QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
-# define QTENTERPRISE_DATAVIS3D_END_NAMESPACE
-# define QTENTERPRISE_DATAVIS3D_USE_NAMESPACE
-#endif
-
-#if defined(DEVELOPMENT_BUILD) && !defined(QT_NO_DEBUG)
-#include <stdarg.h>
-#include <QDebug>
-
-#define CHART_DEBUG chartDebug(3,__LINE__,__FILE__,__FUNCTION__)
-
-static inline QDebug chartDebug(int numargs,...)
-{
- va_list valist;
- va_start(valist, numargs);
- //for( int i = 0 ; i < numargs; i++ )
- int line = va_arg(valist, int);
- char *file = va_arg(valist, char *);
- char *function = va_arg(valist, char *);
- va_end(valist);
- return qDebug() << QString().append(function).append("(").append(file).append(":%1)").arg(line);
-}
+# define QT_DATAVIS3D_BEGIN_NAMESPACE
+# define QT_DATAVIS3D_END_NAMESPACE
+# define QT_DATAVIS3D_USE_NAMESPACE
#endif
#endif // QVIS3DGLOBAL_H
diff --git a/src/datavis3d/global/qdatavis3namespace.h b/src/datavis3d/global/qdatavis3namespace.h
deleted file mode 100644
index e36cc02a..00000000
--- a/src/datavis3d/global/qdatavis3namespace.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of QtDataVis3D module.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** 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 Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QVIS3DNAMESPACE_H
-#define QVIS3DNAMESPACE_H
-
-#include "qdatavis3dglobal.h"
-#include <QOpenGLFunctions>
-#include <QVector3D>
-
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
-
-// Constants used in several files
-const GLfloat m_pi = 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679f;
-// Compensation for z position; move all objects to positive z, as shader can't handle negative values correctly
-const GLfloat zComp = 10.0f;
-// Default light position. To have shadows working correctly, light should be as far as camera, or a bit further
-// y position is added to the minimum height (or can be thought to be that much above or below the camera)
-const QVector3D defaultLightPos = QVector3D(0.0f, 0.5f, zComp);
-const GLfloat defaultRatio = 1.0f / 1.6f; // default aspect ratio 16:10
-
-// Enums used in several files
-enum BarStyle {
- Bars = 0,
- Pyramids,
- Cones,
- Cylinders,
- BevelBars,
- Spheres
-};
-
-enum CameraPreset {
- PresetFrontLow = 0,
- PresetFront,
- PresetFrontHigh,
- PresetLeftLow,
- PresetLeft,
- PresetLeftHigh,
- PresetRightLow,
- PresetRight,
- PresetRightHigh,
- PresetBehindLow,
- PresetBehind,
- PresetBehindHigh,
- PresetIsometricLeft,
- PresetIsometricLeftHigh,
- PresetIsometricRight,
- PresetIsometricRightHigh,
- PresetDirectlyAbove,
- PresetDirectlyAboveCW45,
- PresetDirectlyAboveCCW45,
- PresetFrontBelow, // These work only for graphs including negative values.
- PresetLeftBelow, // They act as Preset...Low for positive-only values.
- PresetRightBelow,
- PresetBehindBelow,
- PresetDirectlyBelow
-};
-
-enum ColorTheme {
- ThemeSystem = 0,
- ThemeBlueCerulean,
- ThemeBlueIcy,
- ThemeBlueNcs,
- ThemeBrownSand,
- ThemeDark,
- ThemeHighContrast,
- ThemeLight
-};
-
-// TODO: Should this be moved to Q3DBarsPrivate? Not for use via API directly?
-enum LabelPosition {
- LabelBelow = 0,
- LabelLow,
- LabelMid,
- LabelHigh,
- LabelOver,
- LabelBottom, // Absolute positions from here onward, used for axes (QDataItem is ignored)
- LabelTop,
- LabelLeft,
- LabelRight
-};
-
-// TODO: Will these be used from other vis types than Q3DBars?
-enum SelectionMode {
- ModeNone = 0,
- ModeBar,
- ModeBarAndRow,
- ModeBarAndColumn,
- ModeBarRowAndColumn,
- ModeZoomRow,
- ModeZoomColumn
-};
-
-enum ShadowQuality {
- ShadowNone = 0,
- ShadowLow = 1,
- ShadowMedium = 3,
- ShadowHigh = 5
-};
-
-enum LabelTransparency {
- TransparencyNone = 0, // Full solid, using colors from theme
- TransparencyFromTheme, // Use colors and transparencies from theme
- TransparencyNoBackground // Draw just text on transparent background
-};
-
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
-
-#endif
diff --git a/src/datavis3d/global/qtdatavis3dnamespace.qdoc b/src/datavis3d/global/qtdatavis3dnamespace.qdoc
new file mode 100644
index 00000000..2a1f6fae
--- /dev/null
+++ b/src/datavis3d/global/qtdatavis3dnamespace.qdoc
@@ -0,0 +1,163 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+/*!
+ \namespace QtDataVis3D
+ \inmodule QtDataVis3D
+ \target QtDataVis3D Namespace
+
+ \brief The QtDataVis3D namespace contains miscellaneous identifiers
+ used throughout the QtDataVis3D library.
+*/
+
+/*!
+ \enum QtDataVis3D::BarStyle
+
+ Predefined bar types.
+
+ \value Bars
+ Basic cubic bar.
+ \value Pyramids
+ Four -sided pyramid.
+ \value Cones
+ Basic cone.
+ \value Cylinders
+ Basic cylinder.
+ \value BevelBars
+ Slilghtly beveled (rounded) cubic bar.
+ \value Spheres
+ Sphere. Not usable in Q3DBars.
+*/
+
+/*!
+ \enum QtDataVis3D::CameraPreset
+
+ Predefined positions for camera.
+
+ \value PresetFrontLow
+ \value PresetFront
+ \value PresetFrontHigh
+ \value PresetLeftLow
+ \value PresetLeft
+ \value PresetLeftHigh
+ \value PresetRightLow
+ \value PresetRight
+ \value PresetRightHigh
+ \value PresetBehindLow
+ \value PresetBehind
+ \value PresetBehindHigh
+ \value PresetIsometricLeft
+ \value PresetIsometricLeftHigh
+ \value PresetIsometricRight
+ \value PresetIsometricRightHigh
+ \value PresetDirectlyAbove
+ \value PresetDirectlyAboveCW45
+ \value PresetDirectlyAboveCCW45
+ \value PresetFrontBelow
+ From PresetFrontBelow onward these only work for graphs including negative values.
+ They act as Preset...Low for positive-only values.
+ \value PresetLeftBelow
+ \value PresetRightBelow
+ \value PresetBehindBelow
+ \value PresetDirectlyBelow
+ Acts as PresetFrontLow for positive -only bars.
+*/
+
+/*!
+ \enum QtDataVis3D::ColorTheme
+
+ Predefined color themes.
+
+ \value ThemeSystem
+ \value ThemeBlueCerulean
+ \value ThemeBlueIcy
+ \value ThemeBlueNcs
+ \value ThemeBrownSand
+ \value ThemeDark
+ \value ThemeHighContrast
+ \value ThemeLight
+*/
+
+/*!
+ \enum QtDataVis3D::LabelPosition
+
+ Predefined positions for labels.
+
+ \value LabelBelow
+ \value LabelLow
+ \value LabelMid
+ \value LabelHigh
+ \value LabelOver
+ \value LabelBottom
+ \value LabelTop
+ \value LabelLeft
+ \value LabelRight
+*/
+
+/*!
+ \enum QtDataVis3D::SelectionMode
+
+ Bar selection modes.
+
+ \value ModeNone
+ Selection mode disabled.
+ \value ModeBar
+ Selection selects a single bar.
+ \value ModeBarAndRow
+ Selection selects a single bar and highlights the row it is on.
+ \value ModeBarAndColumn
+ Selection selects a single bar and highlights the column it is on.
+ \value ModeBarRowAndColumn
+ Selection selects a single bar and highlights the row and the column it is on.
+ \value ModeZoomRow
+ Selection selects a single bar and displays the row it is on in a separate view. The
+ original view is shrunk into upper left corner. Original view is restored by clicking
+ on it.
+ \value ModeZoomColumn
+ Selection selects a single bar and displays the column it is on in a separate view. The
+ original view is shrunk into upper left corner. Original view is restored by clicking
+ on it.
+*/
+
+/*!
+ \enum QtDataVis3D::ShadowQuality
+
+ Quality of shadows.
+
+ \value ShadowNone
+ Shadows are disabled.
+ \value ShadowLow
+ Shadows are rendered in low quality.
+ \value ShadowMedium
+ Shadows are rendered in medium quality.
+ \value ShadowHigh
+ Shadows are rendered in high quality.
+*/
+
+/*!
+ \enum QtDataVis3D::LabelTransparency
+
+ Label transparencies.
+
+ \value TransparencyNone
+ Full solid, using colors from theme.
+ \value TransparencyFromTheme
+ Use colors and transparencies from theme.
+ \value TransparencyNoBackground
+ Draw just text on transparent background.
+*/
diff --git a/src/datavis3d/utils/abstractobjecthelper.cpp b/src/datavis3d/utils/abstractobjecthelper.cpp
new file mode 100644
index 00000000..d54a50c7
--- /dev/null
+++ b/src/datavis3d/utils/abstractobjecthelper.cpp
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "abstractobjecthelper_p.h"
+
+#include <QDebug>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+AbstractObjectHelper::AbstractObjectHelper()
+ : m_vertexbuffer(0),
+ m_normalbuffer(0),
+ m_uvbuffer(0),
+ m_elementbuffer(0),
+ m_indexCount(0),
+ m_meshDataLoaded(false)
+{
+}
+
+AbstractObjectHelper::~AbstractObjectHelper()
+{
+ glDeleteBuffers(1, &m_vertexbuffer);
+ glDeleteBuffers(1, &m_uvbuffer);
+ glDeleteBuffers(1, &m_normalbuffer);
+ glDeleteBuffers(1, &m_elementbuffer);
+}
+
+GLuint AbstractObjectHelper::vertexBuf()
+{
+ if (!m_meshDataLoaded)
+ qFatal("No loaded object");
+ return m_vertexbuffer;
+}
+
+GLuint AbstractObjectHelper::normalBuf()
+{
+ if (!m_meshDataLoaded)
+ qFatal("No loaded object");
+ return m_normalbuffer;
+}
+
+GLuint AbstractObjectHelper::uvBuf()
+{
+ if (!m_meshDataLoaded)
+ qFatal("No loaded object");
+ return m_uvbuffer;
+}
+
+GLuint AbstractObjectHelper::elementBuf()
+{
+ if (!m_meshDataLoaded)
+ qFatal("No loaded object");
+ return m_elementbuffer;
+}
+
+GLuint AbstractObjectHelper::indexCount()
+{
+ return m_indexCount;
+}
+
+GLuint AbstractObjectHelper::indicesType()
+{
+ return m_indicesType;
+}
+
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/utils/abstractobjecthelper_p.h b/src/datavis3d/utils/abstractobjecthelper_p.h
new file mode 100644
index 00000000..a4d701fa
--- /dev/null
+++ b/src/datavis3d/utils/abstractobjecthelper_p.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef ABSTRACTOBJECTHELPER_H
+#define ABSTRACTOBJECTHELPER_H
+
+#include "datavis3dglobal_p.h"
+#include <QOpenGLFunctions>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class AbstractObjectHelper: protected QOpenGLFunctions
+{
+protected:
+ AbstractObjectHelper();
+public:
+ ~AbstractObjectHelper();
+
+ GLuint vertexBuf();
+ GLuint normalBuf();
+ GLuint uvBuf();
+ GLuint elementBuf();
+ GLuint indexCount();
+ GLuint indicesType();
+
+public:
+ GLuint m_vertexbuffer;
+ GLuint m_normalbuffer;
+ GLuint m_uvbuffer;
+ GLuint m_elementbuffer;
+
+ GLuint m_indexCount;
+ GLboolean m_meshDataLoaded;
+
+ GLuint m_indicesType;
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif // ABSTRACTOBJECTHELPER_H
diff --git a/src/datavis3d/utils/camerahelper.cpp b/src/datavis3d/utils/camerahelper.cpp
index 4d59132f..5ae91adb 100644
--- a/src/datavis3d/utils/camerahelper.cpp
+++ b/src/datavis3d/utils/camerahelper.cpp
@@ -1,41 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
@@ -45,21 +22,26 @@
#include <QMatrix4x4>
#include <QVector3D>
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
-
-// Initial camera position
-QVector3D m_position = QVector3D(0, 0.25, 3);
-QVector3D m_target = QVector3D(0, 0, 0);
-QVector3D m_up = QVector3D(0, 1, 0);
+QT_DATAVIS3D_BEGIN_NAMESPACE
-QPoint m_previousMousePos(0, 0);
+CameraHelper::CameraHelper(QObject *parent) :
+ QObject(parent),
+ m_position(0, 0.25, 3),
+ m_target(0, 0, 0),
+ m_up(0, 1, 0),
+ m_previousMousePos(0,0),
+ m_xRotation(0),
+ m_yRotation(0),
+ m_defaultXRotation(0),
+ m_defaultYRotation(0),
+ m_rotationSpeed(100)
+{
+}
-GLfloat m_xRotation = 0;
-GLfloat m_yRotation = 0;
-GLfloat m_defaultXRotation = 0;
-GLfloat m_defaultYRotation = 0;
+CameraHelper::~CameraHelper()
+{
+}
-GLfloat m_rotationSpeed = 100;
// FUNCTIONS
void CameraHelper::setRotationSpeed(int speed)
@@ -89,10 +71,10 @@ QMatrix4x4 CameraHelper::calculateViewMatrix(const QPoint &mousePos, int zoom,
int screenWidth, int screenHeight, bool showUnder)
{
QMatrix4x4 viewMatrix;
- GLint lowerLimit = 0;
+ GLfloat lowerLimit = 0.0f;
if (showUnder)
- lowerLimit = -90;
+ lowerLimit = -90.0f;
// Calculate mouse movement since last frame
GLfloat mouseMoveX = GLfloat(m_previousMousePos.x() - mousePos.x())
@@ -103,10 +85,10 @@ QMatrix4x4 CameraHelper::calculateViewMatrix(const QPoint &mousePos, int zoom,
m_xRotation -= mouseMoveX;
m_yRotation -= mouseMoveY;
// Reset at 360 in x and limit to 0...90 in y
- if (qFabs(m_xRotation) >= 360)
- m_xRotation = 0;
- if (m_yRotation >= 90)
- m_yRotation = 90;
+ if (qAbs(m_xRotation) >= 360.0f)
+ m_xRotation = 0.0f;
+ if (m_yRotation >= 90.0f)
+ m_yRotation = 90.0f;
else if (m_yRotation <= lowerLimit)
m_yRotation = lowerLimit;
@@ -116,8 +98,8 @@ QMatrix4x4 CameraHelper::calculateViewMatrix(const QPoint &mousePos, int zoom,
viewMatrix.translate(m_target.x(), m_target.y(), m_target.z());
// Apply rotations
// Handle x and z rotation when y -angle is other than 0
- viewMatrix.rotate(m_xRotation, 0, cos(m_yRotation * m_pi / 180.0f),
- sin(m_yRotation * m_pi / 180.0f));
+ viewMatrix.rotate(m_xRotation, 0, qCos(qDegreesToRadians(m_yRotation)),
+ qSin(qDegreesToRadians(m_yRotation)));
// y rotation is always "clean"
viewMatrix.rotate(m_yRotation, 1.0f, 0.0f, 0.0f);
// handle zoom by scaling
@@ -126,11 +108,6 @@ QMatrix4x4 CameraHelper::calculateViewMatrix(const QPoint &mousePos, int zoom,
viewMatrix.translate(-m_target.x(), -m_target.y(), -m_target.z());
//qDebug() << m_xRotation << m_yRotation;
- //qDebug() << "sin(m_yRotation)" << sin(m_yRotation*m_pi/180);
- //qDebug() << "asin(m_yRotation)" << asin(m_yRotation*m_pi/180);
- //qDebug() << "cos(m_yRotation)" << cos(m_yRotation*m_pi/180);
- //qDebug() << "tan(m_yRotation)" << tan(m_yRotation*m_pi/180);
-
m_previousMousePos = mousePos;
return viewMatrix;
}
@@ -144,18 +121,17 @@ QVector3D CameraHelper::calculateLightPosition(const QVector3D &lightPosition,
GLfloat xAngle;
GLfloat yAngle;
if (!fixedRotation) {
- xAngle = m_xRotation * m_pi / 180.0f;
- yAngle = m_yRotation * m_pi / 180.0f;
+ xAngle = qDegreesToRadians(m_xRotation);
+ yAngle = qDegreesToRadians(m_yRotation);
} else {
- xAngle = fixedRotation * m_pi / 180.0f;
+ xAngle = qDegreesToRadians(fixedRotation);
yAngle = 0;
}
GLfloat radius = (radiusFactor + lightPosition.y()); // set radius to match the highest height of the light
- GLfloat zPos = radius * cos(xAngle) * cos(yAngle);
- GLfloat xPos = radius * sin(xAngle) * cos(yAngle);
- GLfloat yPos = (radiusFactor + lightPosition.y()) * sin(yAngle);
+ GLfloat zPos = radius * qCos(xAngle) * qCos(yAngle);
+ GLfloat xPos = radius * qSin(xAngle) * qCos(yAngle);
+ GLfloat yPos = (radiusFactor + lightPosition.y()) * qSin(yAngle);
// Keep light in the set position in relation to camera
- // TODO: Does not work perfectly yet; Light seems wrong when viewing scene from sides (or isometrically)
newLightPosition = QVector3D(-xPos + lightPosition.x(),
yPos + lightPosition.y(),
zPos + lightPosition.z());
@@ -179,125 +155,125 @@ QPointF CameraHelper::getCameraRotations()
return rotations;
}
-void CameraHelper::setCameraPreset(CameraPreset preset)
+void CameraHelper::setCameraPreset(QDataVis::CameraPreset preset)
{
switch (preset) {
- case PresetFrontLow: {
+ case QDataVis::PresetFrontLow: {
qDebug("PresetFrontLow");
CameraHelper::setCameraRotation(QPointF(0.0f, 0.0f));
break;
}
- case PresetFront: {
+ case QDataVis::PresetFront: {
qDebug("PresetFront");
CameraHelper::setCameraRotation(QPointF(0.0f, 22.5f));
break;
}
- case PresetFrontHigh: {
+ case QDataVis::PresetFrontHigh: {
qDebug("PresetFrontHigh");
CameraHelper::setCameraRotation(QPointF(0.0f, 45.0f));
break;
}
- case PresetLeftLow: {
+ case QDataVis::PresetLeftLow: {
qDebug("PresetLeftLow");
CameraHelper::setCameraRotation(QPointF(90.0f, 0.0f));
break;
}
- case PresetLeft: {
+ case QDataVis::PresetLeft: {
qDebug("PresetLeft");
CameraHelper::setCameraRotation(QPointF(90.0f, 22.5f));
break;
}
- case PresetLeftHigh: {
+ case QDataVis::PresetLeftHigh: {
qDebug("PresetLeftHigh");
CameraHelper::setCameraRotation(QPointF(90.0f, 45.0f));
break;
}
- case PresetRightLow: {
+ case QDataVis::PresetRightLow: {
qDebug("PresetRightLow");
CameraHelper::setCameraRotation(QPointF(-90.0f, 0.0f));
break;
}
- case PresetRight: {
+ case QDataVis::PresetRight: {
qDebug("PresetRight");
CameraHelper::setCameraRotation(QPointF(-90.0f, 22.5f));
break;
}
- case PresetRightHigh: {
+ case QDataVis::PresetRightHigh: {
qDebug("PresetRightHigh");
CameraHelper::setCameraRotation(QPointF(-90.0f, 45.0f));
break;
}
- case PresetBehindLow: {
+ case QDataVis::PresetBehindLow: {
qDebug("PresetBehindLow");
CameraHelper::setCameraRotation(QPointF(180.0f, 0.0f));
break;
}
- case PresetBehind: {
+ case QDataVis::PresetBehind: {
qDebug("PresetBehind");
CameraHelper::setCameraRotation(QPointF(180.0f, 22.5f));
break;
}
- case PresetBehindHigh: {
+ case QDataVis::PresetBehindHigh: {
qDebug("PresetBehindHigh");
CameraHelper::setCameraRotation(QPointF(180.0f, 45.0f));
break;
}
- case PresetIsometricLeft: {
+ case QDataVis::PresetIsometricLeft: {
qDebug("PresetIsometricLeft");
CameraHelper::setCameraRotation(QPointF(45.0f, 22.5f));
break;
}
- case PresetIsometricLeftHigh: {
+ case QDataVis::PresetIsometricLeftHigh: {
qDebug("PresetIsometricLeftHigh");
CameraHelper::setCameraRotation(QPointF(45.0f, 45.0f));
break;
}
- case PresetIsometricRight: {
+ case QDataVis::PresetIsometricRight: {
qDebug("PresetIsometricRight");
CameraHelper::setCameraRotation(QPointF(-45.0f, 22.5f));
break;
}
- case PresetIsometricRightHigh: {
+ case QDataVis::PresetIsometricRightHigh: {
qDebug("PresetIsometricRightHigh");
CameraHelper::setCameraRotation(QPointF(-45.0f, 45.0f));
break;
}
- case PresetDirectlyAbove: {
+ case QDataVis::PresetDirectlyAbove: {
qDebug("PresetDirectlyAbove");
CameraHelper::setCameraRotation(QPointF(0.0f, 90.0f));
break;
}
- case PresetDirectlyAboveCW45: {
+ case QDataVis::PresetDirectlyAboveCW45: {
qDebug("PresetDirectlyAboveCW45");
CameraHelper::setCameraRotation(QPointF(-45.0f, 90.0f));
break;
}
- case PresetDirectlyAboveCCW45: {
+ case QDataVis::PresetDirectlyAboveCCW45: {
qDebug("PresetDirectlyAboveCCW45");
CameraHelper::setCameraRotation(QPointF(45.0f, 90.0f));
break;
}
- case PresetFrontBelow: {
+ case QDataVis::PresetFrontBelow: {
qDebug("PresetFrontBelow");
CameraHelper::setCameraRotation(QPointF(0.0f, -45.0f));
break;
}
- case PresetLeftBelow: {
+ case QDataVis::PresetLeftBelow: {
qDebug("PresetLeftBelow");
CameraHelper::setCameraRotation(QPointF(90.0f, -45.0f));
break;
}
- case PresetRightBelow: {
+ case QDataVis::PresetRightBelow: {
qDebug("PresetRightBelow");
CameraHelper::setCameraRotation(QPointF(-90.0f, -45.0f));
break;
}
- case PresetBehindBelow: {
+ case QDataVis::PresetBehindBelow: {
qDebug("PresetBehindBelow");
CameraHelper::setCameraRotation(QPointF(180.0f, -45.0f));
break;
}
- case PresetDirectlyBelow: {
+ case QDataVis::PresetDirectlyBelow: {
qDebug("PresetDirectlyBelow");
CameraHelper::setCameraRotation(QPointF(0.0f, -90.0f));
break;
@@ -307,4 +283,4 @@ void CameraHelper::setCameraPreset(CameraPreset preset)
}
}
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/utils/camerahelper_p.h b/src/datavis3d/utils/camerahelper_p.h
index 21b6ccac..3b8c0c9c 100644
--- a/src/datavis3d/utils/camerahelper_p.h
+++ b/src/datavis3d/utils/camerahelper_p.h
@@ -1,41 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
@@ -43,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the Qt API. It exists purely as an
+// This file is not part of the QtDataVis3D API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -52,43 +29,62 @@
#ifndef CAMERAPOSITIONER_P_H
#define CAMERAPOSITIONER_P_H
-#include "qdatavis3dglobal.h"
-#include "qdatavis3namespace.h"
+#include "datavis3dglobal_p.h"
#include "q3dbars.h"
+#include <QObject>
class QMatrix4x4;
class QVector3D;
class QPoint;
class QPointF;
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVIS3D_BEGIN_NAMESPACE
-class CameraHelper
+class CameraHelper : public QObject
{
- public:
+ Q_OBJECT
+
+private:
+ QVector3D m_position;
+ QVector3D m_target;
+ QVector3D m_up;
+
+ QPoint m_previousMousePos;
+
+ GLfloat m_xRotation;
+ GLfloat m_yRotation;
+ GLfloat m_defaultXRotation;
+ GLfloat m_defaultYRotation;
+
+ GLfloat m_rotationSpeed;
+
+public:
+ explicit CameraHelper(QObject *parent = 0);
+ ~CameraHelper();
+
// How fast camera rotates when mouse is dragged. Default is 100.
- static void setRotationSpeed(int speed);
+ void setRotationSpeed(int speed);
// Set camera rotation in degrees
- static void setCameraRotation(const QPointF &rotation);
+ void setCameraRotation(const QPointF &rotation);
// Get camera rotations
- static QPointF getCameraRotations();
+ QPointF getCameraRotations();
// Set default camera orientation. Position's x and y should be 0.
- static void setDefaultCameraOrientation(const QVector3D &defaultPosition,
+ void setDefaultCameraOrientation(const QVector3D &defaultPosition,
const QVector3D &defaultTarget,
const QVector3D &defaultUp);
// Calculate view matrix based on rotation and zoom
- static QMatrix4x4 calculateViewMatrix(const QPoint &mousePos, int zoom,
+ QMatrix4x4 calculateViewMatrix(const QPoint &mousePos, int zoom,
int screenWidth, int screenHeight,
bool showUnder = false);
// Calcluate light position based on rotation. Call after calling calculateViewMatrix to get
// up-to-date position
- static QVector3D calculateLightPosition(const QVector3D &lightPosition,
+ QVector3D calculateLightPosition(const QVector3D &lightPosition,
GLfloat fixedRotation = 0.0f,
GLfloat distanceModifier = 0.0f);
- static void updateMousePos(const QPoint &mousePos);
- static void setCameraPreset(CameraPreset preset);
+ void updateMousePos(const QPoint &mousePos);
+ void setCameraPreset(QDataVis::CameraPreset preset);
};
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
+QT_DATAVIS3D_END_NAMESPACE
#endif
diff --git a/src/datavis3d/utils/meshloader.cpp b/src/datavis3d/utils/meshloader.cpp
index 0bb780ce..ee2f12a6 100644
--- a/src/datavis3d/utils/meshloader.cpp
+++ b/src/datavis3d/utils/meshloader.cpp
@@ -1,41 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
@@ -49,7 +26,7 @@
#include <QDebug>
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVIS3D_BEGIN_NAMESPACE
QString slashTag = QStringLiteral("/");
@@ -145,4 +122,4 @@ bool MeshLoader::loadOBJ(const QString &path,
return true;
}
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/utils/meshloader_p.h b/src/datavis3d/utils/meshloader_p.h
index 88ab89b3..acbfb037 100644
--- a/src/datavis3d/utils/meshloader_p.h
+++ b/src/datavis3d/utils/meshloader_p.h
@@ -1,41 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
@@ -43,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the Qt API. It exists purely as an
+// This file is not part of the QtDataVis3D API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -52,12 +29,12 @@
#ifndef MESHLOADER_P_H
#define MESHLOADER_P_H
-#include "qdatavis3dglobal.h"
+#include "datavis3dglobal_p.h"
class QVector2D;
class QVector3D;
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVIS3D_BEGIN_NAMESPACE
class MeshLoader
{
@@ -69,6 +46,6 @@ class MeshLoader
// TODO: add loaders for other formats?
};
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
+QT_DATAVIS3D_END_NAMESPACE
#endif
diff --git a/src/datavis3d/utils/objecthelper.cpp b/src/datavis3d/utils/objecthelper.cpp
index d280abf8..cbd1e960 100644
--- a/src/datavis3d/utils/objecthelper.cpp
+++ b/src/datavis3d/utils/objecthelper.cpp
@@ -1,69 +1,38 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
#include "meshloader_p.h"
#include "vertexindexer_p.h"
#include "objecthelper_p.h"
+#include "abstractobjecthelper_p.h"
#include <QDebug>
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVIS3D_BEGIN_NAMESPACE
ObjectHelper::ObjectHelper(const QString &objectFile)
- : m_objectFile(objectFile),
- m_vertexbuffer(0),
- m_normalbuffer(0),
- m_uvbuffer(0),
- m_elementbuffer(0),
- m_indexCount(0),
- m_meshDataLoaded(false)
+ : m_objectFile(objectFile)
{
+ m_indicesType = GL_UNSIGNED_SHORT;
}
ObjectHelper::~ObjectHelper()
{
- glDeleteBuffers(1, &m_vertexbuffer);
- glDeleteBuffers(1, &m_uvbuffer);
- glDeleteBuffers(1, &m_normalbuffer);
- glDeleteBuffers(1, &m_elementbuffer);
}
void ObjectHelper::setObjectFile(const QString &objectFile)
@@ -129,37 +98,4 @@ void ObjectHelper::load()
m_meshDataLoaded = true;
}
-GLuint ObjectHelper::vertexBuf()
-{
- if (!m_meshDataLoaded)
- qFatal("No loaded object");
- return m_vertexbuffer;
-}
-
-GLuint ObjectHelper::normalBuf()
-{
- if (!m_meshDataLoaded)
- qFatal("No loaded object");
- return m_normalbuffer;
-}
-
-GLuint ObjectHelper::uvBuf()
-{
- if (!m_meshDataLoaded)
- qFatal("No loaded object");
- return m_uvbuffer;
-}
-
-GLuint ObjectHelper::elementBuf()
-{
- if (!m_meshDataLoaded)
- qFatal("No loaded object");
- return m_elementbuffer;
-}
-
-GLuint ObjectHelper::indexCount()
-{
- return m_indexCount;
-}
-
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/utils/objecthelper_p.h b/src/datavis3d/utils/objecthelper_p.h
index 6cac8770..ba9fc2f3 100644
--- a/src/datavis3d/utils/objecthelper_p.h
+++ b/src/datavis3d/utils/objecthelper_p.h
@@ -1,41 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
@@ -43,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the Qt API. It exists purely as an
+// This file is not part of the QtDataVis3D API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -52,14 +29,15 @@
#ifndef OBJECTHELPER_P_H
#define OBJECTHELPER_P_H
-#include "qdatavis3dglobal.h"
+#include "datavis3dglobal_p.h"
+#include "abstractobjecthelper_p.h"
#include <QOpenGLFunctions>
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVIS3D_BEGIN_NAMESPACE
-class ObjectHelper: protected QOpenGLFunctions
+class ObjectHelper : public AbstractObjectHelper
{
- public:
+public:
ObjectHelper(const QString &objectFile = QString());
~ObjectHelper();
@@ -67,25 +45,10 @@ class ObjectHelper: protected QOpenGLFunctions
void load();
- GLuint vertexBuf();
- GLuint normalBuf();
- GLuint uvBuf();
- GLuint elementBuf();
- GLuint indexCount();
-
- private:
+private:
QString m_objectFile;
-
- GLuint m_vertexbuffer;
- GLuint m_normalbuffer;
- GLuint m_uvbuffer;
- GLuint m_elementbuffer;
-
- GLuint m_indexCount;
-
- GLboolean m_meshDataLoaded;
};
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
+QT_DATAVIS3D_END_NAMESPACE
#endif
diff --git a/src/datavis3d/utils/shaderhelper.cpp b/src/datavis3d/utils/shaderhelper.cpp
index c8a92dae..c8716910 100644
--- a/src/datavis3d/utils/shaderhelper.cpp
+++ b/src/datavis3d/utils/shaderhelper.cpp
@@ -1,41 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
@@ -43,7 +20,7 @@
#include <QOpenGLShader>
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVIS3D_BEGIN_NAMESPACE
ShaderHelper::ShaderHelper(QObject *parent,
const QString &vertexShader,
@@ -249,4 +226,4 @@ GLuint ShaderHelper::normalAtt()
return m_normalAttr;
}
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/utils/shaderhelper_p.h b/src/datavis3d/utils/shaderhelper_p.h
index 55d075de..97fcf8a0 100644
--- a/src/datavis3d/utils/shaderhelper_p.h
+++ b/src/datavis3d/utils/shaderhelper_p.h
@@ -1,41 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
@@ -43,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the Qt API. It exists purely as an
+// This file is not part of the QtDataVis3D API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -52,12 +29,12 @@
#ifndef SHADERHELPER_P_H
#define SHADERHELPER_P_H
-#include "qdatavis3dglobal.h"
+#include "datavis3dglobal_p.h"
#include <QOpenGLFunctions>
class QOpenGLShaderProgram;
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVIS3D_BEGIN_NAMESPACE
class ShaderHelper
{
@@ -128,6 +105,6 @@ class ShaderHelper
GLboolean m_initialized;
};
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
+QT_DATAVIS3D_END_NAMESPACE
#endif
diff --git a/src/datavis3d/utils/surfaceobject.cpp b/src/datavis3d/utils/surfaceobject.cpp
new file mode 100644
index 00000000..4c05c442
--- /dev/null
+++ b/src/datavis3d/utils/surfaceobject.cpp
@@ -0,0 +1,349 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "surfaceobject_p.h"
+#include "abstractobjecthelper_p.h"
+
+#include <QVector3D>
+#include <QVector2D>
+
+#include <QDebug>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+SurfaceObject::SurfaceObject()
+{
+ m_indicesType = GL_UNSIGNED_INT;
+}
+
+SurfaceObject::~SurfaceObject()
+{
+}
+
+void SurfaceObject::setUpSmoothData(QList<qreal> series, int columns, int rows, GLfloat yRange, bool changeGeometry)
+{
+ GLfloat width = (GLfloat(columns) - 1.0f) / 2.0f;
+ GLfloat depth = (GLfloat(rows) - 1.0f) / -2.0f;
+ GLfloat height = yRange / 2.0f;
+
+ // Create vertice table
+ QVector<QVector3D> vertices;
+ QVector<QVector2D> uvs;
+ float uvX = 1.0 / float(columns - 1);
+ float uvY = 1.0 / float(rows - 1);
+ int row = 0;
+ for (float i = 0.0f; i < float(rows); i += 1.0, row += columns) {
+ for (float j = 0; j < columns; j++) {
+ vertices.append(QVector3D(j / width - 1.0f,
+ series.at(row + int(j)) / height - 1.0f,
+ i / depth + 1.0f));
+ uvs.append(QVector2D(j * uvX, i * uvY));
+ }
+ }
+
+ // Create normals
+ QVector<QVector3D> normals;
+ for (int row = 0; row < (rows - 1) * columns; row += columns) {
+ for (int j = 0; j < columns - 1; j++) {
+ normals.append(normal(vertices.at(row + j),
+ vertices.at(row + j + 1),
+ vertices.at(row + columns + j)));
+ }
+ int p = row + columns - 1;
+ normals.append(normal(vertices.at(p),
+ vertices.at(p + columns),
+ vertices.at(p - 1)));
+ }
+ for (int j = (rows - 1) * columns ; j < rows * columns - 1; j++) {
+ normals.append(normal(vertices.at(j),
+ vertices.at(j - columns),
+ vertices.at(j + 1)));
+ }
+ int p = rows * columns - 1;
+ normals.append(normal(vertices.at(p),
+ vertices.at(p - 1),
+ vertices.at(p - columns - 1)));
+
+ // Create indices table
+ GLint *indices = 0;
+ if (changeGeometry) {
+ m_indexCount = 6 * (columns - 1) * (rows - 1);
+ indices = new GLint[m_indexCount];
+ p = 0;
+ for (int row = 0; row < (rows - 1) * columns; row += columns) {
+ for (int j = 0; j < columns - 1; j++) {
+ // Left triangle
+ indices[p++] = row + j + 1;
+ indices[p++] = row + columns + j;
+ indices[p++] = row + j;
+
+ // Right triangle
+ indices[p++] = row + columns + j + 1;
+ indices[p++] = row + columns + j;
+ indices[p++] = row + j + 1;
+ }
+ }
+ }
+
+ // Create line element indices
+ GLint *gridIndices = 0;
+ if (changeGeometry) {
+ m_gridIndexCount = 2 * columns * (rows - 1) + 2 * rows * (columns - 1);
+ gridIndices = new GLint[m_gridIndexCount];
+ p = 0;
+ for (int i = 0, row = 0; i < rows; i++, row += columns) {
+ for (int j = 0; j < columns - 1; j++) {
+ gridIndices[p++] = row + j;
+ gridIndices[p++] = row + j + 1;
+ }
+ }
+ for (int i = 0, row = 0; i < rows - 1; i++, row += columns) {
+ for (int j = 0; j < columns; j++) {
+ gridIndices[p++] = row + j;
+ gridIndices[p++] = row + j + columns;
+ }
+ }
+ }
+
+ createBuffers(vertices, uvs, normals, indices, gridIndices, changeGeometry);
+
+ if (indices)
+ delete indices;
+ if (gridIndices)
+ delete gridIndices;
+}
+
+
+void SurfaceObject::setUpData(QList<qreal> series, int columns, int rows, GLfloat yRange, bool changeGeometry)
+{
+ GLfloat width = (GLfloat(columns) - 1.0f) / 2.0f;
+ GLfloat depth = (GLfloat(rows) - 1.0f) / -2.0f;
+ GLfloat height = yRange / 2.0f;
+ float uvX = 1.0 / float(columns - 1);
+ float uvY = 1.0 / float(rows - 1);
+
+ // Create vertice table
+ QVector<QVector3D> vertices;
+ QVector<QVector2D> uvs;
+ int row = 0;
+ for (float i = 0.0f; i < float(rows); i += 1.0f, row += columns) {
+ for (float j = 0.0f; j < float(columns); j += 1.0f) {
+ vertices.append(QVector3D(j / width - 1.0f,
+ series.at(row + int(j)) / height - 1.0f,
+ i / depth + 1.0f));
+ uvs.append(QVector2D(j * uvX, i * uvY));
+ if (j > 0 && j < columns - 1) {
+ vertices.append(vertices.last());
+ uvs.append(uvs.last());
+ }
+ }
+ }
+
+ // Create normals & indices table
+ QVector<QVector3D> normals;
+ int doubleColumns = columns * 2 - 2;
+
+ GLint *indices = 0;
+ int p = 0;
+ if (changeGeometry) {
+ m_indexCount = 6 * (columns - 1) * (rows - 1);
+ indices = new GLint[m_indexCount];
+ }
+
+ for (int row = 0, upperRow = doubleColumns;
+ row < (rows - 1) * doubleColumns;
+ row += doubleColumns, upperRow += doubleColumns) {
+ for (int j = 0; j < doubleColumns; j += 2) {
+ // Normal for the left triangle
+ normals.append(normal(vertices.at(row + j),
+ vertices.at(row + j + 1),
+ vertices.at(upperRow + j)));
+
+ // Normal for the right triangle
+ normals.append(normal(vertices.at(row + j + 1),
+ vertices.at(upperRow + j + 1),
+ vertices.at(upperRow + j)));
+
+ if (changeGeometry) {
+ // Left triangle
+ indices[p++] = row + j + 1;
+ indices[p++] = upperRow + j;
+ indices[p++] = row + j;
+
+ // Right triangle
+ indices[p++] = upperRow + j + 1;
+ indices[p++] = upperRow + j;
+ indices[p++] = row + j + 1;
+ }
+ }
+ }
+
+ // Create grid line element indices
+ m_gridIndexCount = 2 * columns * (rows - 1) + 2 * rows * (columns - 1);
+ GLint *gridIndices = new GLint[m_gridIndexCount];
+ p = 0;
+ int rowLimit = (rows - 1) * doubleColumns;
+ for (int row = 0; row < rows * doubleColumns; row += doubleColumns) {
+ for (int j = 0; j < doubleColumns; j += 2) {
+ gridIndices[p++] = row + j;
+ gridIndices[p++] = row + j + 1;
+
+ if (row < rowLimit) {
+ gridIndices[p++] = row + j;
+ gridIndices[p++] = row + j + doubleColumns;
+ }
+ }
+ }
+ for (int i = doubleColumns - 1; i < rowLimit; i += doubleColumns) {
+ gridIndices[p++] = i;
+ gridIndices[p++] = i + doubleColumns;
+ }
+
+ createBuffers(vertices, uvs, normals, indices, gridIndices, changeGeometry);
+
+ if (indices)
+ delete indices;
+ if (gridIndices)
+ delete gridIndices;
+}
+
+
+void SurfaceObject::createBuffers(const QVector<QVector3D> &vertices, const QVector<QVector2D> &uvs,
+ const QVector<QVector3D> &normals, const GLint *indices,
+ const GLint *gridIndices, bool changeGeometry)
+{
+ initializeOpenGLFunctions();
+ if (m_meshDataLoaded) {
+ // Delete old data
+ glDeleteBuffers(1, &m_vertexbuffer);
+ glDeleteBuffers(1, &m_normalbuffer);
+ if (changeGeometry) {
+ glDeleteBuffers(1, &m_uvbuffer);
+ glDeleteBuffers(1, &m_elementbuffer);
+ glDeleteBuffers(1, &m_gridElementbuffer);
+ }
+ }
+
+ // Move to buffers
+ glGenBuffers(1, &m_vertexbuffer);
+ glBindBuffer(GL_ARRAY_BUFFER, m_vertexbuffer);
+ glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(QVector3D),
+ &vertices.at(0), GL_STATIC_DRAW);
+
+ glGenBuffers(1, &m_normalbuffer);
+ glBindBuffer(GL_ARRAY_BUFFER, m_normalbuffer);
+ glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(QVector3D),
+ &normals.at(0), GL_STATIC_DRAW);
+
+ if (changeGeometry) {
+ glGenBuffers(1, &m_uvbuffer);
+ glBindBuffer(GL_ARRAY_BUFFER, m_uvbuffer);
+ glBufferData(GL_ARRAY_BUFFER, uvs.size() * sizeof(QVector2D),
+ &uvs.at(0), GL_STATIC_DRAW);
+
+ glGenBuffers(1, &m_elementbuffer);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementbuffer);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_indexCount * sizeof(GLint),
+ indices, GL_STATIC_DRAW);
+
+ glGenBuffers(1, &m_gridElementbuffer);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_gridElementbuffer);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_gridIndexCount * sizeof(GLint),
+ gridIndices, GL_STATIC_DRAW);
+ }
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+
+ // We're done. Set the flag ON
+ m_meshDataLoaded = true;
+}
+
+GLuint SurfaceObject::gridElementBuf()
+{
+ if (!m_meshDataLoaded)
+ qFatal("No loaded object");
+ return m_gridElementbuffer;
+}
+
+GLuint SurfaceObject::gridIndexCount()
+{
+ return m_gridIndexCount;
+}
+
+QVector3D SurfaceObject::normal(const QVector3D &a, const QVector3D &b, const QVector3D &c)
+{
+ QVector3D v1 = b - a;
+ QVector3D v2 = c - a;
+ return QVector3D::crossProduct(v1, v2);
+}
+
+QT_DATAVIS3D_END_NAMESPACE
+
+
+
+// For rainy days
+
+// QVector3D vertices[] = {
+// QVector3D(-0.5f, 0.0f, 0.1f),
+// QVector3D(0.5f, 0.0f, 0.1f),
+// QVector3D(0.0f, 1.0f, -0.5f)
+// };
+
+// QVector3D normals[] = {
+// QVector3D(0.5, 0.0, 1.0),
+// QVector3D(0.5, 0.0, 1.0),
+// QVector3D(0.5, 0.0, 1.0)
+// };
+
+// vertices.append(QVector3D(-1.0f, 0.0f, 0.1f));
+// vertices.append(QVector3D(0.0f, 0.0f, 0.1f));
+// vertices.append(QVector3D(0.0f, 0.5f, -0.5f));
+
+// normals.append(QVector3D(0.5, 0.0, 1.0));
+// normals.append(QVector3D(0.5, 0.0, 1.0));
+// normals.append(QVector3D(0.5, 0.0, 1.0));
+
+//GLushort indices[] = {0, 1, 2, 1, 3, 2};
+//GLushort indices[] = {1, 3, 2};
+
+//qDebug() << indices[p + 0] << ", " << indices[p + 1] << ", " << indices[p + 2];
+//qDebug() << indices[p + 3] << ", " << indices[p + 4] << ", " << indices[p + 5];
+
+//qDebug() << "(" << float(j) / width << ", 0.0, " << float(i) / depth * -1.0f << ")";
+
+//normals.append(QVector3D(1,0,0));
+//normals.append(QVector3D(0,1,0));
+//normals.append(QVector3D(0,0,1));
+//normals.append(QVector3D(1,0,1));
+
+//normals.append(QVector3D(1,0,0));
+//normals.append(QVector3D(0,1,0));
+//normals.append(QVector3D(0,0,1));
+//normals.append(QVector3D(1,0,1));
+
+//normals.append(QVector3D(1,0,0));
+//normals.append(QVector3D(0,1,0));
+//normals.append(QVector3D(0,0,1));
+//normals.append(QVector3D(1,0,1));
+
+
+//qDebug() << "Left normal from (" << row + j << ", " << row + j + 1 << ", " << row + doubleColumns + j << ")";
+
+//qDebug() << "right normal from (" << row + j +1 << ", " << row + doubleColumns + j + 1 << ", " << row + doubleColumns + j << ")";
+
diff --git a/src/datavis3d/utils/surfaceobject_p.h b/src/datavis3d/utils/surfaceobject_p.h
new file mode 100644
index 00000000..729757c4
--- /dev/null
+++ b/src/datavis3d/utils/surfaceobject_p.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef SURFACEOBJECT_P_H
+#define SURFACEOBJECT_P_H
+
+#include "datavis3dglobal_p.h"
+#include "abstractobjecthelper_p.h"
+#include <QOpenGLFunctions>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class SurfaceObject : public AbstractObjectHelper
+{
+public:
+ SurfaceObject();
+ ~SurfaceObject();
+
+ void setUpData(QList<qreal> series, int columns, int rows, GLfloat yRange, bool changeGeometry);
+ void setUpSmoothData(QList<qreal> series, int columns, int rows, GLfloat yRange, bool changeGeometry);
+ GLuint gridElementBuf();
+ GLuint gridIndexCount();
+
+private:
+ QVector3D normal(const QVector3D &a, const QVector3D &b, const QVector3D &c);
+ void createBuffers(const QVector<QVector3D> &vertices, const QVector<QVector2D> &uvs,
+ const QVector<QVector3D> &normals, const GLint *indices,
+ const GLint *gridIndices, bool changeGeometry);
+
+private:
+ QList<qreal> m_series;
+ int m_dataWidth;
+ int m_dataDepth;
+ GLfloat m_yRange;
+ GLuint m_gridElementbuffer;
+ GLuint m_gridIndexCount;
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+#endif // SURFACEOBJECT_P_H
diff --git a/src/datavis3d/utils/texturehelper.cpp b/src/datavis3d/utils/texturehelper.cpp
index 3d827c50..1773c0f8 100644
--- a/src/datavis3d/utils/texturehelper.cpp
+++ b/src/datavis3d/utils/texturehelper.cpp
@@ -1,41 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
@@ -46,7 +23,7 @@
#include <QDebug>
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVIS3D_BEGIN_NAMESPACE
TextureHelper::TextureHelper()
{
@@ -101,6 +78,22 @@ GLuint TextureHelper::create2DTexture(const QImage &image, bool useTrilinearFilt
return textureId;
}
+GLuint TextureHelper::create2DTexture(const uchar *image, int width, int height)
+{
+ GLuint textureId;
+ glGenTextures(1, &textureId);
+ glBindTexture(GL_TEXTURE_2D, textureId);
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height,
+ 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+ return textureId;
+}
+
GLuint TextureHelper::createCubeMapTexture(const QImage &image, bool useTrilinearFiltering)
{
if (image.isNull())
@@ -139,8 +132,8 @@ GLuint TextureHelper::createSelectionBuffer(const QSize &size, GLuint &texture,
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//#if !defined(QT_OPENGL_ES_2)
-// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, size.width(), size.height(), 0, GL_RGB,
-// GL_UNSIGNED_INT, NULL);
+// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(), 0, GL_RGB,
+// GL_UNSIGNED_BYTE, NULL);
//#else
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, size.width(), size.height(), 0, GL_RGB,
GL_UNSIGNED_BYTE, NULL);
@@ -181,17 +174,18 @@ GLuint TextureHelper::createSelectionTexture(const QSize &size, GLuint &frameBuf
glBindTexture(GL_TEXTURE_2D, textureid);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-//#if !defined(QT_OPENGL_ES_2)
-// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, size.width(), size.height(), 0, GL_RGB,
-// GL_UNSIGNED_INT, NULL);
-//#else
+#if !defined(QT_OPENGL_ES_2)
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size.width(), size.height(), 0, GL_RGBA,
+ GL_UNSIGNED_BYTE, NULL);
+#else
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, size.width(), size.height(), 0, GL_RGB,
GL_UNSIGNED_BYTE, NULL);
-//#endif
+#endif
glBindTexture(GL_TEXTURE_2D, 0);
// Create render buffer
- glGenRenderbuffers(1, &depthBuffer);
+ if (!depthBuffer)
+ glGenRenderbuffers(1, &depthBuffer);
glBindRenderbuffer(GL_RENDERBUFFER, depthBuffer);
#if !defined(QT_OPENGL_ES_2)
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, size.width(), size.height());
@@ -201,7 +195,8 @@ GLuint TextureHelper::createSelectionTexture(const QSize &size, GLuint &frameBuf
glBindRenderbuffer(GL_RENDERBUFFER, 0);
// Create frame buffer
- glGenFramebuffers(1, &frameBuffer);
+ if (!frameBuffer)
+ glGenFramebuffers(1, &frameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
// Attach texture to color attachment
@@ -241,7 +236,8 @@ GLuint TextureHelper::createDepthTexture(const QSize &size, GLuint &frameBuffer,
glBindTexture(GL_TEXTURE_2D, 0);
// Create frame buffer
- glGenFramebuffers(1, &frameBuffer);
+ if (!frameBuffer)
+ glGenFramebuffers(1, &frameBuffer);
glBindFramebuffer(GL_FRAMEBUFFER, frameBuffer);
// Attach texture to depth attachment
@@ -395,4 +391,4 @@ QRgb TextureHelper::qt_gl_convertToGLFormatHelper(QRgb src_pixel, GLenum texture
}
}
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/utils/texturehelper_p.h b/src/datavis3d/utils/texturehelper_p.h
index e848f063..e8f17d33 100644
--- a/src/datavis3d/utils/texturehelper_p.h
+++ b/src/datavis3d/utils/texturehelper_p.h
@@ -1,41 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
@@ -43,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the Qt API. It exists purely as an
+// This file is not part of the QtDataVis3D API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -52,11 +29,11 @@
#ifndef TEXTUREHELPER_P_H
#define TEXTUREHELPER_P_H
-#include "qdatavis3dglobal.h"
+#include "datavis3dglobal_p.h"
#include <QOpenGLFunctions>
#include <QRgb>
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVIS3D_BEGIN_NAMESPACE
class TextureHelper : protected QOpenGLFunctions
{
@@ -67,6 +44,7 @@ class TextureHelper : protected QOpenGLFunctions
// Ownership of created texture is transferred to caller
GLuint create2DTexture(const QImage &image, bool useTrilinearFiltering = false,
bool convert = true);
+ GLuint create2DTexture(const uchar *image, int width, int height);
GLuint createCubeMapTexture(const QImage &image, bool useTrilinearFiltering = false);
// Returns selection framebuffer and inserts generated texture id to texture parameters
GLuint createSelectionBuffer(const QSize &size, GLuint &texture, GLuint &depthTexture);
@@ -83,10 +61,12 @@ class TextureHelper : protected QOpenGLFunctions
void convertToGLFormatHelper(QImage &dstImage, const QImage &srcImage, GLenum texture_format);
QRgb qt_gl_convertToGLFormatHelper(QRgb src_pixel, GLenum texture_format);
- friend class Q3DBarsPrivate;
- friend class Q3DMapsPrivate;
+ friend class Bars3dRenderer;
+ friend class Maps3DController;
+ friend class Surface3dRenderer;
+ friend class Scatter3DRenderer;
};
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
+QT_DATAVIS3D_END_NAMESPACE
#endif
diff --git a/src/datavis3d/utils/utils.cpp b/src/datavis3d/utils/utils.cpp
index 7acca185..cf6b91f8 100644
--- a/src/datavis3d/utils/utils.cpp
+++ b/src/datavis3d/utils/utils.cpp
@@ -1,41 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
@@ -51,7 +28,7 @@
#include <QDebug>
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVIS3D_BEGIN_NAMESPACE
#define NUM_IN_POWER(y, x) for (;y<x;y<<=1)
#define MIN_POWER 32
@@ -110,23 +87,23 @@ void Utils::printText(QPainter *painter, const QString &text, const QSize &posit
if (absoluteCoords) {
// This assumes absolute screen coordinates
painter->translate(position.width() - (((float)bgrStrLen / 2.0f)
- * cos(rotation * m_pi / 180.0f))
- + (((float)bgrHeight / 2.0f) * sin(rotation * m_pi / 180.0f)),
+ * qCos(qDegreesToRadians(rotation)))
+ + (((float)bgrHeight / 2.0f) * qSin(qDegreesToRadians(rotation))),
position.height()
- - ((((float)bgrHeight / 2.0f) * cos(rotation * m_pi / 180.0f))
- + (((float)bgrStrLen / 2.0f) * sin(rotation * m_pi / 180.0f))));
+ - ((((float)bgrHeight / 2.0f) * qCos(qDegreesToRadians(rotation)))
+ + (((float)bgrStrLen / 2.0f) * qSin(qDegreesToRadians(rotation)))));
} else {
// This calculates y as a distance from screen bottom
painter->translate(position.width() - (((float)bgrStrLen / 2.0f)
- * cos(rotation * m_pi / 180.0f))
- + (((float)bgrHeight / 2.0f) * sin(rotation * m_pi / 180.0f)),
+ * qCos(qDegreesToRadians(rotation)))
+ + (((float)bgrHeight / 2.0f) * qSin(qDegreesToRadians(rotation))),
painter->window().height() - position.height()
- - ((((float)bgrHeight / 2.0f) * cos(rotation * m_pi / 180.0f))
- + (((float)bgrStrLen / 2.0f) * sin(rotation * m_pi / 180.0f))));
+ - ((((float)bgrHeight / 2.0f) * qCos(qDegreesToRadians(rotation)))
+ + (((float)bgrStrLen / 2.0f) * qSin(qDegreesToRadians(rotation)))));
}
//qDebug() << painter->window().height() - position.height()
- // - ((((float)bgrHeight / 2.0f) * cos(rotation * m_pi / 180.0f))
- // + (((float)bgrStrLen / 2.0f) * sin(rotation * m_pi / 180.0f)));
+ // - ((((float)bgrHeight / 2.0f) * qCos(qDegreesToRadians(rotation)))
+ // + (((float)bgrStrLen / 2.0f) * qSin(qDegreesToRadians(rotation))));
painter->rotate(rotation);
painter->drawText(0, 0,
bgrStrLen, bgrHeight,
@@ -144,7 +121,7 @@ void Utils::printText(QPainter *painter, const QString &text, const QSize &posit
}
QImage Utils::printTextToImage(const QFont &font, const QString &text, const QColor &bgrColor,
- const QColor &txtColor, LabelTransparency transparency)
+ const QColor &txtColor, QDataVis::LabelTransparency transparency)
{
GLuint paddingWidth = 15;
GLuint paddingHeight = 15;
@@ -170,7 +147,7 @@ QImage Utils::printTextToImage(const QFont &font, const QString &text, const QCo
paddingHeight /= 2;
//qDebug() << "label size after padding" << labelSize << paddingWidth << paddingHeight;
#else
- if (TransparencyNoBackground == transparency)
+ if (QDataVis::TransparencyNoBackground == transparency)
labelSize = QSize(valueStrWidth, valueStrHeight);
else
labelSize = QSize(valueStrWidth + paddingWidth * 2, valueStrHeight + paddingHeight * 2);
@@ -187,7 +164,7 @@ QImage Utils::printTextToImage(const QFont &font, const QString &text, const QCo
painter.setCompositionMode(QPainter::CompositionMode_Source);
switch (transparency) {
// TODO: Texture size padding fix for Android f**ks this up for axis labels. Fix or disable for android.
- case TransparencyNoBackground: {
+ case QDataVis::TransparencyNoBackground: {
painter.setFont(valueFont);
painter.setPen(txtColor);
painter.drawText(0, 0,
@@ -196,7 +173,7 @@ QImage Utils::printTextToImage(const QFont &font, const QString &text, const QCo
text);
break;
}
- case TransparencyFromTheme: {
+ case QDataVis::TransparencyFromTheme: {
painter.setBrush(QBrush(bgrColor));
painter.setPen(bgrColor);
painter.drawRoundedRect(0, 0, labelSize.width(), labelSize.height(), 10.0, 10.0f);
@@ -208,7 +185,7 @@ QImage Utils::printTextToImage(const QFont &font, const QString &text, const QCo
text);
break;
}
- case TransparencyNone: {
+ case QDataVis::TransparencyNone: {
painter.setBrush(QBrush(bgrColor));
painter.setPen(bgrColor);
painter.drawRect(0, 0, labelSize.width(), labelSize.height());
@@ -254,4 +231,4 @@ QVector3D Utils::getSelection(QPoint mousepos, int height)
return selectedColor;
}
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/utils/utils.pri b/src/datavis3d/utils/utils.pri
index 566af55f..cef5ebf0 100644
--- a/src/datavis3d/utils/utils.pri
+++ b/src/datavis3d/utils/utils.pri
@@ -4,7 +4,9 @@ HEADERS += $$PWD/meshloader_p.h \
$$PWD/shaderhelper_p.h \
$$PWD/objecthelper_p.h \
$$PWD/texturehelper_p.h \
- $$PWD/utils_p.h
+ $$PWD/utils_p.h \
+ $$PWD/abstractobjecthelper_p.h \
+ $$PWD/surfaceobject_p.h
SOURCES += $$PWD/meshloader.cpp \
$$PWD/vertexindexer.cpp \
@@ -12,4 +14,6 @@ SOURCES += $$PWD/meshloader.cpp \
$$PWD/shaderhelper.cpp \
$$PWD/objecthelper.cpp \
$$PWD/texturehelper.cpp \
- $$PWD/utils.cpp
+ $$PWD/utils.cpp \
+ $$PWD/abstractobjecthelper.cpp \
+ $$PWD/surfaceobject.cpp
diff --git a/src/datavis3d/utils/utils_p.h b/src/datavis3d/utils/utils_p.h
index f809dad7..fe7d6081 100644
--- a/src/datavis3d/utils/utils_p.h
+++ b/src/datavis3d/utils/utils_p.h
@@ -1,41 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
@@ -43,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the Qt API. It exists purely as an
+// This file is not part of the QtDataVis3D API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -52,8 +29,7 @@
#ifndef UTILS_P_H
#define UTILS_P_H
-#include "qdatavis3dglobal.h"
-#include "qdatavis3namespace.h"
+#include "datavis3dglobal_p.h"
#include "q3dbars.h"
class QVector3D;
@@ -63,7 +39,7 @@ class QString;
class QPoint;
class QImage;
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVIS3D_BEGIN_NAMESPACE
class Utils
{
@@ -76,10 +52,10 @@ class Utils
const QString &text,
const QColor &bgrColor,
const QColor &txtColor,
- LabelTransparency transparency);
+ QDataVis::LabelTransparency transparency);
static QVector3D getSelection(QPoint mousepos, int height);
};
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
+QT_DATAVIS3D_END_NAMESPACE
#endif
diff --git a/src/datavis3d/utils/vertexindexer.cpp b/src/datavis3d/utils/vertexindexer.cpp
index c1dfb1aa..6efba116 100644
--- a/src/datavis3d/utils/vertexindexer.cpp
+++ b/src/datavis3d/utils/vertexindexer.cpp
@@ -1,41 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
@@ -46,14 +23,14 @@
#include <QDebug>
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVIS3D_BEGIN_NAMESPACE
int unique_vertices = 0;
// Returns true if v1 can be considered equal to v2
bool VertexIndexer::is_near(float v1, float v2)
{
- return qFabs(v1 - v2) < 0.01f;
+ return qAbs(v1 - v2) < 0.01f;
}
// Searches through all already-exported vertices
@@ -173,4 +150,4 @@ void VertexIndexer::indexVBO_TBN(const QVector<QVector3D> &in_vertices,
//qDebug() << "unique vertices" << unique_vertices;
}
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/utils/vertexindexer_p.h b/src/datavis3d/utils/vertexindexer_p.h
index cced863b..3ca62236 100644
--- a/src/datavis3d/utils/vertexindexer_p.h
+++ b/src/datavis3d/utils/vertexindexer_p.h
@@ -1,41 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
@@ -43,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the Qt API. It exists purely as an
+// This file is not part of the QtDataVis3D API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -52,13 +29,13 @@
#ifndef VERTEXINDEXER_P_H
#define VERTEXINDEXER_P_H
-#include "qdatavis3dglobal.h"
+#include "datavis3dglobal_p.h"
#include <QVector>
#include <QVector2D>
#include <QVector3D>
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVIS3D_BEGIN_NAMESPACE
class VertexIndexer
{
@@ -106,6 +83,6 @@ class VertexIndexer
unsigned short &result);
};
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
+QT_DATAVIS3D_END_NAMESPACE
#endif
diff --git a/src/datavis3dqml2/datavis3dqml2.pro b/src/datavis3dqml2/datavis3dqml2.pro
index 59abef57..c994c5be 100644
--- a/src/datavis3dqml2/datavis3dqml2.pro
+++ b/src/datavis3dqml2/datavis3dqml2.pro
@@ -6,27 +6,33 @@ CONFIG += qt plugin
TARGET = $$qtLibraryTarget($$TARGET)
uri = com.digia.QtDataVis3D
-staticlib:DEFINES+=QTENTERPRISE_DATAVIS3D_STATICLIB
+static {
+ DEFINES += QT_DATAVIS3D_STATICLIB
+ CONFIG -= static staticlib
+}
# Input
-INCLUDEPATH += ../datavis3d/engine
+INCLUDEPATH += ../datavis3d/engine \
+ ../datavis3d/global \
+ ../datavis3d/data
SOURCES += \
datavis3dqml2_plugin.cpp \
declarativebars.cpp \
- declarativemaps.cpp #\
- #declarativedataitem.cpp \
- #declarativedatarow.cpp \
- #declarativedataset.cpp
+ declarativebarsrenderer.cpp \
+ declarativescatter.cpp \
+ declarativescatterrenderer.cpp \
+ declarativemaps.cpp \
+ declarativemapsrenderer.cpp
HEADERS += \
datavis3dqml2_plugin.h \
- declarativebars.h \
- declarativemaps.h \ #\
- declarativebars_p.h
- #declarativedataitem.h \
- #declarativedatarow.h \
- #declarativedataset.h
+ declarativebars_p.h \
+ declarativebarsrenderer_p.h \
+ declarativescatter_p.h \
+ declarativescatterrenderer_p.h \
+ declarativemaps_p.h \
+ declarativemapsrenderer_p.h
OTHER_FILES = qmldir
diff --git a/src/datavis3dqml2/datavis3dqml2_plugin.cpp b/src/datavis3dqml2/datavis3dqml2_plugin.cpp
index 86923cde..d1e534f8 100644
--- a/src/datavis3dqml2/datavis3dqml2_plugin.cpp
+++ b/src/datavis3dqml2/datavis3dqml2_plugin.cpp
@@ -1,63 +1,48 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
#include "datavis3dqml2_plugin.h"
#include <qqml.h>
-#include <QDebug>
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
void Datavis3dqml2Plugin::registerTypes(const char *uri)
{
- qDebug() << "Datavis3dqml2Plugin::registerTypes()";
-
// @uri com.digia.QtDataVis3D
- qmlRegisterType<QDataItem>(uri, 1, 0, "DataItem");
- qmlRegisterType<QDataRow>(uri, 1, 0, "DataRow");
- qmlRegisterType<QDataSet>(uri, 1, 0, "DataSet");
+ qmlRegisterUncreatableType<QAbstractItemModel>(uri, 1, 0, "AbstractItemModel",
+ QLatin1String("Trying to create uncreatable: AbstractItemModel."));
+ qmlRegisterUncreatableType<QDataVis>(uri, 1, 0, "DataVis",
+ QLatin1String("Trying to create uncreatable: DataVis."));
+ qmlRegisterUncreatableType<QAbstractAxis>(uri, 1, 0, "AbstractAxis",
+ QLatin1String("Trying to create uncreatable: AbstractAxis."));
+
+ qmlRegisterType<QItemModelBarDataMapping>(uri, 1, 0, "BarDataMapping");
+ qmlRegisterType<QItemModelMapDataMapping>(uri, 1, 0, "MapDataMapping");
+ qmlRegisterType<QItemModelScatterDataMapping>(uri, 1, 0, "ScatterDataMapping");
qmlRegisterType<DeclarativeBars>(uri, 1, 0, "Bars3D");
-}
+ qmlRegisterType<DeclarativeMaps>(uri, 1, 0, "Maps3D");
+ qmlRegisterType<DeclarativeScatter>(uri, 1, 0, "Scatter3D");
-//#include "moc_datavis3dqml2_plugin.cpp"
+ qmlRegisterType<QValueAxis>(uri, 1, 0, "ValueAxis");
+ qmlRegisterType<QCategoryAxis>(uri, 1, 0, "CategoryAxis");
+}
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3dqml2/datavis3dqml2_plugin.h b/src/datavis3dqml2/datavis3dqml2_plugin.h
index 9dcf00cb..ac88e1b5 100644
--- a/src/datavis3dqml2/datavis3dqml2_plugin.h
+++ b/src/datavis3dqml2/datavis3dqml2_plugin.h
@@ -1,75 +1,53 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
#ifndef DATAVIS3DQML2_PLUGIN_H
#define DATAVIS3DQML2_PLUGIN_H
-#include "QtDataVis3D/qdatavis3dglobal.h"
-#include "QtDataVis3D/qdatavis3namespace.h"
-#include "qdataitem.h"
-#include "qdatarow.h"
-#include "qdataset.h"
-
-#include "declarativebars.h"
-#include "declarativemaps.h"
-//#include "declarativedataitem.h"
-//#include "declarativedatarow.h"
-//#include "declarativedataset.h"
+#include "datavis3dglobal_p.h"
+#include "declarativebars_p.h"
+#include "declarativemaps_p.h"
+#include "declarativescatter_p.h"
+#include "qitemmodelbardatamapping.h"
+#include "qitemmodelmapdatamapping.h"
+#include "qitemmodelscatterdatamapping.h"
+#include "qvalueaxis.h"
+#include "qcategoryaxis.h"
#include <QQmlExtensionPlugin>
-QTENTERPRISE_DATAVIS3D_USE_NAMESPACE
-
-//Q_DECLARE_METATYPE(DeclarativeDataItem *)
-//Q_DECLARE_METATYPE(DeclarativeDataRow *)
-//Q_DECLARE_METATYPE(DeclarativeDataSet *)
+QT_DATAVIS3D_USE_NAMESPACE
Q_DECLARE_METATYPE(DeclarativeBars *)
Q_DECLARE_METATYPE(DeclarativeMaps *)
+Q_DECLARE_METATYPE(DeclarativeScatter *)
+
+Q_DECLARE_METATYPE(QItemModelBarDataMapping *)
+Q_DECLARE_METATYPE(QItemModelMapDataMapping *)
+Q_DECLARE_METATYPE(QItemModelScatterDataMapping *)
+Q_DECLARE_METATYPE(QAbstractItemModel *)
+Q_DECLARE_METATYPE(QDataVis *)
-Q_DECLARE_METATYPE(QDataItem *)
-Q_DECLARE_METATYPE(QDataRow *)
-Q_DECLARE_METATYPE(QDataSet *)
+Q_DECLARE_METATYPE(QAbstractAxis *)
+Q_DECLARE_METATYPE(QCategoryAxis *)
+Q_DECLARE_METATYPE(QValueAxis *)
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVIS3D_BEGIN_NAMESPACE
class Datavis3dqml2Plugin : public QQmlExtensionPlugin
{
@@ -80,7 +58,7 @@ public:
void registerTypes(const char *uri);
};
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
+QT_DATAVIS3D_END_NAMESPACE
#endif // DATAVIS3DQML2_PLUGIN_H
diff --git a/src/datavis3dqml2/declarativebars.cpp b/src/datavis3dqml2/declarativebars.cpp
index 3194baa5..e7af7f8c 100644
--- a/src/datavis3dqml2/declarativebars.cpp
+++ b/src/datavis3dqml2/declarativebars.cpp
@@ -1,63 +1,50 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
-#include "declarativebars.h"
-#include "bars3dshared_p.h"
+#include "declarativebars_p.h"
+#include "declarativebarsrenderer_p.h"
+#include "qitemmodelbardataproxy.h"
+#include "qvalueaxis.h"
-#include <QtQuick/QQuickWindow>
-#include <QtGui/QOpenGLFramebufferObject>
-#include <QOpenGLContext>
-#include <QGuiApplication>
-#include <QThread>
-#include <QDebug>
+QT_DATAVIS3D_BEGIN_NAMESPACE
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
+const QString smoothString(QStringLiteral("Smooth"));
-DeclarativeBars::DeclarativeBars(QQuickItem *parent): QQuickItem(parent), m_cachedState(new DeclarativeBarsCachedStatePrivate()), m_shared(0)
+DeclarativeBars::DeclarativeBars(QQuickItem *parent)
+ : QQuickItem(parent),
+ m_shared(0),
+ m_initialisedSize(0, 0),
+ m_cameraPreset(QDataVis::NoPreset),
+ m_theme(QDataVis::ThemeDefault)
{
setFlags(QQuickItem::ItemHasContents);
+ setAcceptedMouseButtons(Qt::AllButtons);
- setRotation(180.0);
+ // TODO: These seem to have no effect; find a way to activate anti-aliasing
setAntialiasing(true);
setSmooth(true);
+
+ // Create the shared component on the main GUI thread.
+ m_shared = new Bars3dController(boundingRect().toRect());
+ QObject::connect(m_shared, &Bars3dController::shadowQualityChanged, this,
+ &DeclarativeBars::handleShadowQualityUpdate);
+
+ m_shared->setDataProxy(new QItemModelBarDataProxy);
}
DeclarativeBars::~DeclarativeBars()
@@ -65,316 +52,329 @@ DeclarativeBars::~DeclarativeBars()
delete m_shared;
}
-QSGNode *DeclarativeBars::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
+void DeclarativeBars::handleShadowQualityUpdate(QDataVis::ShadowQuality quality)
{
- qDebug() << "Enter DeclarativeBars::updatePaintNode";
- // Delete old node and recreate it. This function gets called when window geometry changes.
- if (oldNode)
- delete oldNode;
-
- if (!m_shared)
- m_shared = new Bars3dShared(boundingRect().toRect());
-
- // Lazy initialization of shared object on the SGRenderThread
- m_shared->initializeOpenGL();
-
- // We need to create a node class that does the rendering (ie. a node that "captures" the rendering we do)
- qDebug() << "DeclarativeBars::updatePaintNode Creating new node";
-
- // Create the new render node
- DeclarativeBarsRenderer *node = new DeclarativeBarsRenderer(window(), m_shared);
- node->setRect(boundingRect());
- m_shared->setBoundingRect(boundingRect().toRect());
-
- if (m_cachedState->m_isSampleSpaceSet) {
- m_shared->setupSampleSpace(m_cachedState->m_samplesRow, m_cachedState->m_samplesColumn, m_cachedState->m_labelRow, m_cachedState->m_labelColumn, m_cachedState->m_labelHeight);
- m_cachedState->m_isSampleSpaceSet = false;
- }
+ emit shadowQualityChanged(quality);
+}
- if (m_cachedState->m_dataRow) {
- m_shared->addDataRow(m_cachedState->m_dataRow);
- m_cachedState->m_dataRow = 0;
- }
+void DeclarativeBars::classBegin()
+{
+ qDebug() << "classBegin";
+}
- if (m_cachedState->m_isSelectionModeSet) {
- m_shared->setSelectionMode(m_cachedState->m_selectionMode);
- m_cachedState->m_isSelectionModeSet = false;
- }
+void DeclarativeBars::componentComplete()
+{
+ qDebug() << "componentComplete";
+}
- if (m_cachedState->m_isLabelTransparencySet) {
- m_shared->setLabelTransparency(m_cachedState->m_labelTransparency);
- m_cachedState->m_isLabelTransparencySet = false;
+QSGNode *DeclarativeBars::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
+{
+ // If old node exists and has right size, reuse it.
+ if (oldNode && m_initialisedSize == boundingRect().size().toSize()) {
+ // Update bounding rectangle (that has same size as before).
+ static_cast<DeclarativeBarsRenderer *>( oldNode )->setRect(boundingRect());
+ return oldNode;
}
- if (m_cachedState->m_isShadowQualitySet) {
- m_shared->setShadowQuality(m_cachedState->m_shadowQuality);
- m_cachedState->m_isShadowQualitySet = false;
- }
+ // Create a new render node when size changes or if there is no node yet
+ m_initialisedSize = boundingRect().size().toSize();
- if (m_cachedState->m_isGridSet) {
- m_shared->setGridEnabled(m_cachedState->m_isGridEnabled);
- m_cachedState->m_isGridSet = false;
- }
+ // Delete old node
+ if (oldNode)
+ delete oldNode;
- qDebug() << "Exit DeclarativeBars::updatePaintNode";
+ // Create a new one and set it's bounding rectangle
+ DeclarativeBarsRenderer *node = new DeclarativeBarsRenderer(window(), m_shared);
+ node->setRect(boundingRect());
+ m_shared->setBoundingRect(boundingRect().toRect());
return node;
}
-void DeclarativeBars::setBarSpecs(QSizeF thickness, QSizeF spacing, bool relative)
+void DeclarativeBars::setupSampleSpace(int rowCount, int columnCount)
{
- m_shared->setBarSpecs(thickness, spacing, relative);
+ m_shared->setupSampleSpace(rowCount, columnCount);
}
-void DeclarativeBars::setBarType(BarStyle style, bool smooth)
+void DeclarativeBars::setBarColor(QColor baseColor, QColor heightColor, QColor depthColor,
+ bool uniform)
{
- m_shared->setBarType(style, smooth);
+ m_shared->setObjectColor(baseColor, heightColor, depthColor, uniform);
}
-void DeclarativeBars::setupSampleSpace(int samplesRow, int samplesColumn, const QString &labelRow,
- const QString &labelColumn, const QString &labelHeight)
+void DeclarativeBars::setCameraPosition(qreal horizontal, qreal vertical, int distance)
{
- m_cachedState->m_samplesRow = samplesRow;
- m_cachedState->m_samplesColumn = samplesColumn;
- m_cachedState->m_labelRow = labelRow;
- m_cachedState->m_labelColumn = labelColumn;
- m_cachedState->m_labelHeight = labelHeight;
- m_cachedState->m_isSampleSpaceSet = true;
+ m_shared->setCameraPosition(GLfloat(horizontal), GLfloat(vertical), GLint(distance));
}
-
-void DeclarativeBars::setCameraPreset(CameraPreset preset)
+void DeclarativeBars::setData(QAbstractItemModel *data)
{
- m_shared->setCameraPreset(preset);
+ static_cast<QItemModelBarDataProxy *>(m_shared->dataProxy())->setItemModel(data);
}
-void DeclarativeBars::setCameraPosition(GLfloat horizontal, GLfloat vertical, GLint distance)
+QAbstractItemModel *DeclarativeBars::data()
{
- m_shared->setCameraPosition(horizontal, vertical, distance);
+ return static_cast<QItemModelBarDataProxy *>(m_shared->dataProxy())->itemModel();
}
-void DeclarativeBars::setTheme(ColorTheme theme)
+void DeclarativeBars::setMapping(QItemModelBarDataMapping *mapping)
{
- m_shared->setTheme(theme);
+ static_cast<QItemModelBarDataProxy *>(m_shared->dataProxy())->setMapping(mapping);
}
-void DeclarativeBars::setBarColor(QColor baseColor, QColor heightColor, QColor depthColor, bool uniform)
+QCategoryAxis *DeclarativeBars::axisX() const
{
- m_shared->setBarColor(baseColor, heightColor, depthColor, uniform);
+ return static_cast<QCategoryAxis *>(m_shared->axisX());
}
+void DeclarativeBars::setAxisX(QCategoryAxis *axis)
+{
+ m_shared->setAxisX(axis);
+}
-void DeclarativeBars::setFontSize(float fontsize)
+QValueAxis *DeclarativeBars::axisY() const
{
- m_shared->setFontSize(fontsize);
+ return static_cast<QValueAxis *>(m_shared->axisY());
}
-float DeclarativeBars::fontSize()
+void DeclarativeBars::setAxisY(QValueAxis *axis)
{
- return m_shared->fontSize();
+ m_shared->setAxisY(axis);
}
-void DeclarativeBars::setFont(const QFont &font)
+QCategoryAxis *DeclarativeBars::axisZ() const
{
- m_shared->setFont(font);
+ return static_cast<QCategoryAxis *>(m_shared->axisZ());
}
-QFont DeclarativeBars::font()
+void DeclarativeBars::setAxisZ(QCategoryAxis *axis)
{
- return m_shared->font();
+ m_shared->setAxisZ(axis);
}
-void DeclarativeBars::setLabelTransparency(DeclarativeBars::LabelTransparency transparency)
+QItemModelBarDataMapping *DeclarativeBars::mapping() const
{
- m_cachedState->m_labelTransparency = QtDataVis3D::LabelTransparency(transparency);
- m_cachedState->m_isLabelTransparencySet = true;
+ return static_cast<QItemModelBarDataProxy *>(m_shared->dataProxy())->mapping();
}
-DeclarativeBars::LabelTransparency DeclarativeBars::labelTransparency()
+void DeclarativeBars::setBarThickness(QSizeF thickness)
{
- return DeclarativeBars::LabelTransparency(m_shared->labelTransparency());
+ m_shared->setBarSpecs(thickness, barSpacing(), isBarSpacingRelative());
}
-void DeclarativeBars::setGridEnabled(bool enable)
+QSizeF DeclarativeBars::barThickness()
{
- m_cachedState->m_isGridEnabled = enable;
- m_cachedState->m_isGridSet = true;
+ return m_shared->barThickness();
}
-bool DeclarativeBars::gridEnabled()
+void DeclarativeBars::setBarSpacing(QSizeF spacing)
{
- return m_shared->gridEnabled();
+ m_shared->setBarSpecs(barThickness(), spacing, isBarSpacingRelative());
}
-void DeclarativeBars::setBackgroundEnabled(bool enable)
+QSizeF DeclarativeBars::barSpacing()
{
- m_shared->setBackgroundEnabled(enable);
+ return m_shared->barSpacing();
}
-bool DeclarativeBars::backgroundEnabled()
+void DeclarativeBars::setBarSpacingRelative(bool relative)
{
- return m_shared->backgroundEnabled();
+ m_shared->setBarSpecs(barThickness(), barSpacing(), relative);
}
-void DeclarativeBars::setTickCount(GLint tickCount, GLfloat step, GLfloat minimum)
+bool DeclarativeBars::isBarSpacingRelative()
{
- m_shared->setTickCount(tickCount, step, minimum);
+ return m_shared->isBarSpecRelative();
}
-void DeclarativeBars::addDataRow(const QVector<float> &dataRow, const QString &labelRow,
- const QVector<QString> &labelsColumn)
+void DeclarativeBars::setBarType(QDataVis::MeshStyle style)
{
- qDebug() << "Enter DeclarativeBars::addDataRow(const QVector<float> &dataRow...)";
- m_shared->addDataRow(dataRow, labelRow, labelsColumn);
+ QString objFile = m_shared->meshFileName();
+ bool smooth = objFile.endsWith(smoothString);
+ m_shared->setBarType(style, smooth);
}
-void DeclarativeBars::addDataRow(const QVector<QDataItem*> &dataRow, const QString &labelRow,
- const QVector<QString> &labelsColumn)
+QDataVis::MeshStyle DeclarativeBars::barType()
{
- qDebug() << "Enter DeclarativeBars::addDataRow(const QVector<QDataItem*> &dataRow...)";
- m_shared->addDataRow(dataRow, labelRow, labelsColumn);
+ QString objFile = m_shared->meshFileName();
+ if (objFile.contains("/sphere"))
+ return QDataVis::Spheres;
+ else
+ return QDataVis::Dots;
}
-void DeclarativeBars::addDataRow(QDataRow *dataRow)
+void DeclarativeBars::setBarSmooth(bool smooth)
{
- qDebug() << "Enter DeclarativeBars::addDataRow(QDataRow *dataRow)";
- m_cachedState->m_dataRow = dataRow;
+ QString objFile = m_shared->meshFileName();
+ if (objFile.endsWith(smoothString)) {
+ if (smooth)
+ return; // Already smooth; do nothing
+ else // Rip Smooth off the end
+ objFile.resize(objFile.indexOf(smoothString));
+ } else {
+ if (!smooth) // Already flat; do nothing
+ return;
+ else // Append Smooth to the end
+ objFile.append(smoothString);
+ }
+ m_shared->setMeshFileName(objFile);
}
-void DeclarativeBars::addDataSet(const QVector< QVector<float> > &data, const QVector<QString> &labelsRow,
- const QVector<QString> &labelsColumn)
+bool DeclarativeBars::barSmooth()
{
- m_shared->addDataSet(data, labelsRow,labelsColumn);
+ QString objFile = m_shared->meshFileName();
+ return objFile.endsWith(smoothString);
}
-void DeclarativeBars::addDataSet(const QVector< QVector<QDataItem*> > &data,
- const QVector<QString> &labelsRow,
- const QVector<QString> &labelsColumn)
+void DeclarativeBars::setMeshFileName(const QString &objFileName)
{
- m_shared->addDataSet(data, labelsRow, labelsColumn);
+ m_shared->setMeshFileName(objFileName);
}
-void DeclarativeBars::addDataSet(QDataSet* dataSet)
+QString DeclarativeBars::meshFileName()
{
- m_shared->addDataSet(dataSet);
+ return m_shared->meshFileName();
}
-void DeclarativeBars::setSelectionMode(DeclarativeBars::SelectionMode mode)
+void DeclarativeBars::setCameraPreset(QDataVis::CameraPreset preset)
{
- m_cachedState->m_selectionMode = QtDataVis3D::SelectionMode(mode);
- m_cachedState->m_isSelectionModeSet = true;
+ // TODO: Implement correctly once "improved camera api" (QTRD-2122) is implemented
+ // We need to save this locally, as there are no getters for it in controller
+ m_cameraPreset = preset;
+ m_shared->setCameraPreset(preset);
}
-DeclarativeBars::SelectionMode DeclarativeBars::selectionMode()
+QDataVis::CameraPreset DeclarativeBars::cameraPreset()
{
- return DeclarativeBars::SelectionMode(m_shared->selectionMode());
+ return m_cameraPreset;
}
-void DeclarativeBars::setShadow(DeclarativeBars::ShadowQuality quality)
+void DeclarativeBars::setTheme(QDataVis::ColorTheme theme)
{
- m_cachedState->m_shadowQuality = QtDataVis3D::ShadowQuality(quality);
- m_cachedState->m_isShadowQualitySet = true;
+ // TODO: Implement correctly once "user-modifiable themes" (QTRD-2120) is implemented
+ // We need to save this locally, as there are no getters for it in controller
+ m_theme = theme;
+ m_shared->setColorTheme(theme);
}
-DeclarativeBars::ShadowQuality DeclarativeBars::shadow()
+QDataVis::ColorTheme DeclarativeBars::theme()
{
- return DeclarativeBars::ShadowQuality(m_shared->shadowQuality());
+ return m_theme;
}
-void DeclarativeBars::setMeshFileName(const QString &objFileName)
+void DeclarativeBars::setFontSize(float fontsize)
{
- m_shared->setMeshFileName(objFileName);
+ m_shared->setFontSize(fontsize);
}
+float DeclarativeBars::fontSize()
+{
+ return m_shared->fontSize();
+}
+void DeclarativeBars::setFont(const QFont &font)
+{
+ m_shared->setFont(font);
+}
+QFont DeclarativeBars::font()
+{
+ return m_shared->font();
+}
-DeclarativeBarsRenderer::DeclarativeBarsRenderer(QQuickWindow *window, Bars3dShared *renderer)
- : m_fbo(0),
- m_texture(0),
- m_window(window),
- m_barsRenderer(renderer)
+void DeclarativeBars::setLabelTransparency(QDataVis::LabelTransparency transparency)
{
- qDebug() << "DeclarativeBarsRenderer::DeclarativeBarsRenderer()";
- connect(m_window, SIGNAL(beforeRendering()), this, SLOT(render()), Qt::DirectConnection);
- qDebug() << "QQuickWindow::openglContext()->thread()" << m_window->openglContext()->thread();
- qDebug() << "QGuiApplication::instance()->thread()" << QGuiApplication::instance()->thread();
+ m_shared->setLabelTransparency(transparency);
}
-DeclarativeBarsRenderer::~DeclarativeBarsRenderer()
+QDataVis::LabelTransparency DeclarativeBars::labelTransparency()
{
- delete m_texture;
- delete m_fbo;
+ return m_shared->labelTransparency();
}
-void DeclarativeBarsRenderer::render()
+void DeclarativeBars::setGridVisible(bool visible)
{
- static bool firstRender = true;
- if (firstRender) qDebug() << "DeclarativeBarsRenderer::render() running on thread "<< QThread::currentThread();
- firstRender = false;
+ m_shared->setGridEnabled(visible);
+}
- QSize size = rect().size().toSize();
+bool DeclarativeBars::isGridVisible()
+{
+ return m_shared->gridEnabled();
+}
- if (!m_fbo) {
- QOpenGLFramebufferObjectFormat format;
- format.setAttachment(QOpenGLFramebufferObject::CombinedDepthStencil);
- m_fbo = new QOpenGLFramebufferObject(size, format);
- m_texture = m_window->createTextureFromId(m_fbo->texture(), size);
+void DeclarativeBars::setBackgroundVisible(bool visible)
+{
+ m_shared->setBackgroundEnabled(visible);
+}
- // TODO: If we create the vis3d this way, how do we connect it with QML?
- // Should we create it at QML and give it to DataVisView using a property (setVisualizer or similar)?
- // DataVisView can then give it here as an argument in constructor?
+bool DeclarativeBars::isBackgroundVisible()
+{
+ return m_shared->backgroundEnabled();
+}
- // TODO: For testing. Add some data to scene.
- QVector< QVector<float> > data;
- QVector<float> row;
- for (float j = 0.0f; j < 5.0f; j++) {
- for (float i = 0.0f; i < 5.0f; i++)
- row.append(j / 10.0f + i / 10.0f);
- data.append(row);
- row.clear();
- }
+void DeclarativeBars::setSelectionMode(QDataVis::SelectionMode mode)
+{
+ m_shared->setSelectionMode(mode);
+}
- setTexture(m_texture);
- }
+QDataVis::SelectionMode DeclarativeBars::selectionMode()
+{
+ return m_shared->selectionMode();
+}
- m_fbo->bind();
+void DeclarativeBars::setShadowQuality(QDataVis::ShadowQuality quality)
+{
+ m_shared->setShadowQuality(quality);
+}
- // SGRendering State resets between calls...
- glDepthMask(true);
- glEnable(GL_DEPTH_TEST);
- glDepthFunc(GL_LESS);
- glEnable(GL_CULL_FACE);
- glCullFace(GL_BACK);
+QDataVis::ShadowQuality DeclarativeBars::shadowQuality()
+{
+ return m_shared->shadowQuality();
+}
- // Emulate mouse movement
- // TODO: Remove this and implement properly
- static int rot = 0;
- rot += 5;
- if (rot > 2870) rot = 0;
- m_barsRenderer->m_mousePos.setX(rot);
- m_barsRenderer->m_mousePos.setY(100);
+int DeclarativeBars::rows() const
+{
+ return m_shared->rowCount();
+}
- // Call the shared rendering function
- m_barsRenderer->render();
+void DeclarativeBars::setRows(int rows)
+{
+ setupSampleSpace(rows, columns());
+}
- m_fbo->bindDefault();
+int DeclarativeBars::columns() const
+{
+ return m_shared->columnCount();
+}
- m_window->update();
+void DeclarativeBars::setColumns(int columns)
+{
+ setupSampleSpace(rows(), columns);
}
+void DeclarativeBars::mousePressEvent(QMouseEvent *event)
+{
+ QPoint mousePos = event->pos();
+ //mousePos.setY(height() - mousePos.y());
+ m_shared->mousePressEvent(event, mousePos);
+}
-DeclarativeBarsCachedStatePrivate::DeclarativeBarsCachedStatePrivate() :
- m_isSampleSpaceSet(false),
- m_labelRow(QStringLiteral("")),
- m_labelColumn(QStringLiteral("")),
- m_labelHeight(QStringLiteral("")),
- m_dataRow(0)
+void DeclarativeBars::mouseReleaseEvent(QMouseEvent *event)
{
+ QPoint mousePos = event->pos();
+ //mousePos.setY(height() - mousePos.y());
+ m_shared->mouseReleaseEvent(event, mousePos);
}
-DeclarativeBarsCachedStatePrivate::~DeclarativeBarsCachedStatePrivate()
+void DeclarativeBars::mouseMoveEvent(QMouseEvent *event)
{
+ QPoint mousePos = event->pos();
+ //mousePos.setY(height() - mousePos.y());
+ m_shared->mouseMoveEvent(event, mousePos);
}
+void DeclarativeBars::wheelEvent(QWheelEvent *event)
+{
+ m_shared->wheelEvent(event);
+}
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3dqml2/declarativebars.h b/src/datavis3dqml2/declarativebars.h
deleted file mode 100644
index 8194cd7d..00000000
--- a/src/datavis3dqml2/declarativebars.h
+++ /dev/null
@@ -1,233 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtDataVis3D module.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** 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 Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef DECLARATIVEBARS_H
-#define DECLARATIVEBARS_H
-
-#include "bars3dshared_p.h"
-#include "qdatavis3dglobal.h"
-#include "qdatavis3namespace.h"
-#include "declarativebars_p.h"
-
-#include <qsgsimpletexturenode.h>
-#include <QQuickItem>
-#include <QObject>
-
-class QOpenGLFramebufferObject;
-class QSGTexture;
-class QQuickWindow;
-
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
-
-class DeclarativeBars : public QQuickItem
-{
- Q_OBJECT
- Q_PROPERTY(SelectionMode selectionMode READ selectionMode WRITE setSelectionMode)
- Q_PROPERTY(LabelTransparency labelTransparency READ labelTransparency WRITE setLabelTransparency)
- Q_PROPERTY(ShadowQuality shadowQuality READ shadow WRITE setShadow)
- Q_PROPERTY(bool grid READ gridEnabled WRITE setGridEnabled)
- Q_PROPERTY(int width READ width WRITE setWidth)
- Q_PROPERTY(int height READ height WRITE setHeight)
- Q_ENUMS(SelectionMode)
- Q_ENUMS(ShadowQuality)
- Q_ENUMS(LabelTransparency)
-
-protected:
- Bars3dShared *m_shared;
- DeclarativeBarsCachedStatePrivate *m_cachedState;
-
-public:
- // Duplicated here to be able to use the same enums
- enum SelectionMode {
- ModeNone = 0,
- ModeBar,
- ModeBarAndRow,
- ModeBarAndColumn,
- ModeBarRowAndColumn,
- ModeZoomRow,
- ModeZoomColumn
- };
-
- enum ShadowQuality {
- ShadowNone = 0,
- ShadowLow = 1,
- ShadowMedium = 3,
- ShadowHigh = 5
- };
-
- enum LabelTransparency {
- TransparencyNone = 0, // Full solid, using colors from theme
- TransparencyFromTheme, // Use colors and transparencies from theme
- TransparencyNoBackground // Draw just text on transparent background
- };
-
-public:
- explicit DeclarativeBars(QQuickItem *parent = 0);
- ~DeclarativeBars();
-
- // Add a row of data. Each new row is added to the front of the sample space, moving previous
- // rows back (if sample space is more than one row deep)
- Q_INVOKABLE void addDataRow(const QVector<GLfloat> &dataRow,
- const QString &labelRow = QString(),
- const QVector<QString> &labelsColumn = QVector<QString>());
- // ownership of dataItems is transferred
- Q_INVOKABLE void addDataRow(const QVector<QDataItem*> &dataRow,
- const QString &labelRow = QString(),
- const QVector<QString> &labelsColumn = QVector<QString>());
- // ownership of dataRow is transferred
- Q_INVOKABLE void addDataRow(QDataRow *dataRow);
-
- // Add complete data set at a time, as a vector of data rows
- Q_INVOKABLE void addDataSet(const QVector< QVector<GLfloat> > &data,
- const QVector<QString> &labelsRow = QVector<QString>(),
- const QVector<QString> &labelsColumn = QVector<QString>());
-
- // ownership of dataItems is transferred
- Q_INVOKABLE void addDataSet(const QVector< QVector<QDataItem*> > &data,
- const QVector<QString> &labelsRow = QVector<QString>(),
- const QVector<QString> &labelsColumn = QVector<QString>());
- // ownership of dataSet is transferred
- Q_INVOKABLE void addDataSet(QDataSet* dataSet);
-
- // bar thickness, spacing between bars, and is spacing relative to thickness or absolute
- // y -component sets the thickness/spacing of z -direction
- // With relative 0.0f means side-to-side, 1.0f = one thickness in between
- Q_INVOKABLE void setBarSpecs(QSizeF thickness = QSizeF(1.0f, 1.0f),
- QSizeF spacing = QSizeF(1.0f, 1.0f),
- bool relative = true);
-
- // bar type; bars (=cubes), pyramids, cones, cylinders, etc.
- Q_INVOKABLE void setBarType(BarStyle style, bool smooth = false);
-
- // override bar type with own mesh
- Q_INVOKABLE void setMeshFileName(const QString &objFileName);
-
- // how many samples per row and column, and names for axes
- Q_INVOKABLE void setupSampleSpace(int samplesRow, int samplesColumn,
- const QString &labelRow = QString(),
- const QString &labelColumn = QString(),
- const QString &labelHeight = QString());
-
- // Select preset camera placement
- Q_INVOKABLE void setCameraPreset(CameraPreset preset);
-
- // Set camera rotation if you don't want to use the presets (in horizontal (-180...180) and
- // vertical (0...90) (or (-90...90) if there are negative values) angles and distance in
- // percentage (10...500))
- Q_INVOKABLE void setCameraPosition(GLfloat horizontal, GLfloat vertical, GLint distance = 100);
-
- // Set theme (bar colors, shaders, window color, background colors, light intensity and text
- // colors are affected)
- Q_INVOKABLE void setTheme(ColorTheme theme);
-
- // Set color if you don't want to use themes. Set uniform to false if you want the (height)
- // color to change from bottom to top
- Q_INVOKABLE void setBarColor(QColor baseColor, QColor heightColor, QColor depthColor,
- bool uniform = true);
-
- // Set tick count and step. Note; tickCount * step should be the maximum possible value of data
- // set. Minimum is the absolute minimum possible value a bar can have. This is especially
- // important to set if values can be negative.
- Q_INVOKABLE void setTickCount(GLint tickCount, GLfloat step, GLfloat minimum = 0.0f);
-
- // TODO: light placement API
-
- // Change selection mode; single bar, bar and row, bar and column, or all
- void setSelectionMode(SelectionMode mode);
- SelectionMode selectionMode();
-
- // Font size adjustment
- void setFontSize(float fontsize);
- float fontSize();
-
- // Set font
- void setFont(const QFont &font);
- QFont font();
-
- // Label transparency adjustment
- void setLabelTransparency(LabelTransparency transparency);
- LabelTransparency labelTransparency();
-
- // Enable or disable background grid
- void setGridEnabled(bool enable);
- bool gridEnabled();
-
- // Enable or disable background mesh
- void setBackgroundEnabled(bool enable);
- bool backgroundEnabled();
-
- // Adjust shadow quality
- void setShadowQuality(ShadowQuality quality);
- ShadowQuality shadowQuality();
-
- // Adjust shadow quality
- void setShadow(DeclarativeBars::ShadowQuality quality);
- DeclarativeBars::ShadowQuality shadow();
-
- protected:
- QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *);
-
-};
-
-// TODO: If we use texture node, our rendering is done into a texture that is then drawn to the
-// qquickwindow -> selection will not work
-class DeclarativeBarsRenderer : public QObject, public QSGSimpleTextureNode
-{
- Q_OBJECT
-
-public:
- DeclarativeBarsRenderer(QQuickWindow *window, Bars3dShared *shared);
- ~DeclarativeBarsRenderer();
-
-public slots:
- void render();
-
-private:
- QOpenGLFramebufferObject *m_fbo;
- QSGTexture *m_texture;
- QQuickWindow *m_window;
- Bars3dShared *m_barsRenderer;
-};
-
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
-QTENTERPRISE_DATAVIS3D_USE_NAMESPACE
-
-#endif
diff --git a/src/datavis3dqml2/declarativebars_p.h b/src/datavis3dqml2/declarativebars_p.h
index 62dcc708..07dc21d4 100644
--- a/src/datavis3dqml2/declarativebars_p.h
+++ b/src/datavis3dqml2/declarativebars_p.h
@@ -1,41 +1,18 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
@@ -43,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the Qt API. It exists purely as an
+// This file is not part of the QtDataVis3D API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -52,45 +29,178 @@
#ifndef DECLARATIVEBARS_P_H
#define DECLARATIVEBARS_P_H
-#include "QtDataVis3D/qdatavis3dglobal.h"
-#include "QtDataVis3D/qdatavis3namespace.h"
-#include <QString>
+#include "datavis3dglobal_p.h"
+#include "bars3dcontroller_p.h"
+#include "declarativebars_p.h"
+#include "qitemmodelbardatamapping.h"
+#include "qvalueaxis.h"
+#include "qcategoryaxis.h"
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
+#include <QAbstractItemModel>
+#include <QQuickItem>
+#include <QObject>
+#include <QQuickWindow>
-class QDataRow;
+QT_DATAVIS3D_BEGIN_NAMESPACE
-class DeclarativeBarsCachedStatePrivate
+class DeclarativeBars : public QQuickItem
{
+ Q_OBJECT
+ Q_PROPERTY(QAbstractItemModel *data READ data WRITE setData)
+ Q_PROPERTY(QItemModelBarDataMapping *mapping READ mapping WRITE setMapping)
+ Q_PROPERTY(QCategoryAxis *axisX READ axisX WRITE setAxisX)
+ Q_PROPERTY(QValueAxis *axisY READ axisY WRITE setAxisY)
+ Q_PROPERTY(QCategoryAxis *axisZ READ axisZ WRITE setAxisZ)
+ Q_PROPERTY(QtDataVis3D::QDataVis::SelectionMode selectionMode READ selectionMode WRITE setSelectionMode)
+ Q_PROPERTY(QtDataVis3D::QDataVis::LabelTransparency labelTransparency READ labelTransparency WRITE setLabelTransparency)
+ Q_PROPERTY(QtDataVis3D::QDataVis::ShadowQuality shadowQuality READ shadowQuality WRITE setShadowQuality)
+ Q_PROPERTY(QtDataVis3D::QDataVis::MeshStyle barType READ barType WRITE setBarType)
+ Q_PROPERTY(QtDataVis3D::QDataVis::CameraPreset cameraPreset READ cameraPreset WRITE setCameraPreset)
+ Q_PROPERTY(QtDataVis3D::QDataVis::ColorTheme theme READ theme WRITE setTheme)
+ Q_PROPERTY(QSizeF barThickness READ barThickness WRITE setBarThickness)
+ Q_PROPERTY(QSizeF barSpacing READ barSpacing WRITE setBarSpacing)
+ Q_PROPERTY(bool barSpacingRelative READ isBarSpacingRelative WRITE setBarSpacingRelative)
+ Q_PROPERTY(bool barSmooth READ barSmooth WRITE setBarSmooth)
+ Q_PROPERTY(QString meshFileName READ meshFileName WRITE setMeshFileName)
+ Q_PROPERTY(QFont font READ font WRITE setFont)
+ Q_PROPERTY(float fontSize READ fontSize WRITE setFontSize)
+ Q_PROPERTY(bool gridVisible READ isGridVisible WRITE setGridVisible)
+ Q_PROPERTY(bool backgroundVisible READ isBackgroundVisible WRITE setBackgroundVisible)
+ Q_PROPERTY(int rows READ rows WRITE setRows)
+ Q_PROPERTY(int columns READ columns WRITE setColumns)
+ Q_ENUMS(QtDataVis3D::QDataVis::SelectionMode)
+ Q_ENUMS(QtDataVis3D::QDataVis::ShadowQuality)
+ Q_ENUMS(QtDataVis3D::QDataVis::LabelTransparency)
+ Q_ENUMS(QtDataVis3D::QDataVis::MeshStyle)
+ Q_ENUMS(QtDataVis3D::QDataVis::CameraPreset)
+ Q_ENUMS(QtDataVis3D::QDataVis::ColorTheme)
+
public:
- explicit DeclarativeBarsCachedStatePrivate();
- ~DeclarativeBarsCachedStatePrivate();
+ explicit DeclarativeBars(QQuickItem *parent = 0);
+ ~DeclarativeBars();
+
+ void classBegin();
+ void componentComplete();
+
+ // how many samples per row and column
+ Q_INVOKABLE void setupSampleSpace(int rowCount, int columnCount);
+
+ // Set color if you don't want to use themes. Set uniform to false if you want the (height)
+ // color to change from bottom to top
+ Q_INVOKABLE void setBarColor(QColor baseColor, QColor heightColor, QColor depthColor,
+ bool uniform = true);
+
+ // Set camera rotation if you don't want to use the presets (in horizontal (-180...180) and
+ // vertical (0...90) (or (-90...90) if there are negative values) angles and distance in
+ // percentage (10...500))
+ Q_INVOKABLE void setCameraPosition(qreal horizontal, qreal vertical, int distance);
+
+ // Add whole data set.
+ void setData(QAbstractItemModel *data);
+ QAbstractItemModel *data();
+
+ QItemModelBarDataMapping *mapping() const;
+ void setMapping(QItemModelBarDataMapping *mapping);
+
+ QCategoryAxis *axisX() const;
+ void setAxisX(QCategoryAxis *axis);
+ QValueAxis *axisY() const;
+ void setAxisY(QValueAxis *axis);
+ QCategoryAxis *axisZ() const;
+ void setAxisZ(QCategoryAxis *axis);
+
+ // Set bar thickness. Y -component sets the thickness of z -direction.
+ void setBarThickness(QSizeF thickness);
+ QSizeF barThickness();
+
+ // Set spacing between bars. Y -component sets the spacing of z -direction.
+ // If spacing is relative, 0.0f means side-to-side and 1.0f = one thickness in between.
+ void setBarSpacing(QSizeF spacing);
+ QSizeF barSpacing();
+
+ // Set bar spacing relative to thickness or absolute
+ void setBarSpacingRelative(bool relative);
+ bool isBarSpacingRelative();
+
+ // Bar type
+ void setBarType(QDataVis::MeshStyle style);
+ QDataVis::MeshStyle barType();
+
+ // Bar smoothing
+ void setBarSmooth(bool smooth);
+ bool barSmooth();
+
+ // override object type with own mesh
+ void setMeshFileName(const QString &objFileName);
+ QString meshFileName();
+
+ // Select preset camera placement
+ void setCameraPreset(QDataVis::CameraPreset preset);
+ QDataVis::CameraPreset cameraPreset();
+
+ // Set theme (object colors, shaders, window color, background colors, light intensity and text
+ // colors are affected)
+ void setTheme(QDataVis::ColorTheme theme);
+ QDataVis::ColorTheme theme();
+
+ // Change selection mode; single bar, bar and row, bar and column, or all
+ void setSelectionMode(QDataVis::SelectionMode mode);
+ QDataVis::SelectionMode selectionMode();
+
+ // Font size adjustment
+ void setFontSize(float fontsize);
+ float fontSize();
+
+ // Set font
+ void setFont(const QFont &font);
+ QFont font();
+
+ // Label transparency adjustment
+ void setLabelTransparency(QDataVis::LabelTransparency transparency);
+ QDataVis::LabelTransparency labelTransparency();
+
+ // Enable or disable background grid
+ void setGridVisible(bool visible);
+ bool isGridVisible();
+
+ // Enable or disable background mesh
+ void setBackgroundVisible(bool visible);
+ bool isBackgroundVisible();
+
+ // Adjust shadow quality
+ void setShadowQuality(QDataVis::ShadowQuality quality);
+ QDataVis::ShadowQuality shadowQuality();
+
+ int rows() const;
+ void setRows(int rows);
- bool m_isSampleSpaceSet;
- int m_cachedState;
- int m_samplesRow;
- int m_samplesColumn;
- QString m_labelRow;
- QString m_labelColumn;
- QString m_labelHeight;
+ int columns() const;
+ void setColumns(int columns);
- QDataRow *m_dataRow;
+public slots:
+ // Used to detect when shadow quality changes autonomously due to e.g. resizing.
+ void handleShadowQualityUpdate(QDataVis::ShadowQuality quality);
- bool m_isSelectionModeSet;
- SelectionMode m_selectionMode;
+signals:
+ // Signals shadow quality changes.
+ void shadowQualityChanged(QDataVis::ShadowQuality quality);
- bool m_isLabelTransparencySet;
- LabelTransparency m_labelTransparency;
+protected:
+ Bars3dController *m_shared;
- bool m_isShadowQualitySet;
- ShadowQuality m_shadowQuality;
+ QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *);
+ void mousePressEvent(QMouseEvent *event);
+ void mouseReleaseEvent(QMouseEvent *event);
+ void mouseMoveEvent(QMouseEvent *event);
+ void wheelEvent(QWheelEvent *event);
- bool m_isGridSet;
- bool m_isGridEnabled;
+private:
+ QSize m_initialisedSize;
+ QDataVis::CameraPreset m_cameraPreset;
+ QDataVis::ColorTheme m_theme;
};
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
-QTENTERPRISE_DATAVIS3D_USE_NAMESPACE
+QT_DATAVIS3D_END_NAMESPACE
-#endif // DECLARATIVEBARS_P_H
+#endif
diff --git a/src/datavis3dqml2/declarativebarsrenderer.cpp b/src/datavis3dqml2/declarativebarsrenderer.cpp
new file mode 100644
index 00000000..1ecd4003
--- /dev/null
+++ b/src/datavis3dqml2/declarativebarsrenderer.cpp
@@ -0,0 +1,86 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "declarativebarsrenderer_p.h"
+
+#include <QtQuick/QQuickWindow>
+#include <QtGui/QOpenGLFramebufferObject>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+DeclarativeBarsRenderer::DeclarativeBarsRenderer(QQuickWindow *window, Bars3dController *renderer)
+ : m_fbo(0),
+ m_texture(0),
+ m_window(window),
+ m_barsRenderer(renderer)
+{
+ connect(m_window, SIGNAL(beforeSynchronizing()), this, SLOT(synchDataToRenderer()), Qt::DirectConnection);
+ connect(m_window, SIGNAL(beforeRendering()), this, SLOT(renderFBO()), Qt::DirectConnection);
+}
+
+DeclarativeBarsRenderer::~DeclarativeBarsRenderer()
+{
+ delete m_texture;
+ delete m_fbo;
+}
+
+void DeclarativeBarsRenderer::synchDataToRenderer()
+{
+ m_barsRenderer->initializeOpenGL();
+ m_barsRenderer->synchDataToRenderer();
+}
+
+void DeclarativeBarsRenderer::renderFBO()
+{
+ QSize size = rect().size().toSize();
+
+ // Create FBO
+ if (!m_fbo) {
+ QOpenGLFramebufferObjectFormat format;
+ format.setAttachment(QOpenGLFramebufferObject::Depth);
+ m_fbo = new QOpenGLFramebufferObject(size, format);
+ m_texture = m_window->createTextureFromId(m_fbo->texture(), size);
+
+ setTexture(m_texture);
+
+ // Flip texture
+ // TODO: Can be gotten rid of once support for texture flipping becomes available (in Qt5.2)
+ QSize ts = m_texture->textureSize();
+ QRectF sourceRect(0, 0, ts.width(), ts.height());
+ float tmp = sourceRect.top();
+ sourceRect.setTop(sourceRect.bottom());
+ sourceRect.setBottom(tmp);
+ QSGGeometry *geometry = this->geometry();
+ QSGGeometry::updateTexturedRectGeometry(geometry, rect(),
+ m_texture->convertToNormalizedSourceRect(sourceRect));
+ markDirty(DirtyMaterial);
+ //qDebug() << "create node" << m_fbo->handle() << m_texture->textureId() << m_fbo->size();
+ }
+
+ // Call the shared rendering function
+ m_fbo->bind();
+
+ m_barsRenderer->render(m_fbo->handle());
+
+ m_fbo->release();
+
+ // New view is in the FBO, request repaint of scene graph
+ m_window->update();
+}
+
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3dqml2/declarativebarsrenderer_p.h b/src/datavis3dqml2/declarativebarsrenderer_p.h
new file mode 100644
index 00000000..1b40d3df
--- /dev/null
+++ b/src/datavis3dqml2/declarativebarsrenderer_p.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef DECLARATIVEBARSRENDERER_H
+#define DECLARATIVEBARSRENDERER_H
+
+#include "datavis3dglobal_p.h"
+#include "bars3dcontroller_p.h"
+#include <qsgsimpletexturenode.h>
+
+class QOpenGLFramebufferObject;
+class QSGTexture;
+class QQuickWindow;
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class DeclarativeBarsRenderer : public QObject, public QSGSimpleTextureNode
+{
+ Q_OBJECT
+
+public:
+ DeclarativeBarsRenderer(QQuickWindow *window, Bars3dController *shared);
+ ~DeclarativeBarsRenderer();
+
+public slots:
+ // Used to synch up data model from controller to renderer while main thread is locked
+ void synchDataToRenderer();
+ // Renders view to FBO before render cycle starts.
+ void renderFBO();
+
+private:
+ QOpenGLFramebufferObject *m_fbo;
+ QSGTexture *m_texture;
+ QQuickWindow *m_window;
+ Bars3dController *m_barsRenderer;
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3dqml2/declarativemaps.cpp b/src/datavis3dqml2/declarativemaps.cpp
index a5bb2318..7be239f2 100644
--- a/src/datavis3dqml2/declarativemaps.cpp
+++ b/src/datavis3dqml2/declarativemaps.cpp
@@ -1,86 +1,229 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
**
** This file is part of the QtDataVis3D module.
**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
+** a written agreement between you and Digia.
**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
**
****************************************************************************/
-#include "declarativemaps.h"
-
-#include <QDebug>
+#include "declarativemaps_p.h"
+#include "declarativemapsrenderer_p.h"
+#include "qitemmodelmapdataproxy.h"
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVIS3D_BEGIN_NAMESPACE
-DeclarativeMaps::DeclarativeMaps()
+DeclarativeMaps::DeclarativeMaps(QQuickItem *parent)
+ : QQuickItem(parent),
+ m_shared(0),
+ m_initializedSize(0, 0)
{
+ setFlags(QQuickItem::ItemHasContents);
+ setAcceptedMouseButtons(Qt::AllButtons);
+
+ // TODO: These seem to have no effect; find a way to activate anti-aliasing
+ setAntialiasing(true);
+ setSmooth(true);
}
DeclarativeMaps::~DeclarativeMaps()
{
+ delete m_shared;
+}
+
+void DeclarativeMaps::classBegin()
+{
+ qDebug() << "classBegin";
+}
+
+void DeclarativeMaps::componentComplete()
+{
+ qDebug() << "componentComplete";
+}
+
+QSGNode *DeclarativeMaps::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
+{
+ if (!m_shared) {
+ m_shared = new Maps3DController(boundingRect().toRect());
+ m_shared->setDataProxy(new QItemModelMapDataProxy);
+ m_shared->initializeOpenGL();
+ }
+
+ // If old node exists and has right size, reuse it.
+ if (oldNode && m_initializedSize == boundingRect().size().toSize()) {
+ // Update bounding rectangle (that has same size as before).
+ static_cast<DeclarativeMapsRenderer *>( oldNode )->setRect(boundingRect());
+ return oldNode;
+ }
+
+ // Create a new render node when size changes or if there is no node yet
+ m_initializedSize = boundingRect().size().toSize();
+
+ // Delete old node
+ if (oldNode)
+ delete oldNode;
+
+ // Create a new one and set it's bounding rectangle
+ DeclarativeMapsRenderer *node = new DeclarativeMapsRenderer(window(), m_shared);
+ node->setRect(boundingRect());
+ m_shared->setBoundingRect(boundingRect().toRect());
+ return node;
+}
+
+void DeclarativeMaps::setData(QAbstractItemModel *data)
+{
+ static_cast<QItemModelMapDataProxy *>(m_shared->dataProxy())->setItemModel(data);
+}
+
+QAbstractItemModel *DeclarativeMaps::data()
+{
+ return static_cast<QItemModelMapDataProxy *>(m_shared->dataProxy())->itemModel();
+}
+
+void DeclarativeMaps::setBarSpecs(const QVector3D &thickness,
+ Q3DMaps::AdjustmentDirection direction)
+{
+ m_shared->setBarSpecs(thickness, direction);
+}
+
+void DeclarativeMaps::setBarType(QDataVis::MeshStyle style, bool smooth)
+{
+ m_shared->setBarType(style, smooth);
+}
+
+void DeclarativeMaps::setMeshFileName(const QString &objFileName)
+{
+ m_shared->setMeshFileName(objFileName);
+}
+
+void DeclarativeMaps::setCameraPreset(QDataVis::CameraPreset preset)
+{
+ m_shared->setCameraPreset(preset);
+}
+
+void DeclarativeMaps::setCameraPosition(GLfloat horizontal, GLfloat vertical, GLint distance)
+{
+ m_shared->setCameraPosition(horizontal, vertical, distance);
+}
+
+void DeclarativeMaps::setTheme(QDataVis::ColorTheme theme)
+{
+ m_shared->setTheme(theme);
+}
+
+void DeclarativeMaps::setBarColor(QColor baseColor, QColor heightColor, bool uniform)
+{
+ m_shared->setBarColor(baseColor, heightColor, uniform);
+}
+
+void DeclarativeMaps::setAreaSpecs(const QRect &areaRect, const QImage &image)
+{
+ m_shared->setAreaSpecs(areaRect, image);
+}
+
+void DeclarativeMaps::setImage(const QImage &image)
+{
+ m_shared->setImage(image);
+}
+
+void DeclarativeMaps::setImage(const QString &imageUrl)
+{
+ m_shared->setImage(QImage(imageUrl));
+}
+
+void DeclarativeMaps::setSelectionMode(QDataVis::SelectionMode mode)
+{
+ m_shared->setSelectionMode(mode);
+}
+
+QDataVis::SelectionMode DeclarativeMaps::selectionMode()
+{
+ return m_shared->selectionMode();
+}
+
+void DeclarativeMaps::setFontSize(float fontsize)
+{
+ m_shared->setFontSize(fontsize);
+}
+
+float DeclarativeMaps::fontSize()
+{
+ return m_shared->fontSize();
+}
+
+void DeclarativeMaps::setFont(const QFont &font)
+{
+ m_shared->setFont(font);
+}
+
+QFont DeclarativeMaps::font()
+{
+ return m_shared->font();
+}
+
+void DeclarativeMaps::setLabelTransparency(QDataVis::LabelTransparency transparency)
+{
+ m_shared->setLabelTransparency(transparency);
+}
+
+QDataVis::LabelTransparency DeclarativeMaps::labelTransparency()
+{
+ return m_shared->labelTransparency();
+}
+
+void DeclarativeMaps::setShadowQuality(QDataVis::ShadowQuality quality)
+{
+ m_shared->setShadowQuality(quality);
+}
+
+QDataVis::ShadowQuality DeclarativeMaps::shadowQuality()
+{
+ return m_shared->shadowQuality();
}
-void DeclarativeMaps::setSelMode(DeclarativeMaps::SelectionMode mode)
+QItemModelMapDataMapping *DeclarativeMaps::mapping() const
{
- setSelectionMode(QtDataVis3D::SelectionMode(mode));
+ return static_cast<QItemModelMapDataProxy *>(m_shared->dataProxy())->mapping();
}
-DeclarativeMaps::SelectionMode DeclarativeMaps::selMode()
+void DeclarativeMaps::setMapping(QItemModelMapDataMapping *mapping)
{
- return DeclarativeMaps::SelectionMode(selectionMode());
+ static_cast<QItemModelMapDataProxy *>(m_shared->dataProxy())->setMapping(mapping);
}
-void DeclarativeMaps::setTransparency(DeclarativeMaps::LabelTransparency transparency)
+void DeclarativeMaps::mousePressEvent(QMouseEvent *event)
{
- setLabelTransparency(QtDataVis3D::LabelTransparency(transparency));
+ QPoint mousePos = event->pos();
+ //mousePos.setY(height() - mousePos.y());
+ m_shared->mousePressEvent(event, mousePos);
}
-DeclarativeMaps::LabelTransparency DeclarativeMaps::transparency()
+void DeclarativeMaps::mouseReleaseEvent(QMouseEvent *event)
{
- return DeclarativeMaps::LabelTransparency(labelTransparency());
+ QPoint mousePos = event->pos();
+ //mousePos.setY(height() - mousePos.y());
+ m_shared->mouseReleaseEvent(event, mousePos);
}
-void DeclarativeMaps::setShadow(DeclarativeMaps::ShadowQuality quality)
+void DeclarativeMaps::mouseMoveEvent(QMouseEvent *event)
{
- setShadowQuality(QtDataVis3D::ShadowQuality(quality));
+ QPoint mousePos = event->pos();
+ //mousePos.setY(height() - mousePos.y());
+ m_shared->mouseMoveEvent(event, mousePos);
}
-DeclarativeMaps::ShadowQuality DeclarativeMaps::shadow()
+void DeclarativeMaps::wheelEvent(QWheelEvent *event)
{
- return DeclarativeMaps::ShadowQuality(shadowQuality());
+ m_shared->wheelEvent(event);
}
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3dqml2/declarativemaps.h b/src/datavis3dqml2/declarativemaps.h
deleted file mode 100644
index aef00c76..00000000
--- a/src/datavis3dqml2/declarativemaps.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtDataVis3D module.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** 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 Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef DECLARATIVEMAPS_H
-#define DECLARATIVEMAPS_H
-
-#include "QtDataVis3D/qdatavis3dglobal.h"
-#include "QtDataVis3D/qdatavis3namespace.h"
-#include "q3dmaps.h"
-
-QTENTERPRISE_DATAVIS3D_BEGIN_NAMESPACE
-
-class DeclarativeMaps : public Q3DMaps
-{
- Q_OBJECT
- Q_PROPERTY(SelectionMode selectionMode READ selMode WRITE setSelMode)
- Q_PROPERTY(LabelTransparency labelTransparency READ transparency WRITE setTransparency)
- Q_PROPERTY(ShadowQuality shadowQuality READ shadow WRITE setShadow)
- Q_ENUMS(SelectionMode)
- Q_ENUMS(ShadowQuality)
- Q_ENUMS(LabelTransparency)
-
-public:
- // Duplicated here to be able to use the same enums
- enum SelectionMode {
- ModeNone = 0,
- ModeBar,
- ModeBarAndRow,
- ModeBarAndColumn,
- ModeBarRowAndColumn,
- ModeZoomRow,
- ModeZoomColumn
- };
-
- enum ShadowQuality {
- ShadowNone = 0,
- ShadowLow = 1,
- ShadowMedium = 3,
- ShadowHigh = 5
- };
-
- enum LabelTransparency {
- TransparencyNone = 0, // Full solid, using colors from theme
- TransparencyFromTheme, // Use colors and transparencies from theme
- TransparencyNoBackground // Draw just text on transparent background
- };
-
-public:
- explicit DeclarativeMaps();
- ~DeclarativeMaps();
-
- // Change selection mode; single bar, bar and row, bar and column, or all
- void setSelMode(DeclarativeMaps::SelectionMode mode);
- DeclarativeMaps::SelectionMode selMode();
-
- // Label transparency adjustment
- void setTransparency(DeclarativeMaps::LabelTransparency transparency);
- DeclarativeMaps::LabelTransparency transparency();
-
- // Adjust shadow quality
- void setShadow(DeclarativeMaps::ShadowQuality quality);
- DeclarativeMaps::ShadowQuality shadow();
-};
-
-QTENTERPRISE_DATAVIS3D_END_NAMESPACE
-
-#endif
diff --git a/src/datavis3dqml2/declarativemaps_p.h b/src/datavis3dqml2/declarativemaps_p.h
new file mode 100644
index 00000000..ba2da0b3
--- /dev/null
+++ b/src/datavis3dqml2/declarativemaps_p.h
@@ -0,0 +1,139 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+//
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef DECLARATIVEMAPS_P_H
+#define DECLARATIVEMAPS_P_H
+
+#include "datavis3dglobal_p.h"
+#include "maps3dcontroller_p.h"
+#include "declarativemaps_p.h"
+#include "qitemmodelmapdatamapping.h"
+
+#include <QAbstractItemModel>
+#include <QQuickItem>
+#include <QObject>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class DeclarativeMaps : public QQuickItem
+{
+ Q_OBJECT
+ Q_PROPERTY(QAbstractItemModel *data READ data WRITE setData)
+ Q_PROPERTY(QtDataVis3D::QDataVis::SelectionMode selectionMode READ selectionMode WRITE setSelectionMode)
+ Q_PROPERTY(QtDataVis3D::QDataVis::LabelTransparency labelTransparency READ labelTransparency WRITE setLabelTransparency)
+ Q_PROPERTY(QtDataVis3D::QDataVis::ShadowQuality shadowQuality READ shadowQuality WRITE setShadowQuality)
+ Q_PROPERTY(QFont font READ font WRITE setFont)
+ Q_PROPERTY(float fontSize READ fontSize WRITE setFontSize)
+ Q_PROPERTY(QItemModelMapDataMapping *mapping READ mapping WRITE setMapping)
+ Q_ENUMS(QtDataVis3D::QDataVis::SelectionMode)
+ Q_ENUMS(QtDataVis3D::QDataVis::ShadowQuality)
+ Q_ENUMS(QtDataVis3D::QDataVis::LabelTransparency)
+
+public:
+ explicit DeclarativeMaps(QQuickItem *parent = 0);
+ ~DeclarativeMaps();
+
+ void classBegin();
+ void componentComplete();
+
+ void setData(QAbstractItemModel *data);
+ QAbstractItemModel *data();
+
+ // bar specifications; base thickness in x, y and z, enum to indicate which direction is increased with value
+ // TODO: Start using thickness also in adjustment direction; use it as a relative value.
+ // For example, in AdjustAll mode setting thickness to (0.1f, 1.0f, 0.5f) would apply value to
+ // x at 10%, y at 100% and z at 50%. If a dimension is not included, given thickness states its absolute value.
+ Q_INVOKABLE void setBarSpecs(const QVector3D &thickness = QVector3D(1.0f, 1.0f, 1.0f),
+ Q3DMaps::AdjustmentDirection direction = Q3DMaps::AdjustHeight);
+
+ // bar type; bars (=cubes), pyramids, cones, cylinders, balls, etc.
+ Q_INVOKABLE void setBarType(QDataVis::MeshStyle style, bool smooth = false);
+
+ // override bar type with own mesh
+ Q_INVOKABLE void setMeshFileName(const QString &objFileName);
+
+ // Select preset camera placement
+ Q_INVOKABLE void setCameraPreset(QDataVis::CameraPreset preset);
+
+ // Set camera rotation if you don't want to use the presets (in horizontal (180...180) and
+ // vertical (0...90) angles and distance in percentage (10...500))
+ Q_INVOKABLE void setCameraPosition(GLfloat horizontal, GLfloat vertical, GLint distance = 100);
+
+ // Set theme (bar colors, shaders, window color, background colors, light intensity and text colors are affected)
+ Q_INVOKABLE void setTheme(QDataVis::ColorTheme theme);
+
+ // Set color if you don't want to use themes. Set uniform to false if you want the (height) color to change from bottom to top
+ Q_INVOKABLE void setBarColor(QColor baseColor, QColor heightColor, bool uniform = true);
+
+ // Set area specs
+ Q_INVOKABLE void setAreaSpecs(const QRect &areaRect, const QImage &image);
+
+ // Set area image
+ Q_INVOKABLE void setImage(const QImage &image);
+ Q_INVOKABLE void setImage(const QString &imageUrl);
+
+ // Change selection mode; single bar, bar and row, bar and column, or all
+ void setSelectionMode(QDataVis::SelectionMode mode);
+ QDataVis::SelectionMode selectionMode();
+
+ // Font size adjustment
+ void setFontSize(float fontsize);
+ float fontSize();
+
+ // Set font
+ void setFont(const QFont &font);
+ QFont font();
+
+ // Label transparency adjustment
+ void setLabelTransparency(QDataVis::LabelTransparency transparency);
+ QDataVis::LabelTransparency labelTransparency();
+
+ // Adjust shadow quality
+ void setShadowQuality(QDataVis::ShadowQuality quality);
+ QDataVis::ShadowQuality shadowQuality();
+
+ QItemModelMapDataMapping *mapping() const;
+ void setMapping(QItemModelMapDataMapping *mapping);
+
+protected:
+ Maps3DController *m_shared;
+
+ QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *);
+
+ void mousePressEvent(QMouseEvent *event);
+ void mouseReleaseEvent(QMouseEvent *event);
+ void mouseMoveEvent(QMouseEvent *event);
+ void wheelEvent(QWheelEvent *event);
+
+private:
+ QSize m_initializedSize;
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3dqml2/declarativemapsrenderer.cpp b/src/datavis3dqml2/declarativemapsrenderer.cpp
new file mode 100644
index 00000000..6e8dc2db
--- /dev/null
+++ b/src/datavis3dqml2/declarativemapsrenderer.cpp
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "declarativemapsrenderer_p.h"
+
+#include <QtQuick/QQuickWindow>
+#include <QtGui/QOpenGLFramebufferObject>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+DeclarativeMapsRenderer::DeclarativeMapsRenderer(QQuickWindow *window, Maps3DController *renderer)
+ : m_fbo(0),
+ m_texture(0),
+ m_window(window),
+ m_mapsRenderer(renderer)
+{
+ connect(m_window, SIGNAL(beforeRendering()), this, SLOT(render()), Qt::DirectConnection);
+}
+
+DeclarativeMapsRenderer::~DeclarativeMapsRenderer()
+{
+ delete m_texture;
+ delete m_fbo;
+}
+
+void DeclarativeMapsRenderer::render()
+{
+ QSize size = rect().size().toSize();
+
+ // Create FBO
+ if (!m_fbo) {
+ QOpenGLFramebufferObjectFormat format;
+ format.setAttachment(QOpenGLFramebufferObject::Depth);
+ m_fbo = new QOpenGLFramebufferObject(size, format);
+ m_texture = m_window->createTextureFromId(m_fbo->texture(), size);
+
+ setTexture(m_texture);
+
+ // Flip texture
+ // TODO: Can be gotten rid of once support for texture flipping becomes available (in Qt5.2)
+ QSize ts = m_texture->textureSize();
+ QRectF sourceRect(0, 0, ts.width(), ts.height());
+ float tmp = sourceRect.top();
+ sourceRect.setTop(sourceRect.bottom());
+ sourceRect.setBottom(tmp);
+ QSGGeometry *geometry = this->geometry();
+ QSGGeometry::updateTexturedRectGeometry(geometry, rect(),
+ m_texture->convertToNormalizedSourceRect(sourceRect));
+ markDirty(DirtyMaterial);
+ //qDebug() << "create node" << m_fbo->handle() << m_texture->textureId() << m_fbo->size();
+ }
+
+ // Call the shared rendering function
+ m_fbo->bind();
+
+ m_mapsRenderer->render(m_fbo->handle());
+
+ m_fbo->release();
+
+ // New view is in the FBO, request repaint of scene graph
+ m_window->update();
+}
+
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3dqml2/declarativemapsrenderer_p.h b/src/datavis3dqml2/declarativemapsrenderer_p.h
new file mode 100644
index 00000000..755764c9
--- /dev/null
+++ b/src/datavis3dqml2/declarativemapsrenderer_p.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef DECLARATIVEMAPSRENDERER_P_H
+#define DECLARATIVEMAPSRENDERER_P_H
+
+#include "datavis3dglobal_p.h"
+#include "maps3dcontroller_p.h"
+#include <qsgsimpletexturenode.h>
+
+class QOpenGLFramebufferObject;
+class QSGTexture;
+class QQuickWindow;
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class DeclarativeMapsRenderer : public QObject, public QSGSimpleTextureNode
+{
+ Q_OBJECT
+
+public:
+ DeclarativeMapsRenderer(QQuickWindow *window, Maps3DController *shared);
+ ~DeclarativeMapsRenderer();
+
+public slots:
+ void render();
+
+private:
+ QOpenGLFramebufferObject *m_fbo;
+ QSGTexture *m_texture;
+ QQuickWindow *m_window;
+ Maps3DController *m_mapsRenderer;
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3dqml2/declarativescatter.cpp b/src/datavis3dqml2/declarativescatter.cpp
new file mode 100644
index 00000000..90daf0e3
--- /dev/null
+++ b/src/datavis3dqml2/declarativescatter.cpp
@@ -0,0 +1,328 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "declarativescatter_p.h"
+#include "declarativescatterrenderer_p.h"
+#include "qitemmodelscatterdataproxy.h"
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+const QString smoothString(QStringLiteral("Smooth"));
+
+DeclarativeScatter::DeclarativeScatter(QQuickItem *parent)
+ : QQuickItem(parent),
+ m_shared(0),
+ m_initialisedSize(0, 0),
+ m_cameraPreset(QDataVis::NoPreset),
+ m_theme(QDataVis::ThemeDefault)
+{
+ setFlags(QQuickItem::ItemHasContents);
+ setAcceptedMouseButtons(Qt::AllButtons);
+
+ // TODO: These seem to have no effect; find a way to activate anti-aliasing
+ setAntialiasing(true);
+ setSmooth(true);
+
+ // Create the shared component on the main GUI thread.
+ m_shared = new Scatter3DController(boundingRect().toRect());
+ QObject::connect(m_shared, &Scatter3DController::shadowQualityChanged, this,
+ &DeclarativeScatter::handleShadowQualityUpdate);
+
+ m_shared->setDataProxy(new QItemModelScatterDataProxy);
+}
+
+DeclarativeScatter::~DeclarativeScatter()
+{
+ delete m_shared;
+}
+
+void DeclarativeScatter::handleShadowQualityUpdate(QDataVis::ShadowQuality quality)
+{
+ emit shadowQualityChanged(quality);
+}
+
+void DeclarativeScatter::classBegin()
+{
+ qDebug() << "classBegin";
+}
+
+void DeclarativeScatter::componentComplete()
+{
+ qDebug() << "componentComplete";
+}
+
+QSGNode *DeclarativeScatter::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
+{
+ // If old node exists and has right size, reuse it.
+ if (oldNode && m_initialisedSize == boundingRect().size().toSize()) {
+ // Update bounding rectangle (that has same size as before).
+ static_cast<DeclarativeScatterRenderer *>( oldNode )->setRect(boundingRect());
+ return oldNode;
+ }
+
+ // Create a new render node when size changes or if there is no node yet
+ m_initialisedSize = boundingRect().size().toSize();
+
+ // Delete old node
+ if (oldNode)
+ delete oldNode;
+
+ // Create a new one and set it's bounding rectangle
+ DeclarativeScatterRenderer *node = new DeclarativeScatterRenderer(window(), m_shared);
+ node->setRect(boundingRect());
+ m_shared->setBoundingRect(boundingRect().toRect());
+ return node;
+}
+
+void DeclarativeScatter::setCameraPosition(qreal horizontal, qreal vertical, int distance)
+{
+ m_shared->setCameraPosition(GLfloat(horizontal), GLfloat(vertical), GLint(distance));
+}
+
+void DeclarativeScatter::setObjectColor(QColor baseColor, QColor heightColor, QColor depthColor,
+ bool uniform)
+{
+ m_shared->setObjectColor(baseColor, heightColor, depthColor, uniform);
+}
+
+void DeclarativeScatter::setData(QAbstractItemModel *data)
+{
+ static_cast<QItemModelScatterDataProxy *>(m_shared->dataProxy())->setItemModel(data);
+}
+
+QAbstractItemModel *DeclarativeScatter::data()
+{
+ return static_cast<QItemModelScatterDataProxy *>(m_shared->dataProxy())->itemModel();
+}
+
+void DeclarativeScatter::setMapping(QItemModelScatterDataMapping *mapping)
+{
+ static_cast<QItemModelScatterDataProxy *>(m_shared->dataProxy())->setMapping(mapping);
+}
+
+QItemModelScatterDataMapping *DeclarativeScatter::mapping() const
+{
+ return static_cast<QItemModelScatterDataProxy *>(m_shared->dataProxy())->mapping();
+}
+
+QValueAxis *DeclarativeScatter::axisX() const
+{
+ return static_cast<QValueAxis *>(m_shared->axisX());
+}
+
+void DeclarativeScatter::setAxisX(QValueAxis *axis)
+{
+ m_shared->setAxisX(axis);
+}
+
+QValueAxis *DeclarativeScatter::axisY() const
+{
+ return static_cast<QValueAxis *>(m_shared->axisY());
+}
+
+void DeclarativeScatter::setAxisY(QValueAxis *axis)
+{
+ m_shared->setAxisY(axis);
+}
+
+QValueAxis *DeclarativeScatter::axisZ() const
+{
+ return static_cast<QValueAxis *>(m_shared->axisZ());
+}
+
+void DeclarativeScatter::setAxisZ(QValueAxis *axis)
+{
+ m_shared->setAxisZ(axis);
+}
+
+void DeclarativeScatter::setObjectType(QDataVis::MeshStyle style)
+{
+ QString objFile = m_shared->meshFileName();
+ bool smooth = objFile.endsWith(smoothString);
+ m_shared->setObjectType(style, smooth);
+}
+
+QDataVis::MeshStyle DeclarativeScatter::objectType()
+{
+ QString objFile = m_shared->meshFileName();
+ if (objFile.contains("/sphere"))
+ return QDataVis::Spheres;
+ else
+ return QDataVis::Dots;
+}
+
+void DeclarativeScatter::setObjectSmooth(bool smooth)
+{
+ QString objFile = m_shared->meshFileName();
+ if (objFile.endsWith(smoothString)) {
+ if (smooth)
+ return; // Already smooth; do nothing
+ else // Rip Smooth off the end
+ objFile.resize(objFile.indexOf(smoothString));
+ } else {
+ if (!smooth) // Already flat; do nothing
+ return;
+ else // Append Smooth to the end
+ objFile.append(smoothString);
+ }
+ m_shared->setMeshFileName(objFile);
+}
+
+bool DeclarativeScatter::objectSmooth()
+{
+ QString objFile = m_shared->meshFileName();
+ return objFile.endsWith(smoothString);
+}
+
+void DeclarativeScatter::setMeshFileName(const QString &objFileName)
+{
+ m_shared->setMeshFileName(objFileName);
+}
+
+QString DeclarativeScatter::meshFileName()
+{
+ return m_shared->meshFileName();
+}
+
+void DeclarativeScatter::setCameraPreset(QDataVis::CameraPreset preset)
+{
+ // TODO: Implement correctly once "improved camera api" (QTRD-2122) is implemented
+ // We need to save this locally, as there are no getters for it in controller
+ m_cameraPreset = preset;
+ m_shared->setCameraPreset(preset);
+}
+
+QDataVis::CameraPreset DeclarativeScatter::cameraPreset()
+{
+ return m_cameraPreset;
+}
+
+void DeclarativeScatter::setTheme(QDataVis::ColorTheme theme)
+{
+ // TODO: Implement correctly once "user-modifiable themes" (QTRD-2120) is implemented
+ // We need to save this locally, as there are no getters for it in controller
+ m_theme = theme;
+ m_shared->setColorTheme(theme);
+
+ // TODO: Investigate why the beforeSynchronizing() signal requires update and is not sent automatically when this value changes,
+ // but is sent wen e.g. enable/disable background changes.
+ update();
+}
+
+QDataVis::ColorTheme DeclarativeScatter::theme()
+{
+ return m_theme;
+}
+
+void DeclarativeScatter::setFontSize(float fontsize)
+{
+ m_shared->setFontSize(fontsize);
+}
+
+float DeclarativeScatter::fontSize()
+{
+ return m_shared->fontSize();
+}
+
+void DeclarativeScatter::setFont(const QFont &font)
+{
+ m_shared->setFont(font);
+}
+
+QFont DeclarativeScatter::font()
+{
+ return m_shared->font();
+}
+
+void DeclarativeScatter::setLabelTransparency(QDataVis::LabelTransparency transparency)
+{
+ m_shared->setLabelTransparency(transparency);
+}
+
+QDataVis::LabelTransparency DeclarativeScatter::labelTransparency()
+{
+ return m_shared->labelTransparency();
+}
+
+void DeclarativeScatter::setGridVisible(bool visible)
+{
+ m_shared->setGridEnabled(visible);
+}
+
+bool DeclarativeScatter::isGridVisible()
+{
+ return m_shared->gridEnabled();
+}
+
+void DeclarativeScatter::setBackgroundVisible(bool visible)
+{
+ m_shared->setBackgroundEnabled(visible);
+}
+
+bool DeclarativeScatter::isBackgroundVisible()
+{
+ return m_shared->backgroundEnabled();
+}
+
+void DeclarativeScatter::setSelectionMode(QDataVis::SelectionMode mode)
+{
+ m_shared->setSelectionMode(mode);
+}
+
+QDataVis::SelectionMode DeclarativeScatter::selectionMode()
+{
+ return m_shared->selectionMode();
+}
+
+void DeclarativeScatter::setShadowQuality(QDataVis::ShadowQuality quality)
+{
+ m_shared->setShadowQuality(quality);
+}
+
+QDataVis::ShadowQuality DeclarativeScatter::shadowQuality()
+{
+ return m_shared->shadowQuality();
+}
+
+void DeclarativeScatter::mousePressEvent(QMouseEvent *event)
+{
+ QPoint mousePos = event->pos();
+ //mousePos.setY(height() - mousePos.y());
+ m_shared->mousePressEvent(event, mousePos);
+}
+
+void DeclarativeScatter::mouseReleaseEvent(QMouseEvent *event)
+{
+ QPoint mousePos = event->pos();
+ //mousePos.setY(height() - mousePos.y());
+ m_shared->mouseReleaseEvent(event, mousePos);
+}
+
+void DeclarativeScatter::mouseMoveEvent(QMouseEvent *event)
+{
+ QPoint mousePos = event->pos();
+ //mousePos.setY(height() - mousePos.y());
+ m_shared->mouseMoveEvent(event, mousePos);
+}
+
+void DeclarativeScatter::wheelEvent(QWheelEvent *event)
+{
+ m_shared->wheelEvent(event);
+}
+
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3dqml2/declarativescatter_p.h b/src/datavis3dqml2/declarativescatter_p.h
new file mode 100644
index 00000000..dce5c021
--- /dev/null
+++ b/src/datavis3dqml2/declarativescatter_p.h
@@ -0,0 +1,175 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef DECLARATIVESCATTER_P_H
+#define DECLARATIVESCATTER_P_H
+
+#include "datavis3dglobal_p.h"
+#include "scatter3dcontroller_p.h"
+#include "declarativescatter_p.h"
+#include "qitemmodelscatterdatamapping.h"
+#include "qvalueaxis.h"
+
+#include <QAbstractItemModel>
+#include <QQuickItem>
+#include <QObject>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class DeclarativeScatter : public QQuickItem
+{
+ Q_OBJECT
+ Q_PROPERTY(QAbstractItemModel *data READ data WRITE setData)
+ Q_PROPERTY(QItemModelScatterDataMapping *mapping READ mapping WRITE setMapping)
+ Q_PROPERTY(QValueAxis *axisX READ axisX WRITE setAxisX)
+ Q_PROPERTY(QValueAxis *axisY READ axisY WRITE setAxisY)
+ Q_PROPERTY(QValueAxis *axisZ READ axisZ WRITE setAxisZ)
+ Q_PROPERTY(QtDataVis3D::QDataVis::SelectionMode selectionMode READ selectionMode WRITE setSelectionMode)
+ Q_PROPERTY(QtDataVis3D::QDataVis::LabelTransparency labelTransparency READ labelTransparency WRITE setLabelTransparency)
+ Q_PROPERTY(QtDataVis3D::QDataVis::ShadowQuality shadowQuality READ shadowQuality WRITE setShadowQuality)
+ Q_PROPERTY(QtDataVis3D::QDataVis::MeshStyle objectType READ objectType WRITE setObjectType)
+ Q_PROPERTY(QtDataVis3D::QDataVis::CameraPreset cameraPreset READ cameraPreset WRITE setCameraPreset)
+ Q_PROPERTY(QtDataVis3D::QDataVis::ColorTheme theme READ theme WRITE setTheme)
+ Q_PROPERTY(bool objectSmooth READ objectSmooth WRITE setObjectSmooth)
+ Q_PROPERTY(QString meshFileName READ meshFileName WRITE setMeshFileName)
+ Q_PROPERTY(QFont font READ font WRITE setFont)
+ Q_PROPERTY(float fontSize READ fontSize WRITE setFontSize)
+ Q_PROPERTY(bool gridVisible READ isGridVisible WRITE setGridVisible)
+ Q_PROPERTY(bool backgroundVisible READ isBackgroundVisible WRITE setBackgroundVisible)
+ Q_ENUMS(QtDataVis3D::QDataVis::SelectionMode)
+ Q_ENUMS(QtDataVis3D::QDataVis::ShadowQuality)
+ Q_ENUMS(QtDataVis3D::QDataVis::LabelTransparency)
+ Q_ENUMS(QtDataVis3D::QDataVis::MeshStyle)
+ Q_ENUMS(QtDataVis3D::QDataVis::CameraPreset)
+ Q_ENUMS(QtDataVis3D::QDataVis::ColorTheme)
+
+public:
+ explicit DeclarativeScatter(QQuickItem *parent = 0);
+ ~DeclarativeScatter();
+
+ void classBegin();
+ void componentComplete();
+
+ // Set camera rotation if you don't want to use the presets (in horizontal (-180...180) and
+ // vertical (-90...90) angles and distance in percentage (10...500))
+ Q_INVOKABLE void setCameraPosition(qreal horizontal, qreal vertical, int distance);
+
+ // Set color if you don't want to use themes. Set uniform to false if you want the (height)
+ // color to change from bottom to top
+ Q_INVOKABLE void setObjectColor(QColor baseColor, QColor heightColor, QColor depthColor,
+ bool uniform = true);
+
+ // Add whole data set.
+ void setData(QAbstractItemModel *data);
+ QAbstractItemModel *data();
+
+ QItemModelScatterDataMapping *mapping() const;
+ void setMapping(QItemModelScatterDataMapping *mapping);
+
+ QValueAxis *axisX() const;
+ void setAxisX(QValueAxis *axis);
+ QValueAxis *axisY() const;
+ void setAxisY(QValueAxis *axis);
+ QValueAxis *axisZ() const;
+ void setAxisZ(QValueAxis *axis);
+
+ // Object type
+ void setObjectType(QDataVis::MeshStyle style);
+ QDataVis::MeshStyle objectType();
+
+ // Object smoothing
+ void setObjectSmooth(bool smooth);
+ bool objectSmooth();
+
+ // override object type with own mesh
+ void setMeshFileName(const QString &objFileName);
+ QString meshFileName();
+
+ // Select preset camera placement
+ void setCameraPreset(QDataVis::CameraPreset preset);
+ QDataVis::CameraPreset cameraPreset();
+
+ // Set theme (object colors, shaders, window color, background colors, light intensity and text
+ // colors are affected)
+ void setTheme(QDataVis::ColorTheme theme);
+ QDataVis::ColorTheme theme();
+
+ // Change selection mode
+ void setSelectionMode(QDataVis::SelectionMode mode);
+ QDataVis::SelectionMode selectionMode();
+
+ // Font size adjustment
+ void setFontSize(float fontsize);
+ float fontSize();
+
+ // Set font
+ void setFont(const QFont &font);
+ QFont font();
+
+ // Label transparency adjustment
+ void setLabelTransparency(QDataVis::LabelTransparency transparency);
+ QDataVis::LabelTransparency labelTransparency();
+
+ // Enable or disable background grid
+ void setGridVisible(bool visible);
+ bool isGridVisible();
+
+ // Enable or disable background mesh
+ void setBackgroundVisible(bool visible);
+ bool isBackgroundVisible();
+
+ // Adjust shadow quality
+ void setShadowQuality(QDataVis::ShadowQuality quality);
+ QDataVis::ShadowQuality shadowQuality();
+
+public slots:
+ // Used to detect when shadow quality changes autonomously due to e.g. resizing.
+ void handleShadowQualityUpdate(QDataVis::ShadowQuality quality);
+
+signals:
+ // Signals shadow quality changes.
+ void shadowQualityChanged(QDataVis::ShadowQuality quality);
+
+protected:
+ Scatter3DController *m_shared;
+ QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *);
+
+ void mousePressEvent(QMouseEvent *event);
+ void mouseReleaseEvent(QMouseEvent *event);
+ void mouseMoveEvent(QMouseEvent *event);
+ void wheelEvent(QWheelEvent *event);
+
+private:
+ QSize m_initialisedSize;
+ QDataVis::CameraPreset m_cameraPreset;
+ QDataVis::ColorTheme m_theme;
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3dqml2/declarativescatterrenderer.cpp b/src/datavis3dqml2/declarativescatterrenderer.cpp
new file mode 100644
index 00000000..23c59c26
--- /dev/null
+++ b/src/datavis3dqml2/declarativescatterrenderer.cpp
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+#include "declarativescatterrenderer_p.h"
+
+#include <QtQuick/QQuickWindow>
+#include <QtGui/QOpenGLFramebufferObject>
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+DeclarativeScatterRenderer::DeclarativeScatterRenderer(QQuickWindow *window,
+ Scatter3DController *renderer)
+ : m_fbo(0),
+ m_texture(0),
+ m_window(window),
+ m_scatterRenderer(renderer)
+{
+ connect(m_window, SIGNAL(beforeSynchronizing()), this, SLOT(synchDataToRenderer()), Qt::DirectConnection);
+ connect(m_window, SIGNAL(beforeRendering()), this, SLOT(renderFBO()), Qt::DirectConnection);
+}
+
+DeclarativeScatterRenderer::~DeclarativeScatterRenderer()
+{
+ delete m_texture;
+ delete m_fbo;
+}
+
+void DeclarativeScatterRenderer::synchDataToRenderer()
+{
+ m_scatterRenderer->initializeOpenGL();
+ m_scatterRenderer->synchDataToRenderer();
+}
+
+void DeclarativeScatterRenderer::renderFBO()
+{
+ QSize size = rect().size().toSize();
+
+ // Create FBO
+ if (!m_fbo) {
+ QOpenGLFramebufferObjectFormat format;
+ format.setAttachment(QOpenGLFramebufferObject::Depth);
+ m_fbo = new QOpenGLFramebufferObject(size, format);
+ m_texture = m_window->createTextureFromId(m_fbo->texture(), size);
+
+ setTexture(m_texture);
+
+ // Flip texture
+ // TODO: Can be gotten rid of once support for texture flipping becomes available (in Qt5.2)
+ QSize ts = m_texture->textureSize();
+ QRectF sourceRect(0, 0, ts.width(), ts.height());
+ float tmp = sourceRect.top();
+ sourceRect.setTop(sourceRect.bottom());
+ sourceRect.setBottom(tmp);
+ QSGGeometry *geometry = this->geometry();
+ QSGGeometry::updateTexturedRectGeometry(geometry, rect(),
+ m_texture->convertToNormalizedSourceRect(sourceRect));
+ markDirty(DirtyMaterial);
+ //qDebug() << "create node" << m_fbo->handle() << m_texture->textureId() << m_fbo->size();
+ }
+
+ // Call the shared rendering function
+ m_fbo->bind();
+
+ m_scatterRenderer->render(m_fbo->handle());
+
+ m_fbo->release();
+
+ // New view is in the FBO, request repaint of scene graph
+ m_window->update();
+}
+
+QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3dqml2/declarativescatterrenderer_p.h b/src/datavis3dqml2/declarativescatterrenderer_p.h
new file mode 100644
index 00000000..498b1d83
--- /dev/null
+++ b/src/datavis3dqml2/declarativescatterrenderer_p.h
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc
+** All rights reserved.
+** For any questions to Digia, please use contact form at http://qt.digia.com
+**
+** This file is part of the QtDataVis3D module.
+**
+** Licensees holding valid Qt Enterprise licenses may use this file in
+** accordance with the Qt Enterprise License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.
+**
+** If you have questions regarding the use of this file, please use
+** contact form at http://qt.digia.com
+**
+****************************************************************************/
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the QtDataVis3D API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+
+#ifndef DECLARATIVESCATTERRENDERER_P_H
+#define DECLARATIVESCATTERRENDERER_P_H
+
+#include "datavis3dglobal_p.h"
+#include "scatter3dcontroller_p.h"
+#include <qsgsimpletexturenode.h>
+
+class QOpenGLFramebufferObject;
+class QSGTexture;
+class QQuickWindow;
+
+QT_DATAVIS3D_BEGIN_NAMESPACE
+
+class DeclarativeScatterRenderer : public QObject, public QSGSimpleTextureNode
+{
+ Q_OBJECT
+
+public:
+ DeclarativeScatterRenderer(QQuickWindow *window, Scatter3DController *shared);
+ ~DeclarativeScatterRenderer();
+
+public slots:
+ // Used to synch up data model from controller to renderer while main thread is locked
+ void synchDataToRenderer();
+ // Renders view to FBO before render cycle starts.
+ void renderFBO();
+
+private:
+ QOpenGLFramebufferObject *m_fbo;
+ QSGTexture *m_texture;
+ QQuickWindow *m_window;
+ Scatter3DController *m_scatterRenderer;
+};
+
+QT_DATAVIS3D_END_NAMESPACE
+
+#endif
diff --git a/src/src.pro b/src/src.pro
index d25722eb..171f9fde 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -1,3 +1,3 @@
TEMPLATE = subdirs
SUBDIRS += datavis3d \
- datavis3dqml2
+ datavis3dqml2