summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomi Korpipää <tomi.korpipaa@digia.com>2013-10-14 08:12:34 +0300
committerTomi Korpipää <tomi.korpipaa@digia.com>2013-10-14 08:12:34 +0300
commit18a5a1510b90a16007569f436392b52553f150fa (patch)
tree190f35b2da9ad298a4bc1636d0a9d993f41ea288
parenta64c67d75badaa7662b8a05b8bc7ed78ec8e651e (diff)
parent34c345b024be424873bbb8b3c83414eea2bc7523 (diff)
Merge remote-tracking branch 'origin/develop'
-rw-r--r--examples/audiolevels/audiolevels.cpp78
-rw-r--r--examples/audiolevels/audiolevels.h (renamed from examples/qmlbarchart/doc/src/qmlbarchart.qdoc)34
-rw-r--r--examples/audiolevels/audiolevels.pro20
-rw-r--r--examples/audiolevels/audiolevelsiodevice.cpp102
-rw-r--r--examples/audiolevels/audiolevelsiodevice.h44
-rw-r--r--examples/audiolevels/doc/images/audiolevels-example.pngbin0 -> 171468 bytes
-rw-r--r--examples/audiolevels/doc/src/audiolevels.qdoc85
-rw-r--r--examples/audiolevels/main.cpp (renamed from examples/barchart/doc/src/barchart.qdoc)26
-rw-r--r--examples/barchart/doc/images/barchart-example.pngbin163146 -> 0 bytes
-rw-r--r--examples/barchart/main.cpp308
-rw-r--r--examples/bars/bars.pro (renamed from examples/mapdata/mapdata.pro)8
-rw-r--r--examples/bars/doc/images/bars-example.pngbin0 -> 381366 bytes
-rw-r--r--examples/bars/doc/src/bars.qdoc159
-rw-r--r--examples/bars/graphmodifier.cpp229
-rw-r--r--examples/bars/graphmodifier.h79
-rw-r--r--examples/bars/main.cpp211
-rw-r--r--examples/customproxy/customproxy.pro (renamed from examples/rainfall/rainfall.pro)11
-rw-r--r--examples/customproxy/customproxy.qrc (renamed from examples/rainfall/rainfall.qrc)0
-rw-r--r--examples/customproxy/data/raindata.txt158
-rw-r--r--examples/customproxy/doc/images/customproxy-example.pngbin0 -> 266150 bytes
-rw-r--r--examples/customproxy/doc/src/customproxy.qdoc113
-rw-r--r--examples/customproxy/main.cpp (renamed from examples/rainfall/main.cpp)18
-rw-r--r--examples/customproxy/rainfallgraph.cpp (renamed from examples/rainfall/rainfallchart.cpp)107
-rw-r--r--examples/customproxy/rainfallgraph.h (renamed from examples/rainfall/rainfallchart.h)25
-rw-r--r--examples/customproxy/variantbardatamapping.cpp (renamed from examples/rainfall/variantbardatamapping.cpp)16
-rw-r--r--examples/customproxy/variantbardatamapping.h (renamed from examples/rainfall/variantbardatamapping.h)14
-rw-r--r--examples/customproxy/variantbardataproxy.cpp (renamed from examples/rainfall/variantbardataproxy.cpp)34
-rw-r--r--examples/customproxy/variantbardataproxy.h (renamed from examples/rainfall/variantbardataproxy.h)10
-rw-r--r--examples/customproxy/variantdataset.cpp (renamed from examples/rainfall/variantdataset.cpp)2
-rw-r--r--examples/customproxy/variantdataset.h (renamed from examples/rainfall/variantdataset.h)10
-rw-r--r--examples/examples.pri30
-rw-r--r--examples/examples.pro19
-rw-r--r--examples/itemmodel/doc/images/itemmodel-example-2.pngbin0 -> 233656 bytes
-rw-r--r--examples/itemmodel/doc/images/itemmodel-example.pngbin0 -> 151107 bytes
-rw-r--r--examples/itemmodel/doc/src/itemmodel.qdoc182
-rw-r--r--examples/itemmodel/itemmodel.pro (renamed from examples/barchart/barchart.pro)3
-rw-r--r--examples/itemmodel/main.cpp287
-rw-r--r--examples/mapdata/Suomi.karttapohja.svg3018
-rw-r--r--examples/mapdata/doc/images/mapdata-example.pngbin114152 -> 0 bytes
-rw-r--r--examples/mapdata/doc/src/mapdata.qdoc29
-rw-r--r--examples/mapdata/main.cpp201
-rw-r--r--examples/mapdata/mapdata.cpp368
-rw-r--r--examples/mapdata/mapdata.qrc8
-rw-r--r--examples/mapdata/weirdthing.obj1232
-rw-r--r--examples/qmlbarchart/qml/qmlbarchart/main.qml205
-rw-r--r--examples/qmlbarchart/qmlbarchart.qrc5
-rw-r--r--examples/qmlbars/doc/images/qmlbars-example.pngbin0 -> 263992 bytes
-rw-r--r--examples/qmlbars/doc/src/qmlbars.qdoc83
-rw-r--r--examples/qmlbars/main.cpp (renamed from examples/qmlbarchart/main.cpp)7
-rw-r--r--examples/qmlbars/qml/qmlbars/axes.qml52
-rw-r--r--examples/qmlbars/qml/qmlbars/data.qml137
-rw-r--r--examples/qmlbars/qml/qmlbars/main.qml163
-rw-r--r--examples/qmlbars/qmlbars.desktop (renamed from examples/qmlmaps/qmlmaps.desktop)6
-rw-r--r--examples/qmlbars/qmlbars.pro (renamed from examples/qmlmaps/qmlmaps.pro)18
-rw-r--r--examples/qmlbars/qmlbars.qrc7
-rw-r--r--examples/qmlbars/qmlbars64.png (renamed from examples/qmlbarchart/qmlbarchart64.png)bin3400 -> 3400 bytes
-rw-r--r--examples/qmlbars/qtquick2applicationviewer/qtquick2applicationviewer.cpp (renamed from examples/qmlbarchart/qtquick2applicationviewer/qtquick2applicationviewer.cpp)0
-rw-r--r--examples/qmlbars/qtquick2applicationviewer/qtquick2applicationviewer.h (renamed from examples/qmlbarchart/qtquick2applicationviewer/qtquick2applicationviewer.h)0
-rw-r--r--examples/qmlbars/qtquick2applicationviewer/qtquick2applicationviewer.pri (renamed from examples/qmlmaps/qtquick2applicationviewer/qtquick2applicationviewer.pri)10
-rw-r--r--examples/qmlmaps/doc/src/qmlmaps.qdoc29
-rw-r--r--examples/qmlmaps/floorplan.jpgbin108298 -> 0 bytes
-rw-r--r--examples/qmlmaps/qml/qmlmaps/main.qml114
-rw-r--r--examples/qmlmaps/qmlmaps.qrc8
-rw-r--r--examples/qmlscatter/doc/images/qmlscatter-example.pngbin0 -> 190076 bytes
-rw-r--r--examples/qmlscatter/doc/images/qmlscatter-newproject.pngbin0 -> 104569 bytes
-rw-r--r--examples/qmlscatter/doc/src/qmlscatter.qdoc147
-rw-r--r--examples/qmlscatter/main.cpp13
-rw-r--r--examples/qmlscatter/qml/qmlscatter/data.qml1109
-rw-r--r--examples/qmlscatter/qml/qmlscatter/main.qml252
-rw-r--r--examples/qmlscatter/qml/qmlscatter/newbutton.qml43
-rw-r--r--examples/qmlscatter/qmlscatter.pro8
-rw-r--r--examples/qmlscatter/qmlscatter.qrc2
-rw-r--r--examples/qmlscatter/qtquick2applicationviewer/qtquick2applicationviewer.pri10
-rw-r--r--examples/qmlsurface/doc/images/qmlsurface-example.pngbin0 -> 748571 bytes
-rw-r--r--examples/qmlsurface/doc/src/qmlsurface.qdoc88
-rw-r--r--examples/qmlsurface/heightmap.pngbin0 -> 38634 bytes
-rw-r--r--examples/qmlsurface/main.cpp46
-rw-r--r--examples/qmlsurface/qml/qmlsurface/data.qml10062
-rw-r--r--examples/qmlsurface/qml/qmlsurface/main.qml166
-rw-r--r--examples/qmlsurface/qml/qmlsurface/newbutton.qml43
-rw-r--r--examples/qmlsurface/qmlsurface.desktop (renamed from examples/qmlbarchart/qmlbarchart.desktop)6
-rw-r--r--examples/qmlsurface/qmlsurface.pro25
-rw-r--r--examples/qmlsurface/qmlsurface.qrc10
-rw-r--r--examples/qmlsurface/qmlsurface64.png (renamed from examples/qmlmaps/qmlmaps64.png)bin3400 -> 3400 bytes
-rw-r--r--examples/qmlsurface/qtquick2applicationviewer/qtquick2applicationviewer.cpp (renamed from examples/qmlmaps/qtquick2applicationviewer/qtquick2applicationviewer.cpp)0
-rw-r--r--examples/qmlsurface/qtquick2applicationviewer/qtquick2applicationviewer.h (renamed from examples/qmlmaps/qtquick2applicationviewer/qtquick2applicationviewer.h)0
-rw-r--r--examples/qmlsurface/qtquick2applicationviewer/qtquick2applicationviewer.pri170
-rw-r--r--examples/rainfall/data/raindata.txt1358
-rw-r--r--examples/rainfall/doc/images/rainfall-example.pngbin294202 -> 0 bytes
-rw-r--r--examples/rainfall/doc/src/rainfall.qdoc28
-rw-r--r--examples/scatter/doc/images/scatter-example.pngbin0 -> 433068 bytes
-rw-r--r--examples/scatter/doc/src/scatter.qdoc154
-rw-r--r--examples/scatter/main.cpp162
-rw-r--r--examples/scatter/scatter.pro13
-rw-r--r--examples/scatter/scatterdatamodifier.cpp188
-rw-r--r--examples/scatter/scatterdatamodifier.h (renamed from examples/mapdata/mapdata.h)45
-rw-r--r--examples/scatterchart/doc/src/scatterchart.qdoc29
-rw-r--r--examples/spectrum/doc/images/spectrum-example.pngbin79769 -> 0 bytes
-rw-r--r--examples/spectrum/doc/src/spectrum.qdoc28
-rw-r--r--examples/surface/doc/images/surface-example.pngbin0 -> 366836 bytes
-rw-r--r--examples/surface/doc/src/surface.qdoc131
-rw-r--r--examples/surface/main.cpp210
-rw-r--r--examples/surface/mountain.pngbin0 -> 34540 bytes
-rw-r--r--examples/surface/surface.pro17
-rw-r--r--examples/surface/surface.qrc5
-rw-r--r--examples/surface/surfacegraph.cpp242
-rw-r--r--examples/surface/surfacegraph.h83
-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.cpp440
-rw-r--r--examples/widget/doc/images/widget-example.pngbin233825 -> 0 bytes
-rw-r--r--examples/widget/doc/src/widget.qdoc29
-rw-r--r--qtdatavisualization.pro (renamed from qtdatavis3d.pro)4
-rw-r--r--src/datavis3d/axis/axis.pri12
-rw-r--r--src/datavis3d/axis/qabstractaxis.cpp84
-rw-r--r--src/datavis3d/axis/qabstractaxis_p.h61
-rw-r--r--src/datavis3d/axis/qcategoryaxis.cpp60
-rw-r--r--src/datavis3d/axis/qvalueaxis.cpp235
-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/qbardataproxy.cpp262
-rw-r--r--src/datavis3d/data/qitemmodelbardatamapping.cpp156
-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/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/qitemmodelscatterdataproxy.cpp305
-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/qmapdataproxy.cpp111
-rw-r--r--src/datavis3d/data/qmapdataproxy.h88
-rw-r--r--src/datavis3d/data/qscatterdataproxy.cpp210
-rw-r--r--src/datavis3d/data/scatterrenderitem.cpp51
-rw-r--r--src/datavis3d/datavis3d.pro24
-rw-r--r--src/datavis3d/doc/images/q3dbars-minimal.pngbin7688 -> 0 bytes
-rw-r--r--src/datavis3d/doc/qtdatavis3d.qdocconf33
-rw-r--r--src/datavis3d/doc/snippets/doc_src_qtdatavis3d.cpp21
-rw-r--r--src/datavis3d/doc/src/qtdatavis3d-index.qdoc62
-rw-r--r--src/datavis3d/doc/src/qtdatavis3d.qdoc26
-rw-r--r--src/datavis3d/doc/src/qtdatavis3dlicense.qdoc31
-rw-r--r--src/datavis3d/engine/abstract3dcontroller.cpp698
-rw-r--r--src/datavis3d/engine/abstract3drenderer.cpp219
-rw-r--r--src/datavis3d/engine/bars3dcontroller.cpp459
-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/q3dbars.cpp487
-rw-r--r--src/datavis3d/engine/q3dbars.h163
-rw-r--r--src/datavis3d/engine/q3dmaps.cpp270
-rw-r--r--src/datavis3d/engine/q3dmaps.h143
-rw-r--r--src/datavis3d/engine/q3dscatter.cpp463
-rw-r--r--src/datavis3d/engine/q3dscatter.h153
-rw-r--r--src/datavis3d/engine/q3dsurface.cpp181
-rw-r--r--src/datavis3d/engine/q3dsurface.h84
-rw-r--r--src/datavis3d/engine/scatter3dcontroller.cpp367
-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/theme.cpp307
-rw-r--r--src/datavis3d/global/global.pri4
-rw-r--r--src/datavis3d/global/qdatavis3denums.h115
-rw-r--r--src/datavis3d/global/qdatavis3dglobal.h67
-rw-r--r--src/datavis3d/global/qtdatavis3dnamespace.qdoc163
-rw-r--r--src/datavis3d/utils/surfaceobject.cpp349
-rw-r--r--src/datavis3d/utils/utils.cpp234
-rw-r--r--src/datavis3dqml2/datavis3dqml2_plugin.cpp48
-rw-r--r--src/datavis3dqml2/datavis3dqml2_plugin.h64
-rw-r--r--src/datavis3dqml2/declarativebars.cpp380
-rw-r--r--src/datavis3dqml2/declarativebars_p.h206
-rw-r--r--src/datavis3dqml2/declarativemaps.cpp229
-rw-r--r--src/datavis3dqml2/declarativemaps_p.h139
-rw-r--r--src/datavis3dqml2/declarativescatter.cpp328
-rw-r--r--src/datavis3dqml2/declarativescatter_p.h175
-rw-r--r--src/datavis3dqml2/qmldir3
-rw-r--r--src/datavisualization/axis/axis.pri12
-rw-r--r--src/datavisualization/axis/q3dabstractaxis.cpp373
-rw-r--r--src/datavisualization/axis/q3dabstractaxis.h (renamed from src/datavis3d/axis/qabstractaxis.h)40
-rw-r--r--src/datavisualization/axis/q3dabstractaxis_p.h77
-rw-r--r--src/datavisualization/axis/q3dcategoryaxis.cpp152
-rw-r--r--src/datavisualization/axis/q3dcategoryaxis.h (renamed from src/datavis3d/axis/qcategoryaxis.h)32
-rw-r--r--src/datavisualization/axis/q3dcategoryaxis_p.h (renamed from src/datavis3d/axis/qcategoryaxis_p.h)26
-rw-r--r--src/datavisualization/axis/q3dvalueaxis.cpp270
-rw-r--r--src/datavisualization/axis/q3dvalueaxis.h (renamed from src/datavis3d/axis/qvalueaxis.h)38
-rw-r--r--src/datavisualization/axis/q3dvalueaxis_p.h (renamed from src/datavis3d/axis/qvalueaxis_p.h)35
-rw-r--r--src/datavisualization/common.pri (renamed from src/datavis3d/common.pri)3
-rw-r--r--src/datavisualization/data/abstractitemmodelhandler.cpp250
-rw-r--r--src/datavisualization/data/abstractitemmodelhandler_p.h90
-rw-r--r--src/datavisualization/data/abstractrenderitem.cpp (renamed from src/datavis3d/data/abstractrenderitem.cpp)47
-rw-r--r--src/datavisualization/data/abstractrenderitem_p.h (renamed from src/datavis3d/data/abstractrenderitem_p.h)29
-rw-r--r--src/datavisualization/data/baritemmodelhandler.cpp148
-rw-r--r--src/datavisualization/data/baritemmodelhandler_p.h (renamed from src/datavis3d/data/qitemmodelmapdatamapping_p.h)34
-rw-r--r--src/datavisualization/data/barrenderitem.cpp (renamed from src/datavis3d/data/barrenderitem.cpp)47
-rw-r--r--src/datavisualization/data/barrenderitem_p.h (renamed from src/datavis3d/data/barrenderitem_p.h)35
-rw-r--r--src/datavisualization/data/data.pri (renamed from src/datavis3d/data/data.pri)44
-rw-r--r--src/datavisualization/data/labelitem.cpp (renamed from src/datavis3d/data/labelitem.cpp)6
-rw-r--r--src/datavisualization/data/labelitem_p.h (renamed from src/datavis3d/data/labelitem_p.h)10
-rw-r--r--src/datavisualization/data/qabstractdatamapping.cpp71
-rw-r--r--src/datavisualization/data/qabstractdatamapping.h53
-rw-r--r--src/datavisualization/data/qabstractdatamapping_p.h50
-rw-r--r--src/datavisualization/data/qabstractdataproxy.cpp148
-rw-r--r--src/datavisualization/data/qabstractdataproxy.h (renamed from src/datavis3d/data/qabstractdataproxy.h)26
-rw-r--r--src/datavisualization/data/qabstractdataproxy_p.h (renamed from src/datavis3d/data/qabstractdataproxy_p.h)14
-rw-r--r--src/datavisualization/data/qbardataitem.cpp (renamed from src/datavis3d/data/qbardataitem.cpp)39
-rw-r--r--src/datavisualization/data/qbardataitem.h (renamed from src/datavis3d/data/qbardataitem.h)14
-rw-r--r--src/datavisualization/data/qbardataitem_p.h (renamed from src/datavis3d/data/qbardataitem_p.h)10
-rw-r--r--src/datavisualization/data/qbardataproxy.cpp707
-rw-r--r--src/datavisualization/data/qbardataproxy.h (renamed from src/datavis3d/data/qbardataproxy.h)76
-rw-r--r--src/datavisualization/data/qbardataproxy_p.h (renamed from src/datavis3d/data/qbardataproxy_p.h)32
-rw-r--r--src/datavisualization/data/qheightmapsurfacedataproxy.cpp489
-rw-r--r--src/datavisualization/data/qheightmapsurfacedataproxy.h75
-rw-r--r--src/datavisualization/data/qheightmapsurfacedataproxy_p.h69
-rw-r--r--src/datavisualization/data/qitemmodelbardatamapping.cpp407
-rw-r--r--src/datavisualization/data/qitemmodelbardatamapping.h (renamed from src/datavis3d/data/qitemmodelbardatamapping.h)55
-rw-r--r--src/datavisualization/data/qitemmodelbardatamapping_p.h (renamed from src/datavis3d/data/qitemmodelbardatamapping_p.h)16
-rw-r--r--src/datavisualization/data/qitemmodelbardataproxy.cpp198
-rw-r--r--src/datavisualization/data/qitemmodelbardataproxy.h62
-rw-r--r--src/datavisualization/data/qitemmodelbardataproxy_p.h (renamed from src/datavis3d/data/qmapdataproxy_p.h)40
-rw-r--r--src/datavisualization/data/qitemmodelscatterdatamapping.cpp200
-rw-r--r--src/datavisualization/data/qitemmodelscatterdatamapping.h (renamed from src/datavis3d/data/qitemmodelscatterdatamapping.h)40
-rw-r--r--src/datavisualization/data/qitemmodelscatterdatamapping_p.h (renamed from src/datavis3d/data/qitemmodelscatterdatamapping_p.h)17
-rw-r--r--src/datavisualization/data/qitemmodelscatterdataproxy.cpp196
-rw-r--r--src/datavisualization/data/qitemmodelscatterdataproxy.h (renamed from src/datavis3d/data/qitemmodelscatterdataproxy.h)32
-rw-r--r--src/datavisualization/data/qitemmodelscatterdataproxy_p.h58
-rw-r--r--src/datavisualization/data/qitemmodelsurfacedatamapping.cpp411
-rw-r--r--src/datavisualization/data/qitemmodelsurfacedatamapping.h90
-rw-r--r--src/datavisualization/data/qitemmodelsurfacedatamapping_p.h63
-rw-r--r--src/datavisualization/data/qitemmodelsurfacedataproxy.cpp198
-rw-r--r--src/datavisualization/data/qitemmodelsurfacedataproxy.h62
-rw-r--r--src/datavisualization/data/qitemmodelsurfacedataproxy_p.h58
-rw-r--r--src/datavisualization/data/qscatterdataitem.cpp (renamed from src/datavis3d/data/qscatterdataitem.cpp)68
-rw-r--r--src/datavisualization/data/qscatterdataitem.h (renamed from src/datavis3d/data/qscatterdataitem.h)20
-rw-r--r--src/datavisualization/data/qscatterdataitem_p.h (renamed from src/datavis3d/data/qscatterdataitem_p.h)10
-rw-r--r--src/datavisualization/data/qscatterdataproxy.cpp367
-rw-r--r--src/datavisualization/data/qscatterdataproxy.h (renamed from src/datavis3d/data/qscatterdataproxy.h)41
-rw-r--r--src/datavisualization/data/qscatterdataproxy_p.h (renamed from src/datavis3d/data/qscatterdataproxy_p.h)11
-rw-r--r--src/datavisualization/data/qsurfacedataitem.cpp143
-rw-r--r--src/datavisualization/data/qsurfacedataitem.h59
-rw-r--r--src/datavisualization/data/qsurfacedataitem_p.h (renamed from src/datavis3d/data/qmapdataitem_p.h)27
-rw-r--r--src/datavisualization/data/qsurfacedataproxy.cpp289
-rw-r--r--src/datavisualization/data/qsurfacedataproxy.h66
-rw-r--r--src/datavisualization/data/qsurfacedataproxy_p.h63
-rw-r--r--src/datavisualization/data/scatteritemmodelhandler.cpp81
-rw-r--r--src/datavisualization/data/scatteritemmodelhandler_p.h53
-rw-r--r--src/datavisualization/data/scatterrenderitem.cpp42
-rw-r--r--src/datavisualization/data/scatterrenderitem_p.h (renamed from src/datavis3d/data/scatterrenderitem_p.h)36
-rw-r--r--src/datavisualization/data/surfaceitemmodelhandler.cpp144
-rw-r--r--src/datavisualization/data/surfaceitemmodelhandler_p.h53
-rw-r--r--src/datavisualization/datavisualization.pro27
-rw-r--r--src/datavisualization/doc/images/q3dbars-minimal.pngbin0 -> 8611 bytes
-rw-r--r--src/datavisualization/doc/images/q3dscatter-minimal.pngbin0 -> 7998 bytes
-rw-r--r--src/datavisualization/doc/images/q3dsurface-minimal.pngbin0 -> 16174 bytes
-rw-r--r--src/datavisualization/doc/qtdatavisualization.qdocconf51
-rw-r--r--src/datavisualization/doc/snippets/doc_src_q3dbars_construction.cpp46
-rw-r--r--src/datavisualization/doc/snippets/doc_src_q3dscatter_construction.cpp (renamed from src/datavis3d/doc/snippets/doc_src_q3dbars_construction.cpp)17
-rw-r--r--src/datavisualization/doc/snippets/doc_src_q3dsurface_construction.cpp50
-rw-r--r--src/datavisualization/doc/snippets/doc_src_qmldatavisualization.cpp121
-rw-r--r--src/datavisualization/doc/snippets/doc_src_qtdatavisualization.cpp118
-rw-r--r--src/datavisualization/doc/snippets/doc_src_qtdatavisualization.pro (renamed from src/datavis3d/doc/snippets/doc_src_qtdatavis3d.pro)4
-rw-r--r--src/datavisualization/doc/src/qtdatavisualization-index.qdoc78
-rw-r--r--src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc81
-rw-r--r--src/datavisualization/doc/src/qtdatavisualization-qml-bars3d.qdoc136
-rw-r--r--src/datavisualization/doc/src/qtdatavisualization-qml-colorgradient.qdoc81
-rw-r--r--src/datavisualization/doc/src/qtdatavisualization-qml-scatter3d.qdoc105
-rw-r--r--src/datavisualization/doc/src/qtdatavisualization-qml-surface3d.qdoc90
-rw-r--r--src/datavisualization/doc/src/qtdatavisualization.qdoc209
-rw-r--r--src/datavisualization/engine/abstract3dcontroller.cpp1056
-rw-r--r--src/datavisualization/engine/abstract3dcontroller_p.h (renamed from src/datavis3d/engine/abstract3dcontroller_p.h)179
-rw-r--r--src/datavisualization/engine/abstract3drenderer.cpp313
-rw-r--r--src/datavisualization/engine/abstract3drenderer_p.h (renamed from src/datavis3d/engine/abstract3drenderer_p.h)98
-rw-r--r--src/datavisualization/engine/axisrendercache.cpp (renamed from src/datavis3d/engine/axisrendercache.cpp)57
-rw-r--r--src/datavisualization/engine/axisrendercache_p.h (renamed from src/datavis3d/engine/axisrendercache_p.h)23
-rw-r--r--src/datavisualization/engine/bars3dcontroller.cpp428
-rw-r--r--src/datavisualization/engine/bars3dcontroller_p.h (renamed from src/datavis3d/engine/bars3dcontroller_p.h)97
-rw-r--r--src/datavisualization/engine/bars3drenderer.cpp (renamed from src/datavis3d/engine/bars3drenderer.cpp)1115
-rw-r--r--src/datavisualization/engine/bars3drenderer_p.h (renamed from src/datavis3d/engine/bars3drenderer_p.h)82
-rw-r--r--src/datavisualization/engine/drawer.cpp (renamed from src/datavis3d/engine/drawer.cpp)115
-rw-r--r--src/datavisualization/engine/drawer_p.h (renamed from src/datavis3d/engine/drawer_p.h)26
-rw-r--r--src/datavisualization/engine/engine.pri (renamed from src/datavis3d/engine/engine.pri)27
-rw-r--r--src/datavisualization/engine/engine.qrc (renamed from src/datavis3d/engine/engine.qrc)1
-rw-r--r--src/datavisualization/engine/meshes/backgroudFlat.obj (renamed from src/datavis3d/engine/meshes/backgroudFlat.obj)0
-rw-r--r--src/datavisualization/engine/meshes/backgroudNegatives.obj (renamed from src/datavis3d/engine/meshes/backgroudNegatives.obj)0
-rw-r--r--src/datavisualization/engine/meshes/backgroudSmooth.obj (renamed from src/datavis3d/engine/meshes/backgroudSmooth.obj)0
-rw-r--r--src/datavisualization/engine/meshes/barFilledFlat.obj (renamed from src/datavis3d/engine/meshes/barFilledFlat.obj)0
-rw-r--r--src/datavisualization/engine/meshes/barFilledSmooth.obj (renamed from src/datavis3d/engine/meshes/barFilledSmooth.obj)0
-rw-r--r--src/datavisualization/engine/meshes/barFlat.obj (renamed from src/datavis3d/engine/meshes/barFlat.obj)0
-rw-r--r--src/datavisualization/engine/meshes/barSmooth.obj (renamed from src/datavis3d/engine/meshes/barSmooth.obj)0
-rw-r--r--src/datavisualization/engine/meshes/coneFilledFlat.obj (renamed from src/datavis3d/engine/meshes/coneFilledFlat.obj)0
-rw-r--r--src/datavisualization/engine/meshes/coneFilledSmooth.obj (renamed from src/datavis3d/engine/meshes/coneFilledSmooth.obj)0
-rw-r--r--src/datavisualization/engine/meshes/coneFlat.obj (renamed from src/datavis3d/engine/meshes/coneFlat.obj)0
-rw-r--r--src/datavisualization/engine/meshes/coneSmooth.obj (renamed from src/datavis3d/engine/meshes/coneSmooth.obj)0
-rw-r--r--src/datavisualization/engine/meshes/cubeFilledFlat.obj (renamed from src/datavis3d/engine/meshes/cubeFilledFlat.obj)0
-rw-r--r--src/datavisualization/engine/meshes/cubeFilledSmooth.obj (renamed from src/datavis3d/engine/meshes/cubeFilledSmooth.obj)0
-rw-r--r--src/datavisualization/engine/meshes/cubeFlat.obj (renamed from src/datavis3d/engine/meshes/cubeFlat.obj)0
-rw-r--r--src/datavisualization/engine/meshes/cubeSmooth.obj (renamed from src/datavis3d/engine/meshes/cubeSmooth.obj)0
-rw-r--r--src/datavisualization/engine/meshes/cylinderFilledFlat.obj (renamed from src/datavis3d/engine/meshes/cylinderFilledFlat.obj)0
-rw-r--r--src/datavisualization/engine/meshes/cylinderFilledSmooth.obj (renamed from src/datavis3d/engine/meshes/cylinderFilledSmooth.obj)0
-rw-r--r--src/datavisualization/engine/meshes/cylinderFlat.obj (renamed from src/datavis3d/engine/meshes/cylinderFlat.obj)0
-rw-r--r--src/datavisualization/engine/meshes/cylinderSmooth.obj (renamed from src/datavis3d/engine/meshes/cylinderSmooth.obj)0
-rw-r--r--src/datavisualization/engine/meshes/plane.obj (renamed from src/datavis3d/engine/meshes/plane.obj)0
-rw-r--r--src/datavisualization/engine/meshes/pyramidFilledFlat.obj (renamed from src/datavis3d/engine/meshes/pyramidFilledFlat.obj)0
-rw-r--r--src/datavisualization/engine/meshes/pyramidFilledSmooth.obj (renamed from src/datavis3d/engine/meshes/pyramidFilledSmooth.obj)0
-rw-r--r--src/datavisualization/engine/meshes/pyramidFlat.obj (renamed from src/datavis3d/engine/meshes/pyramidFlat.obj)0
-rw-r--r--src/datavisualization/engine/meshes/pyramidSmooth.obj (renamed from src/datavis3d/engine/meshes/pyramidSmooth.obj)0
-rw-r--r--src/datavisualization/engine/meshes/scatterdot.obj (renamed from src/datavis3d/engine/meshes/scatterdot.obj)0
-rw-r--r--src/datavisualization/engine/meshes/scatterdotFlat.obj (renamed from src/datavis3d/engine/meshes/scatterdotFlat.obj)0
-rw-r--r--src/datavisualization/engine/meshes/sphere.obj (renamed from src/datavis3d/engine/meshes/sphere.obj)0
-rw-r--r--src/datavisualization/engine/meshes/sphereSmooth.obj (renamed from src/datavis3d/engine/meshes/sphereSmooth.obj)0
-rw-r--r--src/datavisualization/engine/q3dbars.cpp620
-rw-r--r--src/datavisualization/engine/q3dbars.h142
-rw-r--r--src/datavisualization/engine/q3dbars_p.h (renamed from src/datavis3d/engine/q3dbars_p.h)15
-rw-r--r--src/datavisualization/engine/q3dbox.cpp481
-rw-r--r--src/datavisualization/engine/q3dbox.h184
-rw-r--r--src/datavisualization/engine/q3dcamera.cpp698
-rw-r--r--src/datavisualization/engine/q3dcamera.h131
-rw-r--r--src/datavisualization/engine/q3dcamera_p.h87
-rw-r--r--src/datavisualization/engine/q3dlight.cpp79
-rw-r--r--src/datavisualization/engine/q3dlight.h50
-rw-r--r--src/datavisualization/engine/q3dlight_p.h59
-rw-r--r--src/datavisualization/engine/q3dobject.cpp121
-rw-r--r--src/datavisualization/engine/q3dobject.h65
-rw-r--r--src/datavisualization/engine/q3dobject_p.h53
-rw-r--r--src/datavisualization/engine/q3dscatter.cpp568
-rw-r--r--src/datavisualization/engine/q3dscatter.h128
-rw-r--r--src/datavisualization/engine/q3dscatter_p.h (renamed from src/datavis3d/engine/q3dscatter_p.h)13
-rw-r--r--src/datavisualization/engine/q3dscene.cpp375
-rw-r--r--src/datavisualization/engine/q3dscene.h103
-rw-r--r--src/datavisualization/engine/q3dscene_p.h85
-rw-r--r--src/datavisualization/engine/q3dsurface.cpp542
-rw-r--r--src/datavisualization/engine/q3dsurface.h123
-rw-r--r--src/datavisualization/engine/q3dsurface_p.h (renamed from src/datavis3d/engine/q3dsurface_p.h)21
-rw-r--r--src/datavisualization/engine/q3dwindow.cpp (renamed from src/datavis3d/engine/q3dwindow.cpp)70
-rw-r--r--src/datavisualization/engine/q3dwindow.h (renamed from src/datavis3d/engine/q3dwindow.h)22
-rw-r--r--src/datavisualization/engine/q3dwindow_p.h (renamed from src/datavis3d/engine/q3dwindow_p.h)15
-rw-r--r--src/datavisualization/engine/scatter3dcontroller.cpp271
-rw-r--r--src/datavisualization/engine/scatter3dcontroller_p.h (renamed from src/datavis3d/engine/scatter3dcontroller_p.h)52
-rw-r--r--src/datavisualization/engine/scatter3drenderer.cpp (renamed from src/datavis3d/engine/scatter3drenderer.cpp)991
-rw-r--r--src/datavisualization/engine/scatter3drenderer_p.h (renamed from src/datavis3d/engine/scatter3drenderer_p.h)83
-rw-r--r--src/datavisualization/engine/selectionpointer.cpp275
-rw-r--r--src/datavisualization/engine/selectionpointer_p.h97
-rw-r--r--src/datavisualization/engine/shaders/ambient.frag (renamed from src/datavis3d/engine/shaders/ambient.frag)0
-rw-r--r--src/datavisualization/engine/shaders/colorOnY.frag (renamed from src/datavis3d/engine/shaders/colorOnY.frag)9
-rw-r--r--src/datavisualization/engine/shaders/colorOnY_ES2.frag (renamed from src/datavis3d/engine/shaders/colorOnY_ES2.frag)7
-rw-r--r--src/datavisualization/engine/shaders/default.frag (renamed from src/datavis3d/engine/shaders/default.frag)2
-rw-r--r--src/datavisualization/engine/shaders/default.vert (renamed from src/datavis3d/engine/shaders/default.vert)0
-rw-r--r--src/datavisualization/engine/shaders/default_ES2.frag (renamed from src/datavis3d/engine/shaders/default_ES2.frag)2
-rw-r--r--src/datavisualization/engine/shaders/default_ES2.vert (renamed from src/datavis3d/engine/shaders/default_ES2.vert)0
-rw-r--r--src/datavisualization/engine/shaders/depth.frag (renamed from src/datavis3d/engine/shaders/depth.frag)0
-rw-r--r--src/datavisualization/engine/shaders/depth.vert (renamed from src/datavis3d/engine/shaders/depth.vert)0
-rw-r--r--src/datavisualization/engine/shaders/label.frag (renamed from src/datavis3d/engine/shaders/label.frag)0
-rw-r--r--src/datavisualization/engine/shaders/label.vert (renamed from src/datavis3d/engine/shaders/label.vert)0
-rw-r--r--src/datavisualization/engine/shaders/selection.frag (renamed from src/datavis3d/engine/shaders/selection.frag)0
-rw-r--r--src/datavisualization/engine/shaders/selection.vert (renamed from src/datavis3d/engine/shaders/selection.vert)0
-rw-r--r--src/datavisualization/engine/shaders/shadow.frag (renamed from src/datavis3d/engine/shaders/shadow.frag)34
-rw-r--r--src/datavisualization/engine/shaders/shadow.vert (renamed from src/datavis3d/engine/shaders/shadow.vert)0
-rw-r--r--src/datavisualization/engine/shaders/shadowNoTex.frag (renamed from src/datavis3d/engine/shaders/shadowNoTex.frag)67
-rw-r--r--src/datavisualization/engine/shaders/shadowNoTexColorOnY.frag (renamed from src/datavis3d/engine/shaders/shadowNoTexColorOnY.frag)38
-rw-r--r--src/datavisualization/engine/shaders/surface.frag (renamed from src/datavis3d/engine/shaders/surface.frag)5
-rw-r--r--src/datavisualization/engine/shaders/surface.vert (renamed from src/datavis3d/engine/shaders/surface.vert)5
-rw-r--r--src/datavisualization/engine/shaders/surfaceFlat.frag (renamed from src/datavis3d/engine/shaders/surfaceFlat.frag)4
-rw-r--r--src/datavisualization/engine/shaders/surfaceFlat.vert (renamed from src/datavis3d/engine/shaders/surfaceFlat.vert)3
-rw-r--r--src/datavisualization/engine/shaders/surfaceGrid.frag6
-rw-r--r--src/datavisualization/engine/shaders/surfaceGrid.vert6
-rw-r--r--src/datavisualization/engine/shaders/surface_ES2.frag39
-rw-r--r--src/datavisualization/engine/shaders/texture.frag (renamed from src/datavis3d/engine/shaders/texture.frag)0
-rw-r--r--src/datavisualization/engine/shaders/texture.vert (renamed from src/datavis3d/engine/shaders/texture.vert)0
-rw-r--r--src/datavisualization/engine/shaders/texture_ES2.frag (renamed from src/datavis3d/engine/shaders/texture_ES2.frag)2
-rw-r--r--src/datavisualization/engine/surface3dcontroller.cpp233
-rw-r--r--src/datavisualization/engine/surface3dcontroller_p.h108
-rw-r--r--src/datavisualization/engine/surface3drenderer.cpp2185
-rw-r--r--src/datavisualization/engine/surface3drenderer_p.h (renamed from src/datavis3d/engine/surface3drenderer_p.h)162
-rw-r--r--src/datavisualization/engine/theme.cpp250
-rw-r--r--src/datavisualization/engine/theme_p.h (renamed from src/datavis3d/engine/theme_p.h)27
-rw-r--r--src/datavisualization/global/datavisualizationglobal_p.h (renamed from src/datavis3d/global/datavis3dglobal_p.h)24
-rw-r--r--src/datavisualization/global/global.pri4
-rw-r--r--src/datavisualization/global/qdatavisualizationenums.h126
-rw-r--r--src/datavisualization/global/qdatavisualizationglobal.h67
-rw-r--r--src/datavisualization/global/qtdatavisualizationenums.qdoc176
-rw-r--r--src/datavisualization/input/input.pri12
-rw-r--r--src/datavisualization/input/q3dinputhandler.cpp190
-rw-r--r--src/datavisualization/input/q3dinputhandler.h48
-rw-r--r--src/datavisualization/input/q3dinputhandler_p.h (renamed from src/datavis3d/engine/q3dmaps_p.h)30
-rw-r--r--src/datavisualization/input/qabstract3dinputhandler.cpp210
-rw-r--r--src/datavisualization/input/qabstract3dinputhandler.h82
-rw-r--r--src/datavisualization/input/qabstract3dinputhandler_p.h70
-rw-r--r--src/datavisualization/input/qtouch3dinputhandler.cpp209
-rw-r--r--src/datavisualization/input/qtouch3dinputhandler.h47
-rw-r--r--src/datavisualization/input/qtouch3dinputhandler_p.h50
-rw-r--r--src/datavisualization/utils/abstractobjecthelper.cpp (renamed from src/datavis3d/utils/abstractobjecthelper.cpp)6
-rw-r--r--src/datavisualization/utils/abstractobjecthelper_p.h (renamed from src/datavis3d/utils/abstractobjecthelper_p.h)10
-rw-r--r--src/datavisualization/utils/camerahelper.cpp (renamed from src/datavis3d/utils/camerahelper.cpp)102
-rw-r--r--src/datavisualization/utils/camerahelper_p.h (renamed from src/datavis3d/utils/camerahelper_p.h)10
-rw-r--r--src/datavisualization/utils/meshloader.cpp (renamed from src/datavis3d/utils/meshloader.cpp)6
-rw-r--r--src/datavisualization/utils/meshloader_p.h (renamed from src/datavis3d/utils/meshloader_p.h)10
-rw-r--r--src/datavisualization/utils/objecthelper.cpp (renamed from src/datavis3d/utils/objecthelper.cpp)6
-rw-r--r--src/datavisualization/utils/objecthelper_p.h (renamed from src/datavis3d/utils/objecthelper_p.h)10
-rw-r--r--src/datavisualization/utils/shaderhelper.cpp (renamed from src/datavis3d/utils/shaderhelper.cpp)18
-rw-r--r--src/datavisualization/utils/shaderhelper_p.h (renamed from src/datavis3d/utils/shaderhelper_p.h)11
-rw-r--r--src/datavisualization/utils/surfaceobject.cpp346
-rw-r--r--src/datavisualization/utils/surfaceobject_p.h (renamed from src/datavis3d/utils/surfaceobject_p.h)33
-rw-r--r--src/datavisualization/utils/texturehelper.cpp (renamed from src/datavis3d/utils/texturehelper.cpp)60
-rw-r--r--src/datavisualization/utils/texturehelper_p.h (renamed from src/datavis3d/utils/texturehelper_p.h)18
-rw-r--r--src/datavisualization/utils/utils.cpp263
-rw-r--r--src/datavisualization/utils/utils.pri (renamed from src/datavis3d/utils/utils.pri)0
-rw-r--r--src/datavisualization/utils/utils_p.h (renamed from src/datavis3d/utils/utils_p.h)32
-rw-r--r--src/datavisualization/utils/vertexindexer.cpp (renamed from src/datavis3d/utils/vertexindexer.cpp)6
-rw-r--r--src/datavisualization/utils/vertexindexer_p.h (renamed from src/datavis3d/utils/vertexindexer_p.h)10
-rw-r--r--src/datavisualizationqml2/abstractdeclarative.cpp189
-rw-r--r--src/datavisualizationqml2/abstractdeclarative_p.h119
-rw-r--r--src/datavisualizationqml2/colorgradient.cpp75
-rw-r--r--src/datavisualizationqml2/colorgradient_p.h90
-rw-r--r--src/datavisualizationqml2/datavisualizationqml2.pro (renamed from src/datavis3dqml2/datavis3dqml2.pro)30
-rw-r--r--src/datavisualizationqml2/datavisualizationqml2_plugin.cpp70
-rw-r--r--src/datavisualizationqml2/datavisualizationqml2_plugin.h88
-rw-r--r--src/datavisualizationqml2/declarativebars.cpp214
-rw-r--r--src/datavisualizationqml2/declarativebars_p.h113
-rw-r--r--src/datavisualizationqml2/declarativebarsrenderer.cpp (renamed from src/datavis3dqml2/declarativebarsrenderer.cpp)19
-rw-r--r--src/datavisualizationqml2/declarativebarsrenderer_p.h (renamed from src/datavis3dqml2/declarativebarsrenderer_p.h)14
-rw-r--r--src/datavisualizationqml2/declarativescatter.cpp168
-rw-r--r--src/datavisualizationqml2/declarativescatter_p.h93
-rw-r--r--src/datavisualizationqml2/declarativescatterrenderer.cpp (renamed from src/datavis3dqml2/declarativescatterrenderer.cpp)17
-rw-r--r--src/datavisualizationqml2/declarativescatterrenderer_p.h (renamed from src/datavis3dqml2/declarativescatterrenderer_p.h)10
-rw-r--r--src/datavisualizationqml2/declarativesurface.cpp185
-rw-r--r--src/datavisualizationqml2/declarativesurface_p.h97
-rw-r--r--src/datavisualizationqml2/declarativesurfacerenderer.cpp (renamed from src/datavis3dqml2/declarativemapsrenderer.cpp)36
-rw-r--r--src/datavisualizationqml2/declarativesurfacerenderer_p.h (renamed from src/datavis3dqml2/declarativemapsrenderer_p.h)29
-rw-r--r--src/datavisualizationqml2/qmldir3
-rw-r--r--src/src.pro5
-rw-r--r--sync.profile2
-rw-r--r--tests/barstest/barstest.pro (renamed from examples/widget/widget.pro)4
-rw-r--r--tests/barstest/chart.cpp580
-rw-r--r--tests/barstest/chart.h (renamed from examples/widget/chart.h)54
-rw-r--r--tests/barstest/main.cpp (renamed from examples/widget/main.cpp)232
-rw-r--r--tests/kinectsurface/QtKinectWrapper/00openni_notes.txt2
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/ARC/XnOSARC.h166
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/ARC/XnPlatformARC.h194
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/Android-Arm/XnPlatformAndroid-Arm.h49
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/IXnNodeAllocator.h53
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/Linux-Arm/XnPlatformLinux-Arm.h37
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/Linux-x86/XnOSLinux-x86.h165
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/Linux-x86/XnPlatformLinux-x86.h195
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/MacOSX/XnPlatformMacOSX.h43
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/Win32/XnOSWin32.h157
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/Win32/XnPlatformWin32.h255
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/Win32/usb100.h270
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnAlgorithms.h81
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnArray.h313
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnBaseNode.h59
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnBitSet.h135
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnCallback.h41
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnCodecIDs.h34
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnContext.h569
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnCppWrapper.h10100
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnCyclicQueueT.h79
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnCyclicStackT.h80
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnDataTypes.h120
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnDerivedCast.h80
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnDump.h202
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnDumpWriters.h127
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnEnumerationErrors.h142
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnEvent.h301
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnEventT.h393
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnFPSCalculator.h72
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnGeneralBuffer.h119
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnHash.h1014
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnHashT.h668
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnInternalDefs.h27
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnLicensing.h72
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnList.h749
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnListT.h556
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnLog.h545
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnLogTypes.h80
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnLogWriterBase.h128
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnMacros.h128
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnModuleCFunctions.h1995
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnModuleCppInterface.h605
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnModuleCppRegistratration.h303
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnModuleInterface.h1351
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnNode.h76
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnNodeAllocator.h46
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnOS.h784
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnOSCpp.h163
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnOSMemory.h47
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnOSStrings.h47
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnOpenNI.h50
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnPlatform.h124
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnPrdNode.h2614
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnPrdNodeInfo.h126
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnPrdNodeInfoList.h226
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnProfiling.h131
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnPropNames.h62
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnQueries.h159
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnQueue.h198
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnQueueT.h63
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnScheduler.h92
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnStack.h151
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnStackT.h58
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnStatus.h110
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnStatusCodes.h81
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnStatusRegister.h81
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnStringsHash.h118
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnStringsHashT.h90
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnThreadSafeQueue.h156
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnTypes.h1188
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnUSB.h128
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnUSBDevice.h117
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnUtils.h427
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnVersion.h58
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/mingw-win32/XnOSLinux-x86.h165
-rw-r--r--tests/kinectsurface/QtKinectWrapper/OpenNI/Include/mingw-win32/XnPlatformLinux-x86.h196
-rw-r--r--tests/kinectsurface/QtKinectWrapper/QKinectWrapper.cpp283
-rw-r--r--tests/kinectsurface/QtKinectWrapper/QKinectWrapper.h117
-rw-r--r--tests/kinectsurface/QtKinectWrapper/config.pro60
-rw-r--r--tests/kinectsurface/kinectsurface.pro71
-rw-r--r--tests/kinectsurface/main.cpp167
-rw-r--r--tests/kinectsurface/surfacedata.cpp357
-rw-r--r--tests/kinectsurface/surfacedata.h99
-rw-r--r--tests/qmlcamera/main.cpp (renamed from examples/qmlmaps/main.cpp)11
-rw-r--r--tests/qmlcamera/qml/qmlcamera/Axes.qml50
-rw-r--r--tests/qmlcamera/qml/qmlcamera/ControlSurface.qml53
-rw-r--r--tests/qmlcamera/qml/qmlcamera/Data.qml133
-rw-r--r--tests/qmlcamera/qml/qmlcamera/main.qml150
-rw-r--r--tests/qmlcamera/qmlcamera.desktop11
-rw-r--r--tests/qmlcamera/qmlcamera.pro (renamed from examples/qmlbarchart/qmlbarchart.pro)14
-rw-r--r--tests/qmlcamera/qmlcamera.qrc7
-rw-r--r--tests/qmlcamera/qmlcamera64.pngbin0 -> 3400 bytes
-rw-r--r--tests/qmlcamera/qmlcamera80.pngbin0 -> 4945 bytes
-rw-r--r--tests/qmlcamera/qmlcamera_harmattan.desktop11
-rw-r--r--tests/qmlcamera/qtquick2applicationviewer/qtquick2applicationviewer.cpp81
-rw-r--r--tests/qmlcamera/qtquick2applicationviewer/qtquick2applicationviewer.h33
-rw-r--r--tests/qmlcamera/qtquick2applicationviewer/qtquick2applicationviewer.pri (renamed from examples/qmlbarchart/qtquick2applicationviewer/qtquick2applicationviewer.pri)0
-rw-r--r--tests/scattertest/main.cpp (renamed from examples/scatterchart/main.cpp)21
-rw-r--r--tests/scattertest/scatterchart.cpp (renamed from examples/scatterchart/scatterchart.cpp)171
-rw-r--r--tests/scattertest/scatterchart.h (renamed from examples/scatterchart/scatterchart.h)11
-rw-r--r--tests/scattertest/scattertest.pro (renamed from examples/scatterchart/scatterchart.pro)4
-rw-r--r--tests/spectrum/3rdparty/fftreal/Array.h (renamed from examples/spectrum/3rdparty/fftreal/Array.h)0
-rw-r--r--tests/spectrum/3rdparty/fftreal/Array.hpp (renamed from examples/spectrum/3rdparty/fftreal/Array.hpp)0
-rw-r--r--tests/spectrum/3rdparty/fftreal/DynArray.h (renamed from examples/spectrum/3rdparty/fftreal/DynArray.h)0
-rw-r--r--tests/spectrum/3rdparty/fftreal/DynArray.hpp (renamed from examples/spectrum/3rdparty/fftreal/DynArray.hpp)0
-rw-r--r--tests/spectrum/3rdparty/fftreal/FFTReal.dsp (renamed from examples/spectrum/3rdparty/fftreal/FFTReal.dsp)0
-rw-r--r--tests/spectrum/3rdparty/fftreal/FFTReal.dsw (renamed from examples/spectrum/3rdparty/fftreal/FFTReal.dsw)0
-rw-r--r--tests/spectrum/3rdparty/fftreal/FFTReal.h (renamed from examples/spectrum/3rdparty/fftreal/FFTReal.h)0
-rw-r--r--tests/spectrum/3rdparty/fftreal/FFTReal.hpp (renamed from examples/spectrum/3rdparty/fftreal/FFTReal.hpp)0
-rw-r--r--tests/spectrum/3rdparty/fftreal/FFTRealFixLen.h (renamed from examples/spectrum/3rdparty/fftreal/FFTRealFixLen.h)0
-rw-r--r--tests/spectrum/3rdparty/fftreal/FFTRealFixLen.hpp (renamed from examples/spectrum/3rdparty/fftreal/FFTRealFixLen.hpp)0
-rw-r--r--tests/spectrum/3rdparty/fftreal/FFTRealFixLenParam.h (renamed from examples/spectrum/3rdparty/fftreal/FFTRealFixLenParam.h)0
-rw-r--r--tests/spectrum/3rdparty/fftreal/FFTRealPassDirect.h (renamed from examples/spectrum/3rdparty/fftreal/FFTRealPassDirect.h)0
-rw-r--r--tests/spectrum/3rdparty/fftreal/FFTRealPassDirect.hpp (renamed from examples/spectrum/3rdparty/fftreal/FFTRealPassDirect.hpp)0
-rw-r--r--tests/spectrum/3rdparty/fftreal/FFTRealPassInverse.h (renamed from examples/spectrum/3rdparty/fftreal/FFTRealPassInverse.h)0
-rw-r--r--tests/spectrum/3rdparty/fftreal/FFTRealPassInverse.hpp (renamed from examples/spectrum/3rdparty/fftreal/FFTRealPassInverse.hpp)0
-rw-r--r--tests/spectrum/3rdparty/fftreal/FFTRealSelect.h (renamed from examples/spectrum/3rdparty/fftreal/FFTRealSelect.h)0
-rw-r--r--tests/spectrum/3rdparty/fftreal/FFTRealSelect.hpp (renamed from examples/spectrum/3rdparty/fftreal/FFTRealSelect.hpp)0
-rw-r--r--tests/spectrum/3rdparty/fftreal/FFTRealUseTrigo.h (renamed from examples/spectrum/3rdparty/fftreal/FFTRealUseTrigo.h)0
-rw-r--r--tests/spectrum/3rdparty/fftreal/FFTRealUseTrigo.hpp (renamed from examples/spectrum/3rdparty/fftreal/FFTRealUseTrigo.hpp)0
-rw-r--r--tests/spectrum/3rdparty/fftreal/OscSinCos.h (renamed from examples/spectrum/3rdparty/fftreal/OscSinCos.h)0
-rw-r--r--tests/spectrum/3rdparty/fftreal/OscSinCos.hpp (renamed from examples/spectrum/3rdparty/fftreal/OscSinCos.hpp)0
-rw-r--r--tests/spectrum/3rdparty/fftreal/TestAccuracy.h (renamed from examples/spectrum/3rdparty/fftreal/TestAccuracy.h)0
-rw-r--r--tests/spectrum/3rdparty/fftreal/TestAccuracy.hpp (renamed from examples/spectrum/3rdparty/fftreal/TestAccuracy.hpp)0
-rw-r--r--tests/spectrum/3rdparty/fftreal/TestHelperFixLen.h (renamed from examples/spectrum/3rdparty/fftreal/TestHelperFixLen.h)0
-rw-r--r--tests/spectrum/3rdparty/fftreal/TestHelperFixLen.hpp (renamed from examples/spectrum/3rdparty/fftreal/TestHelperFixLen.hpp)0
-rw-r--r--tests/spectrum/3rdparty/fftreal/TestHelperNormal.h (renamed from examples/spectrum/3rdparty/fftreal/TestHelperNormal.h)0
-rw-r--r--tests/spectrum/3rdparty/fftreal/TestHelperNormal.hpp (renamed from examples/spectrum/3rdparty/fftreal/TestHelperNormal.hpp)0
-rw-r--r--tests/spectrum/3rdparty/fftreal/TestSpeed.h (renamed from examples/spectrum/3rdparty/fftreal/TestSpeed.h)0
-rw-r--r--tests/spectrum/3rdparty/fftreal/TestSpeed.hpp (renamed from examples/spectrum/3rdparty/fftreal/TestSpeed.hpp)0
-rw-r--r--tests/spectrum/3rdparty/fftreal/TestWhiteNoiseGen.h (renamed from examples/spectrum/3rdparty/fftreal/TestWhiteNoiseGen.h)0
-rw-r--r--tests/spectrum/3rdparty/fftreal/TestWhiteNoiseGen.hpp (renamed from examples/spectrum/3rdparty/fftreal/TestWhiteNoiseGen.hpp)0
-rw-r--r--tests/spectrum/3rdparty/fftreal/def.h (renamed from examples/spectrum/3rdparty/fftreal/def.h)0
-rw-r--r--tests/spectrum/3rdparty/fftreal/fftreal.pas (renamed from examples/spectrum/3rdparty/fftreal/fftreal.pas)0
-rw-r--r--tests/spectrum/3rdparty/fftreal/fftreal.pro (renamed from examples/spectrum/3rdparty/fftreal/fftreal.pro)0
-rw-r--r--tests/spectrum/3rdparty/fftreal/fftreal_wrapper.cpp (renamed from examples/spectrum/3rdparty/fftreal/fftreal_wrapper.cpp)2
-rw-r--r--tests/spectrum/3rdparty/fftreal/fftreal_wrapper.h (renamed from examples/spectrum/3rdparty/fftreal/fftreal_wrapper.h)2
-rw-r--r--tests/spectrum/3rdparty/fftreal/license.txt (renamed from examples/spectrum/3rdparty/fftreal/license.txt)0
-rw-r--r--tests/spectrum/3rdparty/fftreal/readme.txt (renamed from examples/spectrum/3rdparty/fftreal/readme.txt)0
-rw-r--r--tests/spectrum/3rdparty/fftreal/test.cpp (renamed from examples/spectrum/3rdparty/fftreal/test.cpp)0
-rw-r--r--tests/spectrum/3rdparty/fftreal/test_fnc.h (renamed from examples/spectrum/3rdparty/fftreal/test_fnc.h)0
-rw-r--r--tests/spectrum/3rdparty/fftreal/test_fnc.hpp (renamed from examples/spectrum/3rdparty/fftreal/test_fnc.hpp)0
-rw-r--r--tests/spectrum/3rdparty/fftreal/test_settings.h (renamed from examples/spectrum/3rdparty/fftreal/test_settings.h)0
-rw-r--r--tests/spectrum/3rdparty/fftreal/testapp.dpr (renamed from examples/spectrum/3rdparty/fftreal/testapp.dpr)0
-rw-r--r--tests/spectrum/README.txt (renamed from examples/spectrum/README.txt)0
-rw-r--r--tests/spectrum/spectrum.pri (renamed from examples/spectrum/spectrum.pri)0
-rw-r--r--tests/spectrum/spectrum.pro (renamed from examples/spectrum/spectrum.pro)3
-rw-r--r--tests/spectrum/spectrumapp/engine.cpp (renamed from examples/spectrum/spectrumapp/engine.cpp)8
-rw-r--r--tests/spectrum/spectrumapp/engine.h (renamed from examples/spectrum/spectrumapp/engine.h)2
-rw-r--r--tests/spectrum/spectrumapp/frequencyspectrum.cpp (renamed from examples/spectrum/spectrumapp/frequencyspectrum.cpp)2
-rw-r--r--tests/spectrum/spectrumapp/frequencyspectrum.h (renamed from examples/spectrum/spectrumapp/frequencyspectrum.h)2
-rw-r--r--tests/spectrum/spectrumapp/main.cpp (renamed from examples/spectrum/spectrumapp/main.cpp)44
-rw-r--r--tests/spectrum/spectrumapp/soundFiles/Rockhop.wav (renamed from examples/spectrum/spectrumapp/soundFiles/Rockhop.wav)bin1059308 -> 1059308 bytes
-rw-r--r--tests/spectrum/spectrumapp/soundFiles/futurebells_beat.wav (renamed from examples/spectrum/spectrumapp/soundFiles/futurebells_beat.wav)bin352084 -> 352084 bytes
-rw-r--r--tests/spectrum/spectrumapp/soundFiles/onclassical_demo_fiati-di-parma_thuille_terzo-tempo_sestetto_small-version.wav (renamed from examples/spectrum/spectrumapp/soundFiles/onclassical_demo_fiati-di-parma_thuille_terzo-tempo_sestetto_small-version.wav)bin1055502 -> 1055502 bytes
-rw-r--r--tests/spectrum/spectrumapp/spectrum.h (renamed from examples/spectrum/spectrumapp/spectrum.h)2
-rw-r--r--tests/spectrum/spectrumapp/spectrum.qrc (renamed from examples/spectrum/spectrumapp/spectrum.qrc)0
-rw-r--r--tests/spectrum/spectrumapp/spectrumanalyser.cpp (renamed from examples/spectrum/spectrumapp/spectrumanalyser.cpp)2
-rw-r--r--tests/spectrum/spectrumapp/spectrumanalyser.h (renamed from examples/spectrum/spectrumapp/spectrumanalyser.h)2
-rw-r--r--tests/spectrum/spectrumapp/spectrumapp.pro (renamed from examples/spectrum/spectrumapp/spectrumapp.pro)6
-rw-r--r--tests/spectrum/spectrumapp/utils.cpp (renamed from examples/spectrum/spectrumapp/utils.cpp)2
-rw-r--r--tests/spectrum/spectrumapp/utils.h (renamed from examples/spectrum/spectrumapp/utils.h)2
-rw-r--r--tests/spectrum/spectrumapp/wavfile.cpp (renamed from examples/spectrum/spectrumapp/wavfile.cpp)2
-rw-r--r--tests/spectrum/spectrumapp/wavfile.h (renamed from examples/spectrum/spectrumapp/wavfile.h)2
-rw-r--r--tests/surfacetest/Heightmap.pngbin0 -> 71764 bytes
-rw-r--r--tests/surfacetest/graphmodifier.cpp388
-rw-r--r--tests/surfacetest/graphmodifier.h95
-rw-r--r--tests/surfacetest/main.cpp256
-rw-r--r--tests/surfacetest/surfacetest.pro16
-rw-r--r--tests/surfacetest/surfacetest.qrc5
-rw-r--r--tests/tests.pri72
-rw-r--r--tests/tests.pro17
617 files changed, 73792 insertions, 24180 deletions
diff --git a/examples/audiolevels/audiolevels.cpp b/examples/audiolevels/audiolevels.cpp
new file mode 100644
index 00000000..e1788936
--- /dev/null
+++ b/examples/audiolevels/audiolevels.cpp
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 "audiolevelsiodevice.h"
+#include "audiolevels.h"
+
+#include <QtDataVisualization/qbardataproxy.h>
+#include <QtDataVisualization/q3dvalueaxis.h>
+#include <QtDataVisualization/q3dscene.h>
+#include <QtDataVisualization/q3dcamera.h>
+
+#include <QAudioDeviceInfo>
+#include <QAudioInput>
+
+QT_DATAVISUALIZATION_USE_NAMESPACE
+
+AudioLevels::AudioLevels(Q3DBars *graph, QObject *parent)
+ : QObject(parent),
+ m_graph(graph),
+ m_device(0),
+ m_audioInput(0)
+{
+ // Set up the graph
+ m_graph->setBarThickness(0.5);
+ m_graph->setBarSpacing(QSizeF(0.0, 1.0));
+ m_graph->setGridVisible(false);
+ m_graph->setBackgroundVisible(false);
+ m_graph->valueAxis()->setRange(0.0, 2.0);
+ m_graph->setShadowQuality(QDataVis::ShadowQualityNone);
+ m_graph->scene()->activeCamera()->setCameraPosition(-20.0, 10.0, 20);
+ m_graph->setTheme(QDataVis::ThemeIsabelle);
+ m_graph->setBarType(QDataVis::MeshStyleBars);
+
+ //! [0]
+ QAudioFormat formatAudio;
+ formatAudio.setSampleRate(8000);
+ formatAudio.setChannelCount(1);
+ formatAudio.setSampleSize(8);
+ formatAudio.setCodec("audio/pcm");
+ formatAudio.setByteOrder(QAudioFormat::LittleEndian);
+ formatAudio.setSampleType(QAudioFormat::UnSignedInt);
+
+ QAudioDeviceInfo inputDevices = QAudioDeviceInfo::defaultInputDevice();
+ m_audioInput = new QAudioInput(inputDevices, formatAudio, this);
+#ifdef Q_OS_MAC
+ // Mac seems to wait for entire buffer to fill before calling writeData, so use smaller buffer
+ m_audioInput->setBufferSize(256);
+#else
+ m_audioInput->setBufferSize(1024);
+#endif
+
+ m_device = new AudioLevelsIODevice(m_graph->activeDataProxy(), this);
+ m_device->open(QIODevice::WriteOnly);
+
+ m_audioInput->start(m_device);
+ //! [0]
+}
+
+AudioLevels::~AudioLevels()
+{
+ m_audioInput->stop();
+ m_device->close();
+}
diff --git a/examples/qmlbarchart/doc/src/qmlbarchart.qdoc b/examples/audiolevels/audiolevels.h
index becc5d8b..db1d8936 100644
--- a/examples/qmlbarchart/doc/src/qmlbarchart.qdoc
+++ b/examples/audiolevels/audiolevels.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -16,14 +16,30 @@
**
****************************************************************************/
-/*!
- \example qmlbarchart
- \title Qt Quick 2 Barchart Example
+#ifndef AUDIOLEVELS_H
+#define AUDIOLEVELS_H
- The Qt Quick 2 barchart example shows how to make a simple 3D bar chart using Q3DBars using Qt
- Quick 2.
+#include <QtDataVisualization/q3dbars.h>
- \image qmlbarchart-example.png
+QT_DATAVISUALIZATION_USE_NAMESPACE
- TODO
-*/
+class AudioLevelsIODevice;
+class QAudioInput;
+
+class AudioLevels : public QObject
+{
+ Q_OBJECT
+
+public:
+ AudioLevels(Q3DBars *graph, QObject *parent = 0);
+ ~AudioLevels();
+
+private:
+ //! [0]
+ Q3DBars *m_graph;
+ AudioLevelsIODevice *m_device;
+ QAudioInput *m_audioInput;
+ //! [0]
+};
+
+#endif
diff --git a/examples/audiolevels/audiolevels.pro b/examples/audiolevels/audiolevels.pro
new file mode 100644
index 00000000..7df4379b
--- /dev/null
+++ b/examples/audiolevels/audiolevels.pro
@@ -0,0 +1,20 @@
+!include( ../examples.pri ) {
+ error( "Couldn't find the examples.pri file!" )
+}
+
+TARGET = audiolevels
+
+QT += multimedia
+
+SOURCES += main.cpp \
+ audiolevels.cpp \
+ audiolevelsiodevice.cpp
+
+HEADERS += audiolevels.h \
+ audiolevelsiodevice.h
+
+INSTALLS += target
+
+OTHER_FILES += doc/src/* \
+ doc/images/*
+
diff --git a/examples/audiolevels/audiolevelsiodevice.cpp b/examples/audiolevels/audiolevelsiodevice.cpp
new file mode 100644
index 00000000..11cba5aa
--- /dev/null
+++ b/examples/audiolevels/audiolevelsiodevice.cpp
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 "audiolevelsiodevice.h"
+#include <QDebug>
+
+QT_DATAVISUALIZATION_USE_NAMESPACE
+
+//! [1]
+static const int resolution = 8;
+static const int rowSize = 800;
+static const int rowCount = 7; // Must be odd number
+static const int middleRow = rowCount / 2;
+//! [1]
+
+AudioLevelsIODevice::AudioLevelsIODevice(QBarDataProxy *proxy, QObject *parent)
+ : QIODevice(parent),
+ m_proxy(proxy),
+ m_array(new QBarDataArray)
+{
+ // We reuse the existing array for maximum performance, so construct the array here
+ //! [0]
+ m_array->reserve(rowCount);
+ for (int i = 0; i < rowCount; i++)
+ m_array->append(new QBarDataRow(rowSize));
+ //! [0]
+
+ qDebug() << "Total of" << (rowSize * rowCount) << "items in the array.";
+}
+
+// Implementation required for this pure virtual function
+qint64 AudioLevelsIODevice::readData(char *data, qint64 maxSize)
+{
+ Q_UNUSED(data)
+ Q_UNUSED(maxSize)
+ return -1;
+}
+
+//! [2]
+qint64 AudioLevelsIODevice::writeData(const char *data, qint64 maxSize)
+{
+ // The amount of new data available.
+ int newDataSize = maxSize / resolution;
+
+ // If we get more data than array size, we need to adjust the start index for new data.
+ int newDataStartIndex = qMax(0, (newDataSize - rowSize));
+
+ // Move the old data ahead in the rows (only do first half of rows + middle one now).
+ // If the amount of new data was larger than row size, skip copying.
+ if (!newDataStartIndex) {
+ for (int i = 0; i <= middleRow; i++) {
+ QBarDataItem *srcPos = m_array->at(i)->data();
+ QBarDataItem *dstPos = srcPos + newDataSize;
+ memmove(dstPos, srcPos, (rowSize - newDataSize) * sizeof(QBarDataItem));
+ }
+ }
+
+ // Insert data in reverse order, so that newest data is always at the front of the row.
+ int index = 0;
+ for (int i = newDataSize - 1; i >= newDataStartIndex; i--) {
+ // Add 0.01 to the value to avoid gaps in the graph (i.e. zero height bars).
+ qreal value = qreal(quint8(data[resolution * i]) - 128) / 2.0 + 0.01;
+ (*m_array->at(middleRow))[index].setValue(value);
+ // Insert a fractional value into front half of the rows.
+ for (int j = 1; j <= middleRow; j++) {
+ qreal fractionalValue = value / qreal(j + 1);
+ (*m_array->at(middleRow - j))[index].setValue(fractionalValue);
+ }
+ index++;
+ }
+
+ // Copy the front half of rows to the back half for symmetry.
+ index = 0;
+ for (int i = rowCount - 1; i > middleRow; i--) {
+ QBarDataItem *srcPos = m_array->at(index++)->data();
+ QBarDataItem *dstPos = m_array->at(i)->data();
+ memcpy(dstPos, srcPos, rowSize * sizeof(QBarDataItem));
+ }
+
+ // Reset the proxy array now that data has been updated to trigger a redraw.
+ m_proxy->resetArray(m_array);
+
+ return maxSize;
+}
+//! [2]
+
+
diff --git a/examples/audiolevels/audiolevelsiodevice.h b/examples/audiolevels/audiolevelsiodevice.h
new file mode 100644
index 00000000..8d665fe8
--- /dev/null
+++ b/examples/audiolevels/audiolevelsiodevice.h
@@ -0,0 +1,44 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 AUDIOLEVELSIODEVICE_H
+#define AUDIOLEVELSIODEVICE_H
+
+#include <QtDataVisualization/qbardataproxy.h>
+#include <QIODevice>
+
+QT_DATAVISUALIZATION_USE_NAMESPACE
+
+class AudioLevelsIODevice : public QIODevice
+{
+ Q_OBJECT
+public:
+ explicit AudioLevelsIODevice(QBarDataProxy *proxy, QObject *parent = 0);
+
+protected:
+ qint64 readData(char *data, qint64 maxSize);
+ qint64 writeData(const char *data, qint64 maxSize);
+
+private:
+ //! [0]
+ QBarDataProxy *m_proxy;
+ QBarDataArray *m_array;
+ //! [0]
+};
+
+#endif
diff --git a/examples/audiolevels/doc/images/audiolevels-example.png b/examples/audiolevels/doc/images/audiolevels-example.png
new file mode 100644
index 00000000..47c982d9
--- /dev/null
+++ b/examples/audiolevels/doc/images/audiolevels-example.png
Binary files differ
diff --git a/examples/audiolevels/doc/src/audiolevels.qdoc b/examples/audiolevels/doc/src/audiolevels.qdoc
new file mode 100644
index 00000000..3d392487
--- /dev/null
+++ b/examples/audiolevels/doc/src/audiolevels.qdoc
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 audiolevels
+ \title Audiolevels Example
+ \ingroup qtdatavisualization_examples
+ \brief Simple application showing real time audio data.
+
+ The audiolevels example shows how feed real-time dynamic data to a graph using Q3DBars.
+
+ This example reads the audio levels from a microphone and displays those levels
+ in a bar graph. To increase the load for demonstration purposes, and to make the
+ graph little fancier, slightly modified data is used to fill multiple rows.
+
+ \image audiolevels-example.png
+
+ The interesting stuff happens in AudioLevels and AudioLevelsIODevice classes, so we
+ concentrate on those and skip explaining the basic Q3DBars functionality - for that see
+ \l{Bars Example}.
+
+ AudioLevelsIODevice subclasses QIODevice and is given as input device for QAudioInput
+ class, so it receives microphone data.
+
+ In the header file for QAudioInput class we declare necessary members:
+
+ \snippet ../examples/audiolevels/audiolevels.h 0
+
+ And initialize the microphone listening in the source:
+
+ \snippet ../examples/audiolevels/audiolevels.cpp 0
+
+ In the header file for AudioLevelsIODevice class we store pointers to the data proxy and
+ also the data array we give to the proxy, because we reuse the same array to keep memory
+ reallocations to the minimum:
+
+ \snippet ../examples/audiolevels/audiolevelsiodevice.h 0
+
+ In the source file we define some static constants to define size of the data array and
+ the middle row index, as well as the resolution of the visualization. You may need to adjust
+ these values to get decent performance in low-end devices:
+
+ \snippet ../examples/audiolevels/audiolevelsiodevice.cpp 1
+
+ The \c resolution constant indicates the sample rate, e.g. value 8 means every eighth
+ byte from audio input is visualized. This is necessary to make the data readable, as it would
+ otherwise make the graph scroll too fast.
+
+ In the AudioLevelsIODevice class constructor we initialize the data array:
+
+ \snippet ../examples/audiolevels/audiolevelsiodevice.cpp 0
+
+ The AudioLevelsIODevice::writeData function is called whenever there is new audio data
+ available to be visualized. There we move the old data along the rows and insert new
+ data in the beginning of the rows:
+
+ \snippet ../examples/audiolevels/audiolevelsiodevice.cpp 2
+
+ We use a couple of techniques here to improve performance. First off, we reuse
+ the existing data array, as this allows us to avoid any extra memory allocations in our
+ application code. This also means the data array dimensions do not change, which further
+ improves efficiency in the bar graph renderer.
+ Secondly, since the rows are QVectors of QBarDataItems, which do not allocate any data that needs
+ deletion, we can utilize memmove and memcpy functions to quickly move and copy data around.
+
+ \note In the future versions of Qt Data Visualization, QBarDataItem might get extended so that
+ it does allocate some memory to store other optional bar properties besides the value.
+ In use cases where those optional properties are used, using memmove and memcpy would lead to
+ memory leaks, so use them with care.
+*/
diff --git a/examples/barchart/doc/src/barchart.qdoc b/examples/audiolevels/main.cpp
index 6c2c8760..9d16610c 100644
--- a/examples/barchart/doc/src/barchart.qdoc
+++ b/examples/audiolevels/main.cpp
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -16,13 +16,23 @@
**
****************************************************************************/
-/*!
- \example barchart
- \title Barchart Example
+#include "audiolevels.h"
- The barchart example shows how to make a simple 3D bar chart using Q3DBars.
+#include <QGuiApplication>
+#include <QAudio>
- \image barchart-example.png
+using namespace QtDataVisualization;
- TODO
-*/
+int main(int argc, char *argv[])
+{
+ QGuiApplication app(argc, argv);
+
+ Q3DBars window;
+ window.resize(1024, 768);
+ window.setTitle("Qt Data Visualization - Microphone audio levels visualizer");
+ window.show();
+
+ AudioLevels audioLevels(&window);
+
+ return app.exec();
+}
diff --git a/examples/barchart/doc/images/barchart-example.png b/examples/barchart/doc/images/barchart-example.png
deleted file mode 100644
index 0f321c95..00000000
--- a/examples/barchart/doc/images/barchart-example.png
+++ /dev/null
Binary files differ
diff --git a/examples/barchart/main.cpp b/examples/barchart/main.cpp
deleted file mode 100644
index 77230b5d..00000000
--- a/examples/barchart/main.cpp
+++ /dev/null
@@ -1,308 +0,0 @@
-/****************************************************************************
-**
-** 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 <QtDataVis3D/q3dbars.h>
-#include <QtDataVis3D/qcategoryaxis.h>
-#include <QtDataVis3D/qitemmodelbardataproxy.h>
-#include <QtDataVis3D/qvalueaxis.h>
-
-#include <QApplication>
-#include <QVBoxLayout>
-#include <QTableWidget>
-#include <QScreen>
-#include <QTimer>
-#include <QFont>
-#include <QDebug>
-
-//#define CYCLE_THROUGH_STYLES
-//#define CYCLE_THROUGH_PRESET_CAMERAS
-//#define CYCLE_THROUGH_THEMES
-#define USE_STATIC_DATA
-
-using namespace QtDataVis3D;
-
-class ChartDataGenerator : public QObject
-{
-public:
- explicit ChartDataGenerator(Q3DBars *barchart, QTableWidget *tableWidget);
- ~ChartDataGenerator();
-
- void setupModel();
- void addRow();
- void changeStyle();
- void changePresetCamera();
- void changeTheme();
- void start();
-
-private:
- Q3DBars *m_chart;
- QTimer *m_dataTimer;
- QTimer *m_styleTimer;
- QTimer *m_presetTimer;
- QTimer *m_themeTimer;
- int m_columnCount;
- int m_rowCount;
- QTableWidget *m_tableWidget; // not owned
-};
-
-ChartDataGenerator::ChartDataGenerator(Q3DBars *barchart, QTableWidget *tableWidget)
- : m_chart(barchart),
- m_dataTimer(0),
- m_styleTimer(0),
- m_presetTimer(0),
- m_themeTimer(0),
- 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
- m_chart->setBarSpecs(QSizeF(1.0f, 1.0f), QSizeF(0.2f, 0.2f), true);
-
-#ifndef USE_STATIC_DATA
- // Set up sample space; make it as deep as it's wide
- 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(QDataVis::Pyramids, false);
-#endif
-
-#ifndef USE_STATIC_DATA
- // Set selection mode to full
- m_chart->setSelectionMode(QDataVis::ModeItemRowAndColumn);
-#else
- // Set selection mode to zoom row
- m_chart->setSelectionMode(QDataVis::ModeZoomRow);
- m_chart->setFont(QFont("Courier", 25));
-#endif
-
-#ifndef CYCLE_THROUGH_THEMES
- // Set bar colors
- m_chart->setBarColor(QColor(Qt::gray), QColor(Qt::red), QColor(Qt::darkBlue));
-#else
- m_chart->setLabelTransparency(QDataVis::TransparencyNone);
-#endif
-
- // Set preset camera position
- m_chart->setCameraPreset(QDataVis::PresetFront);
-}
-
-ChartDataGenerator::~ChartDataGenerator()
-{
- if (m_dataTimer) {
- m_dataTimer->stop();
- delete m_dataTimer;
- }
- if (m_styleTimer) {
- m_styleTimer->stop();
- delete m_styleTimer;
- }
- if (m_presetTimer) {
- m_presetTimer->stop();
- delete m_presetTimer;
- }
- if (m_themeTimer) {
- m_themeTimer->stop();
- delete m_themeTimer;
- }
- delete m_chart;
-}
-
-void ChartDataGenerator::start()
-{
-#ifndef USE_STATIC_DATA
- m_dataTimer = new QTimer();
- m_dataTimer->setTimerType(Qt::CoarseTimer);
- m_dataTimer->setInterval(20);
- QObject::connect(m_dataTimer, &QTimer::timeout, this, &ChartDataGenerator::addRow);
- m_dataTimer->start(20);
-#else
- setupModel();
-#endif
-
-#ifdef CYCLE_THROUGH_STYLES
- // Change bar style every 10 seconds
- m_styleTimer = new QTimer();
- m_styleTimer->setTimerType(Qt::CoarseTimer);
- m_styleTimer->setInterval(10000);
- QObject::connect(m_styleTimer, &QTimer::timeout, this, &ChartDataGenerator::changeStyle);
- m_styleTimer->start(10000);
-#endif
-
-#ifdef CYCLE_THROUGH_PRESET_CAMERAS
- // Change preset camera every 5 seconds
- m_presetTimer = new QTimer();
- m_presetTimer->setTimerType(Qt::CoarseTimer);
- m_presetTimer->setInterval(5000);
- QObject::connect(m_presetTimer, &QTimer::timeout, this,
- &ChartDataGenerator::changePresetCamera);
- m_presetTimer->start(5000);
-#endif
-
-#ifdef CYCLE_THROUGH_THEMES
- // Change theme every 2 seconds
- m_themeTimer = new QTimer();
- m_themeTimer->setTimerType(Qt::CoarseTimer);
- m_themeTimer->setInterval(3000);//2000);
- QObject::connect(m_themeTimer, &QTimer::timeout, this, &ChartDataGenerator::changeTheme);
- m_themeTimer->start(3000);//2000);
-#endif
-}
-
-void ChartDataGenerator::setupModel()
-{
- // Set up row and column names
- QStringList days;
- days << "Monday" << "Tuesday" << "Wednesday" << "Thursday" << "Friday" << "Saturday" << "Sunday";
- 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, 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, 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
-
- // Add labels
- 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);
-
- for (int week = 0; week < weeks.size(); week++) {
- for (int day = 0; day < days.size(); day++) {
- QModelIndex index = m_tableWidget->model()->index(week, day);
- m_tableWidget->model()->setData(index, hours[week][day]);
- }
- }
-
- // Set up sample space based on prepared data
- m_chart->setupSampleSpace(weeks.size(), days.size());
-}
-
-void ChartDataGenerator::addRow()
-{
- 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()
-{
- static int model = 0;
- switch (model) {
- case 0:
- m_chart->setBarType(QDataVis::Cylinders, false);
- break;
- case 1:
- m_chart->setBarType(QDataVis::Cylinders, true);
- break;
- case 2:
- m_chart->setBarType(QDataVis::Cones, false);
- break;
- case 3:
- m_chart->setBarType(QDataVis::Cones, true);
- break;
- case 4:
- m_chart->setBarType(QDataVis::Bars, false);
- break;
- case 5:
- m_chart->setBarType(QDataVis::Bars, true);
- break;
- case 6:
- m_chart->setBarType(QDataVis::Pyramids, false);
- break;
- case 7:
- m_chart->setBarType(QDataVis::Pyramids, true);
- break;
- }
- model++;
- if (model > 7)
- model = 0;
-}
-
-void ChartDataGenerator::changePresetCamera()
-{
- static int preset = 0;
-
- m_chart->setCameraPreset((QDataVis::CameraPreset)preset);
-
- if (++preset > (int)QDataVis::PresetDirectlyAboveCCW45)
- preset = 0;
-}
-
-void ChartDataGenerator::changeTheme()
-{
- static int theme = 0;
-
- m_chart->setTheme((QDataVis::ColorTheme)theme);
-
- if (++theme > (int)QDataVis::ThemeLight)
- theme = 0;
-}
-
-int main(int argc, char **argv)
-{
- QApplication app(argc, argv);
-
- QWidget *widget = new QWidget;
- QVBoxLayout *layout = new QVBoxLayout(widget);
-
- Q3DBars *chart = new Q3DBars();
- 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("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/mapdata/mapdata.pro b/examples/bars/bars.pro
index 091fdc7c..e4e2c5fa 100644
--- a/examples/mapdata/mapdata.pro
+++ b/examples/bars/bars.pro
@@ -2,12 +2,12 @@
error( "Couldn't find the examples.pri file!" )
}
-SOURCES += main.cpp mapdata.cpp
-HEADERS += mapdata.h
+SOURCES += main.cpp graphmodifier.cpp
+HEADERS += graphmodifier.h
QT += widgets
INSTALLS += target
-RESOURCES += \
- mapdata.qrc
+OTHER_FILES += doc/src/* \
+ doc/images/*
diff --git a/examples/bars/doc/images/bars-example.png b/examples/bars/doc/images/bars-example.png
new file mode 100644
index 00000000..fb30a944
--- /dev/null
+++ b/examples/bars/doc/images/bars-example.png
Binary files differ
diff --git a/examples/bars/doc/src/bars.qdoc b/examples/bars/doc/src/bars.qdoc
new file mode 100644
index 00000000..379aa871
--- /dev/null
+++ b/examples/bars/doc/src/bars.qdoc
@@ -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 QtDataVisualization 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 bars
+ \title Bars Example
+ \ingroup qtdatavisualization_examples
+ \brief Using Q3DBars in a widget application.
+
+ The bars example shows how to make a 3D bar graph using Q3DBars and combining the use of
+ widgets for adjusting several adjustable qualities. The example shows how to:
+
+ \list
+ \li Create an application with Q3DBars and some widgets
+ \li Use QBarDataProxy to set data to the graph
+ \li Adjust some graph properties using widget controls
+ \endlist
+
+ It also demonstrates how having negative bar values affects the graph.
+
+ \image bars-example.png
+
+ \section1 Creating the application
+
+ First, in main.cpp, we create a QApplication, instantiate Q3DBars and a window container
+ for it:
+
+ \snippet ../examples/bars/main.cpp 0
+
+ The call to QWidget::createWindowContainer is required, as all data visualization types
+ (Q3DBars, Q3DScatter, Q3DSurface) inherit QWindow. Any class inheriting QWindow cannot be used
+ as a widget any other way.
+
+ Then we'll create horizontal and vertical layouts. We'll add the graph and the vertical
+ layout into the horizontal one:
+
+ \snippet ../examples/bars/main.cpp 1
+
+ We're not using the vertical layout for anything yet, but we'll get back to it in
+ \l {Using widgets to control the graph}
+
+ Next, let's create another class to handle the data addition and other interaction with the
+ graph. Let's call it GraphModifier (See \l {Setting up the graph} and
+ \l {Adding data to the graph} for details):
+
+ \snippet ../examples/bars/main.cpp 2
+
+ The application main is done and we can show the graph and start the event loop:
+
+ \snippet ../examples/bars/main.cpp 3
+
+ \section1 Setting up the graph
+
+ Let's set up the graph in the constructor of the GraphModifier class we instantiated in the
+ application main:
+
+ \snippet ../examples/bars/graphmodifier.cpp 0
+
+ Let's take a closer look at parts of the code.
+
+ First we're creating the axes and the proxy into member variables to support changing them
+ easily later on, if we want to:
+
+ \snippet ../examples/bars/graphmodifier.cpp 1
+
+ Then we're setting some of the visual qualities for the graph:
+
+ \snippet ../examples/bars/graphmodifier.cpp 2
+
+ We're also setting up the axes and adding them to the graph. Notice that we're not setting them
+ active yet:
+
+ \snippet ../examples/bars/graphmodifier.cpp 3
+
+ And add the proxy. Note that we're not setting it active yet, but just adding it:
+
+ \snippet ../examples/bars/graphmodifier.cpp 4
+
+ That concludes setting up the graph.
+
+ \section1 Adding data to the graph
+
+ At the end of the constructor there's a call:
+
+ \code resetTemperatureData(); \endcode
+
+ The method is used to add data to the proxy:
+
+ \snippet ../examples/bars/graphmodifier.cpp 5
+
+ Now the data is in the proxy, but not in the graph. We have not set the proxy active yet.
+
+ In application main, we called \c {modifier->start()} after constructing all the necessary
+ objects. This is what is done in it:
+
+ \snippet ../examples/bars/graphmodifier.cpp 6
+
+ Finally we set the proxy and the axes active. Now our graph has the data and is ready to be
+ used.
+
+ \section1 Using widgets to control the graph
+
+ There isn't much interaction yet, so let's continue by adding some widgets back in the
+ application main. Let's just focus on two:
+
+ \snippet ../examples/bars/main.cpp 4
+
+ We can use these to rotate the graph using slider widgets instead of just using the mouse or
+ touch.
+
+ Let's add them to the vertical layout we created earlier:
+
+ \snippet ../examples/bars/main.cpp 5
+
+ Then we'll connect them to methods in GraphModifier:
+
+ \snippet ../examples/bars/main.cpp 6
+
+ Here are the methods in GraphModifier the signals were connected to:
+
+ \snippet ../examples/bars/graphmodifier.cpp 7
+
+ Now these two sliders can be used to rotate the graph.
+
+ And so we have an application in which we can control:
+
+ \list
+ \li Graph rotation
+ \li Label style
+ \li Camera preset
+ \li Background visibility
+ \li Grid visibility
+ \li Bar shading smoothness
+ \li Bar style
+ \li Selection mode
+ \li Theme
+ \li Shadow quality
+ \li Font
+ \li Font size
+ \endlist
+
+ \section1 Example contents
+
+*/
diff --git a/examples/bars/graphmodifier.cpp b/examples/bars/graphmodifier.cpp
new file mode 100644
index 00000000..0b33bde0
--- /dev/null
+++ b/examples/bars/graphmodifier.cpp
@@ -0,0 +1,229 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 "graphmodifier.h"
+#include <QtDataVisualization/q3dcategoryaxis.h>
+#include <QtDataVisualization/q3dvalueaxis.h>
+#include <QtDataVisualization/qbardataproxy.h>
+#include <QtDataVisualization/q3dscene.h>
+#include <QtDataVisualization/q3dcamera.h>
+#include <QTime>
+
+QT_DATAVISUALIZATION_USE_NAMESPACE
+
+const QString celsiusString = QString(QChar(0xB0)) + "C";
+
+//! [0]
+GraphModifier::GraphModifier(Q3DBars *bargraph)
+ : m_graph(bargraph),
+ m_xRotation(0.0),
+ m_yRotation(0.0),
+ m_fontSize(30),
+ m_segments(4),
+ m_subSegments(3),
+ m_minval(-20.0),
+ m_maxval(20.0),
+ //! [1]
+ m_temperatureAxis(new Q3DValueAxis),
+ m_yearAxis(new Q3DCategoryAxis),
+ m_monthAxis(new Q3DCategoryAxis),
+ m_temperatureData(new QBarDataProxy),
+ //! [1]
+ m_style(QDataVis::MeshStyleBevelBars),
+ m_smooth(false)
+{
+ //! [2]
+ m_graph->setBackgroundVisible(false);
+ m_graph->setShadowQuality(QDataVis::ShadowQualitySoftMedium);
+ m_graph->setFont(QFont("Times New Roman", m_fontSize));
+ m_graph->setLabelStyle(QDataVis::LabelStyleFromTheme);
+ //! [2]
+
+ m_months << "January" << "February" << "March" << "April" << "May" << "June" << "July" << "August" << "September" << "October" << "November" << "December";
+ m_years << "2006" << "2007" << "2008" << "2009" << "2010" << "2011" << "2012";
+
+ //! [3]
+ m_temperatureAxis->setTitle("Average temperature");
+ m_temperatureAxis->setSegmentCount(m_segments);
+ m_temperatureAxis->setSubSegmentCount(m_subSegments);
+ m_temperatureAxis->setRange(m_minval, m_maxval);
+ m_temperatureAxis->setLabelFormat(QString(QStringLiteral("%d ") + celsiusString));
+
+ m_yearAxis->setTitle("Year");
+ m_monthAxis->setTitle("Month");
+
+ m_graph->addAxis(m_temperatureAxis);
+ m_graph->addAxis(m_yearAxis);
+ m_graph->addAxis(m_monthAxis);
+ //! [3]
+
+ m_temperatureData->setItemLabelFormat(QStringLiteral("@valueTitle for @colLabel @rowLabel: @valueLabel"));
+
+ //! [4]
+ m_graph->addDataProxy(m_temperatureData);
+ //! [4]
+
+ resetTemperatureData();
+}
+//! [0]
+
+GraphModifier::~GraphModifier()
+{
+ delete m_graph;
+}
+
+void GraphModifier::start()
+{
+ //! [6]
+ m_graph->setActiveDataProxy(m_temperatureData);
+
+ m_graph->setValueAxis(m_temperatureAxis);
+ m_graph->setRowAxis(m_yearAxis);
+ m_graph->setColumnAxis(m_monthAxis);
+ //! [6]
+}
+
+void GraphModifier::resetTemperatureData()
+{
+ //! [5]
+ // Set up data
+ static const qreal temp[7][12] = {
+ {-6.7, -11.7, -9.7, 3.3, 9.2, 14.0, 16.3, 17.8, 10.2, 2.1, -2.6, -0.3}, // 2006
+ {-6.8, -13.3, 0.2, 1.5, 7.9, 13.4, 16.1, 15.5, 8.2, 5.4, -2.6, -0.8}, // 2007
+ {-4.2, -4.0, -4.6, 1.9, 7.3, 12.5, 15.0, 12.8, 7.6, 5.1, -0.9, -1.3}, // 2008
+ {-7.8, -8.8, -4.2, 0.7, 9.3, 13.2, 15.8, 15.5, 11.2, 0.6, 0.7, -8.4}, // 2009
+ {-14.4, -12.1, -7.0, 2.3, 11.0, 12.6, 18.8, 13.8, 9.4, 3.9, -5.6, -13.0}, // 2010
+ {-9.0, -15.2, -3.8, 2.6, 8.3, 15.9, 18.6, 14.9, 11.1, 5.3, 1.8, -0.2}, // 2011
+ {-8.7, -11.3, -2.3, 0.4, 7.5, 12.2, 16.4, 14.1, 9.2, 3.1, 0.3, -12.1} // 2012
+ };
+
+ // Create data array
+ QBarDataArray *dataSet = new QBarDataArray;
+ QBarDataRow *dataRow;
+
+ dataSet->reserve(m_years.size());
+ for (int year = 0; year < m_years.size(); year++) {
+ // Create a data row
+ dataRow = new QBarDataRow(m_months.size());
+ for (int month = 0; month < m_months.size(); month++) {
+ // Add data to the row
+ (*dataRow)[month].setValue(temp[year][month]);
+ }
+ // Add the row to the set
+ dataSet->append(dataRow);
+ }
+
+ // Add data to the graph (the graph assumes ownership of it)
+ m_temperatureData->resetArray(dataSet, m_years, m_months);
+ //! [5]
+}
+
+void GraphModifier::changeStyle(int style)
+{
+ m_style = QDataVis::MeshStyle(style);
+ m_graph->setBarType(m_style, m_smooth);
+}
+
+void GraphModifier::changePresetCamera()
+{
+ static int preset = QDataVis::CameraPresetFrontLow;
+
+ m_graph->scene()->activeCamera()->setCameraPreset((QDataVis::CameraPreset)preset);
+
+ if (++preset > QDataVis::CameraPresetDirectlyBelow)
+ preset = QDataVis::CameraPresetFrontLow;
+}
+
+void GraphModifier::changeTheme(int theme)
+{
+ m_graph->setTheme((QDataVis::Theme)theme);
+}
+
+void GraphModifier::changeLabelStyle()
+{
+ static int style = QDataVis::LabelStyleFromTheme;
+
+ m_graph->setLabelStyle((QDataVis::LabelStyle)style);
+
+ if (++style > QDataVis::LabelStyleTransparent)
+ style = QDataVis::LabelStyleOpaque;
+}
+
+void GraphModifier::changeSelectionMode(int selectionMode)
+{
+ m_graph->setSelectionMode((QDataVis::SelectionMode)selectionMode);
+}
+
+void GraphModifier::changeFont(const QFont &font)
+{
+ QFont newFont = font;
+ newFont.setPointSize(m_fontSize);
+ m_graph->setFont(newFont);
+}
+
+void GraphModifier::changeFontSize(int fontsize)
+{
+ m_fontSize = fontsize;
+ QFont font = m_graph->font();
+ font.setPointSize(m_fontSize);
+ m_graph->setFont(font);
+}
+
+void GraphModifier::shadowQualityUpdatedByVisual(QDataVis::ShadowQuality sq)
+{
+ int quality = int(sq);
+ // Updates the UI component to show correct shadow quality
+ emit shadowQualityChanged(quality);
+}
+
+void GraphModifier::changeShadowQuality(int quality)
+{
+ QDataVis::ShadowQuality sq = QDataVis::ShadowQuality(quality);
+ m_graph->setShadowQuality(sq);
+ emit shadowQualityChanged(quality);
+}
+
+//! [7]
+void GraphModifier::rotateX(int rotation)
+{
+ m_xRotation = rotation;
+ m_graph->scene()->activeCamera()->setCameraPosition(m_xRotation, m_yRotation);
+}
+
+void GraphModifier::rotateY(int rotation)
+{
+ m_yRotation = rotation;
+ m_graph->scene()->activeCamera()->setCameraPosition(m_xRotation, m_yRotation);
+}
+//! [7]
+
+void GraphModifier::setBackgroundEnabled(int enabled)
+{
+ m_graph->setBackgroundVisible((bool)enabled);
+}
+
+void GraphModifier::setGridEnabled(int enabled)
+{
+ m_graph->setGridVisible((bool)enabled);
+}
+
+void GraphModifier::setSmoothBars(int smooth)
+{
+ m_smooth = bool(smooth);
+ m_graph->setBarType(m_style, m_smooth);
+}
diff --git a/examples/bars/graphmodifier.h b/examples/bars/graphmodifier.h
new file mode 100644
index 00000000..2e18ffd2
--- /dev/null
+++ b/examples/bars/graphmodifier.h
@@ -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 QtDataVisualization 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 GRAPHMODIFIER_H
+#define GRAPHMODIFIER_H
+
+#include <QtDataVisualization/q3dbars.h>
+
+#include <QFont>
+#include <QDebug>
+#include <QStringList>
+#include <QPointer>
+
+using namespace QtDataVisualization;
+
+class GraphModifier : public QObject
+{
+ Q_OBJECT
+public:
+ explicit GraphModifier(Q3DBars *bargraph);
+ ~GraphModifier();
+
+ void resetTemperatureData();
+ void changePresetCamera();
+ void changeLabelStyle();
+ void changeFont(const QFont &font);
+ void changeFontSize(int fontsize);
+ void rotateX(int rotation);
+ void rotateY(int rotation);
+ void setBackgroundEnabled(int enabled);
+ void setGridEnabled(int enabled);
+ void setSmoothBars(int smooth);
+ void start();
+
+public slots:
+ void changeStyle(int style);
+ void changeSelectionMode(int selectionMode);
+ void changeTheme(int theme);
+ void changeShadowQuality(int quality);
+ void shadowQualityUpdatedByVisual(QDataVis::ShadowQuality shadowQuality);
+
+signals:
+ void shadowQualityChanged(int quality);
+
+private:
+ Q3DBars *m_graph;
+ qreal m_xRotation;
+ qreal m_yRotation;
+ int m_fontSize;
+ int m_segments;
+ int m_subSegments;
+ qreal m_minval;
+ qreal m_maxval;
+ QStringList m_months;
+ QStringList m_years;
+ Q3DValueAxis *m_temperatureAxis;
+ Q3DCategoryAxis *m_yearAxis;
+ Q3DCategoryAxis *m_monthAxis;
+ QBarDataProxy *m_temperatureData;
+ QDataVis::MeshStyle m_style;
+ bool m_smooth;
+};
+
+#endif
diff --git a/examples/bars/main.cpp b/examples/bars/main.cpp
new file mode 100644
index 00000000..158244b4
--- /dev/null
+++ b/examples/bars/main.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 QtDataVisualization 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 "graphmodifier.h"
+
+#include <QApplication>
+#include <QWidget>
+#include <QHBoxLayout>
+#include <QVBoxLayout>
+#include <QPushButton>
+#include <QCheckBox>
+#include <QSlider>
+#include <QFontComboBox>
+#include <QLabel>
+#include <QScreen>
+#include <QFontDatabase>
+
+int main(int argc, char **argv)
+{
+ //! [0]
+ QApplication app(argc, argv);
+ Q3DBars *widgetgraph = new Q3DBars();
+ QWidget *container = QWidget::createWindowContainer(widgetgraph);
+ //! [0]
+
+ QSize screenSize = widgetgraph->screen()->size();
+ container->setMinimumSize(QSize(screenSize.width() / 2, screenSize.height() / 1.5));
+ container->setMaximumSize(screenSize);
+ container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ container->setFocusPolicy(Qt::StrongFocus);
+
+ //! [1]
+ QWidget *widget = new QWidget;
+ QHBoxLayout *hLayout = new QHBoxLayout(widget);
+ QVBoxLayout *vLayout = new QVBoxLayout();
+ hLayout->addWidget(container, 1);
+ hLayout->addLayout(vLayout);
+ //! [1]
+
+ widget->setWindowTitle(QStringLiteral("Average temperatures in Oulu, Finland (2006-2012)"));
+
+ QComboBox *themeList = new QComboBox(widget);
+ themeList->addItem(QStringLiteral("Qt"));
+ themeList->addItem(QStringLiteral("Primary Colors"));
+ themeList->addItem(QStringLiteral("Digia"));
+ themeList->addItem(QStringLiteral("Stone Moss"));
+ themeList->addItem(QStringLiteral("Army Blue"));
+ themeList->addItem(QStringLiteral("Retro"));
+ themeList->addItem(QStringLiteral("Ebony"));
+ themeList->addItem(QStringLiteral("Isabelle"));
+ themeList->setCurrentIndex(0);
+
+ QPushButton *labelButton = new QPushButton(widget);
+ labelButton->setText(QStringLiteral("Change label style"));
+
+ QCheckBox *smoothCheckBox = new QCheckBox(widget);
+ smoothCheckBox->setText(QStringLiteral("Smooth bars"));
+ smoothCheckBox->setChecked(false);
+
+ QComboBox *barStyleList = new QComboBox(widget);
+ barStyleList->addItem(QStringLiteral("Bars"));
+ barStyleList->addItem(QStringLiteral("Pyramids"));
+ barStyleList->addItem(QStringLiteral("Cones"));
+ barStyleList->addItem(QStringLiteral("Cylinders"));
+ barStyleList->addItem(QStringLiteral("Beveled Bars"));
+ barStyleList->setCurrentIndex(4);
+
+ QPushButton *cameraButton = new QPushButton(widget);
+ cameraButton->setText(QStringLiteral("Change camera preset"));
+
+ QComboBox *selectionModeList = new QComboBox(widget);
+ selectionModeList->addItem(QStringLiteral("None"));
+ selectionModeList->addItem(QStringLiteral("Bar"));
+ selectionModeList->addItem(QStringLiteral("Bar and Row"));
+ selectionModeList->addItem(QStringLiteral("Bar and Column"));
+ selectionModeList->addItem(QStringLiteral("Bar, Row and Column"));
+ selectionModeList->addItem(QStringLiteral("Slice into Row"));
+ selectionModeList->addItem(QStringLiteral("Slice into Column"));
+ selectionModeList->setCurrentIndex(1);
+
+ QCheckBox *backgroundCheckBox = new QCheckBox(widget);
+ backgroundCheckBox->setText(QStringLiteral("Show background"));
+ backgroundCheckBox->setChecked(false);
+
+ QCheckBox *gridCheckBox = new QCheckBox(widget);
+ gridCheckBox->setText(QStringLiteral("Show grid"));
+ gridCheckBox->setChecked(true);
+
+ //! [4]
+ QSlider *rotationSliderX = new QSlider(Qt::Horizontal, widget);
+ rotationSliderX->setTickInterval(30);
+ rotationSliderX->setTickPosition(QSlider::TicksBelow);
+ rotationSliderX->setMinimum(-180);
+ rotationSliderX->setValue(0);
+ rotationSliderX->setMaximum(180);
+ QSlider *rotationSliderY = new QSlider(Qt::Horizontal, widget);
+ rotationSliderY->setTickInterval(15);
+ rotationSliderY->setTickPosition(QSlider::TicksAbove);
+ rotationSliderY->setMinimum(-90);
+ rotationSliderY->setValue(0);
+ rotationSliderY->setMaximum(90);
+ //! [4]
+
+ QSlider *fontSizeSlider = new QSlider(Qt::Horizontal, widget);
+ fontSizeSlider->setTickInterval(10);
+ fontSizeSlider->setTickPosition(QSlider::TicksBelow);
+ fontSizeSlider->setMinimum(1);
+ fontSizeSlider->setValue(30);
+ fontSizeSlider->setMaximum(100);
+
+ QFontComboBox *fontList = new QFontComboBox(widget);
+ fontList->setCurrentFont(QFont("Times New Roman"));
+
+ QComboBox *shadowQuality = new QComboBox(widget);
+ shadowQuality->addItem(QStringLiteral("None"));
+ shadowQuality->addItem(QStringLiteral("Low"));
+ shadowQuality->addItem(QStringLiteral("Medium"));
+ shadowQuality->addItem(QStringLiteral("High"));
+ shadowQuality->addItem(QStringLiteral("Low Soft"));
+ shadowQuality->addItem(QStringLiteral("Medium Soft"));
+ shadowQuality->addItem(QStringLiteral("High Soft"));
+ shadowQuality->setCurrentIndex(5);
+
+ //! [5]
+ vLayout->addWidget(new QLabel(QStringLiteral("Rotate horizontally")));
+ vLayout->addWidget(rotationSliderX, 0, Qt::AlignTop);
+ vLayout->addWidget(new QLabel(QStringLiteral("Rotate vertically")));
+ vLayout->addWidget(rotationSliderY, 0, Qt::AlignTop);
+ //! [5]
+ vLayout->addWidget(labelButton, 0, Qt::AlignTop);
+ vLayout->addWidget(cameraButton, 0, Qt::AlignTop);
+ vLayout->addWidget(backgroundCheckBox);
+ vLayout->addWidget(gridCheckBox);
+ vLayout->addWidget(smoothCheckBox, 0, Qt::AlignTop);
+ vLayout->addWidget(new QLabel(QStringLiteral("Change bar style")));
+ vLayout->addWidget(barStyleList);
+ vLayout->addWidget(new QLabel(QStringLiteral("Change selection mode")));
+ vLayout->addWidget(selectionModeList);
+ vLayout->addWidget(new QLabel(QStringLiteral("Change theme")));
+ vLayout->addWidget(themeList);
+ 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);
+
+ //! [2]
+ GraphModifier *modifier = new GraphModifier(widgetgraph);
+ //! [2]
+
+ //! [6]
+ QObject::connect(rotationSliderX, &QSlider::valueChanged, modifier, &GraphModifier::rotateX);
+ QObject::connect(rotationSliderY, &QSlider::valueChanged, modifier, &GraphModifier::rotateY);
+ //! [6]
+
+ QObject::connect(labelButton, &QPushButton::clicked, modifier,
+ &GraphModifier::changeLabelStyle);
+ QObject::connect(cameraButton, &QPushButton::clicked, modifier,
+ &GraphModifier::changePresetCamera);
+
+ QObject::connect(backgroundCheckBox, &QCheckBox::stateChanged, modifier,
+ &GraphModifier::setBackgroundEnabled);
+ QObject::connect(gridCheckBox, &QCheckBox::stateChanged, modifier,
+ &GraphModifier::setGridEnabled);
+ QObject::connect(smoothCheckBox, &QCheckBox::stateChanged, modifier,
+ &GraphModifier::setSmoothBars);
+
+ QObject::connect(barStyleList, SIGNAL(currentIndexChanged(int)), modifier,
+ SLOT(changeStyle(int)));
+
+ QObject::connect(selectionModeList, SIGNAL(currentIndexChanged(int)), modifier,
+ SLOT(changeSelectionMode(int)));
+
+ QObject::connect(themeList, SIGNAL(currentIndexChanged(int)), modifier,
+ SLOT(changeTheme(int)));
+
+ QObject::connect(shadowQuality, SIGNAL(currentIndexChanged(int)), modifier,
+ SLOT(changeShadowQuality(int)));
+
+ QObject::connect(modifier, &GraphModifier::shadowQualityChanged, shadowQuality,
+ &QComboBox::setCurrentIndex);
+ QObject::connect(widgetgraph, &Q3DBars::shadowQualityChanged, modifier,
+ &GraphModifier::shadowQualityUpdatedByVisual);
+
+ QObject::connect(fontSizeSlider, &QSlider::valueChanged, modifier,
+ &GraphModifier::changeFontSize);
+ QObject::connect(fontList, &QFontComboBox::currentFontChanged, modifier,
+ &GraphModifier::changeFont);
+
+ //! [3]
+ widget->show();
+ modifier->start();
+ return app.exec();
+ //! [3]
+}
diff --git a/examples/rainfall/rainfall.pro b/examples/customproxy/customproxy.pro
index af7f963b..2b764a41 100644
--- a/examples/rainfall/rainfall.pro
+++ b/examples/customproxy/customproxy.pro
@@ -3,21 +3,22 @@
}
SOURCES += main.cpp \
- rainfallchart.cpp \
+ rainfallgraph.cpp \
variantdataset.cpp \
variantbardataproxy.cpp \
variantbardatamapping.cpp \
HEADERS += \
- rainfallchart.h \
+ rainfallgraph.h \
variantdataset.h \
variantbardataproxy.h \
variantbardatamapping.h
INSTALLS += target
-RESOURCES += \
- rainfall.qrc
+RESOURCES += customproxy.qrc
-OTHER_FILES += data/raindata.txt
+OTHER_FILES += data/raindata.txt \
+ doc/src/* \
+ doc/images/*
diff --git a/examples/rainfall/rainfall.qrc b/examples/customproxy/customproxy.qrc
index 53cd4915..53cd4915 100644
--- a/examples/rainfall/rainfall.qrc
+++ b/examples/customproxy/customproxy.qrc
diff --git a/examples/customproxy/data/raindata.txt b/examples/customproxy/data/raindata.txt
new file mode 100644
index 00000000..531d66be
--- /dev/null
+++ b/examples/customproxy/data/raindata.txt
@@ -0,0 +1,158 @@
+# Rainfall per month from 2000 to 2012 in Northern Finland (Sodankylä, Utsjoki, Kuusamo)
+# Format: year, month, rainfall
+2000,1, 72,
+2000,2, 47,
+2000,3, 37,
+2000,4, 79,
+2000,5, 42,
+2000,6, 73,
+2000,7, 94,
+2000,8, 37,
+2000,9, 17,
+2000,10,69,
+2000,11,42,
+2000,12,42,
+2001,1, 25,
+2001,2, 47,
+2001,3, 20,
+2001,4, 70,
+2001,5, 27,
+2001,6, 40,
+2001,7, 123,
+2001,8, 39,
+2001,9, 66,
+2001,10,55,
+2001,11,29,
+2001,12,12,
+2002,1, 24,
+2002,2, 45,
+2002,3, 27,
+2002,4, 30,
+2002,5, 16,
+2002,6, 98,
+2002,7, 122,
+2002,8, 20,
+2002,9, 50,
+2002,10,24,
+2002,11,22,
+2002,12,12,
+2003,1, 43,
+2003,2, 17,
+2003,3, 26,
+2003,4, 22,
+2003,5, 60,
+2003,6, 14,
+2003,7, 86,
+2003,8, 77,
+2003,9, 69,
+2003,10,49,
+2003,11,23,
+2003,12,44,
+2004,1, 15,
+2004,2, 19,
+2004,3, 10,
+2004,4, 11,
+2004,5, 41,
+2004,6, 29,
+2004,7, 49,
+2004,8, 72,
+2004,9, 50,
+2004,10,18,
+2004,11,19,
+2004,12,40,
+2005,1, 60,
+2005,2, 24,
+2005,3, 12,
+2005,4, 50,
+2005,5, 88,
+2005,6, 32,
+2005,7, 76,
+2005,8, 55,
+2005,9, 92,
+2005,10,35,
+2005,11,105,
+2005,12,59,
+2006,1, 27,
+2006,2, 18,
+2006,3, 17,
+2006,4, 26,
+2006,5, 24,
+2006,6, 18,
+2006,7, 35,
+2006,8, 28,
+2006,9, 80,
+2006,10,52,
+2006,11,43,
+2006,12,44,
+2007,1, 41,
+2007,2, 21,
+2007,3, 30,
+2007,4, 20,
+2007,5, 53,
+2007,6, 29,
+2007,7, 139,
+2007,8, 52,
+2007,9, 51,
+2007,10,24,
+2007,11,47,
+2007,12,33,
+2008,1, 67,
+2008,2, 19,
+2008,3, 30,
+2008,4, 31,
+2008,5, 29,
+2008,6, 79,
+2008,7, 75,
+2008,8, 99,
+2008,9, 34,
+2008,10,52,
+2008,11,60,
+2008,12,20,
+2009,1, 9,
+2009,2, 22,
+2009,3, 11,
+2009,4, 10,
+2009,5, 69,
+2009,6, 30,
+2009,7, 78,
+2009,8, 93,
+2009,9, 70,
+2009,10,32,
+2009,11,56,
+2009,12,23,
+2010,1, 12,
+2010,2, 28,
+2010,3, 55,
+2010,4, 20,
+2010,5, 65,
+2010,6, 26,
+2010,7, 134,
+2010,8, 57,
+2010,9, 51,
+2010,10,53,
+2010,11,8,
+2010,12,9,
+2011,1, 34,
+2011,2, 20,
+2011,3, 30,
+2011,4, 31,
+2011,5, 42,
+2011,6, 78,
+2011,7, 85,
+2011,8, 33,
+2011,9, 42,
+2011,10,87,
+2011,11,41,
+2011,12,72,
+2012,1, 32,
+2012,2, 42,
+2012,3, 30,
+2012,4, 50,
+2012,5, 30,
+2012,6, 70,
+2012,7, 52,
+2012,8, 20,
+2012,9, 99,
+2012,10,70,
+2012,11,69,
+2012,12,49
diff --git a/examples/customproxy/doc/images/customproxy-example.png b/examples/customproxy/doc/images/customproxy-example.png
new file mode 100644
index 00000000..f1b5c443
--- /dev/null
+++ b/examples/customproxy/doc/images/customproxy-example.png
Binary files differ
diff --git a/examples/customproxy/doc/src/customproxy.qdoc b/examples/customproxy/doc/src/customproxy.qdoc
new file mode 100644
index 00000000..288a7149
--- /dev/null
+++ b/examples/customproxy/doc/src/customproxy.qdoc
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 customproxy
+ \title Custom Proxy Example
+ \ingroup qtdatavisualization_examples
+ \brief Using Q3DBars with a custom proxy.
+
+ The custom proxy example shows how to create a custom proxy to use with Q3DBars.
+
+ \image customproxy-example.png
+
+ The interesting thing about custom proxy example is the custom dataset and the corresponding
+ proxy usage, so we concentrate on that and skip explaining the basic Q3DBars functionality
+ - for that see \l{Bars Example}.
+
+ This example defines a simple flexible data set \c VariantDataSet where each data item is a
+ a variant list. Each item can have multiple different values, identified by their index in
+ the list. In this example, the data set is storing monthly rainfall data, where value in
+ index one is the year, index two contains the month, and the third value has the amount
+ of rainfall in that month.
+
+ The custom proxy we provide here is similar to item model based proxies provided by Qt
+ Data Visualization in that it requires a mapping object to interpret the data.
+
+ Let's take a closer look at the custom classes:
+
+ \section1 VariantDataSet
+
+ \c VariantDataSet class provides a simple API:
+
+ \snippet ../examples/customproxy/variantdataset.h 1
+ \dots 0
+ \codeline
+ \snippet ../examples/customproxy/variantdataset.h 0
+
+ As you can see, the data items are simply QVariantList objects, and the data can be added either
+ singly or in lists. The only additional functionality provided is clearing the data set and querying
+ for a reference to the data contained in the set. Signals are emitted when data is added or the set
+ is cleared.
+
+ \section1 VariantBarDataProxy
+
+ \c VariantBarDataProxy is a subclass of QBarDataProxy and provides a simple API of just getters
+ and setters for the data set and the mapping:
+
+ \snippet ../examples/customproxy/variantbardataproxy.h 0
+ \dots 0
+ \codeline
+ \snippet ../examples/customproxy/variantbardataproxy.h 1
+
+ On the implementation side, the proxy listens for the changes in the data set and the mapping,
+ and resolves the data set if any changes are detected. It is not particularly efficient
+ implementation in that any change will cause re-resolving of the entire data set, but that is not
+ an issue for this example. The interesting part is the \c resolveDataSet() method:
+
+ \snippet ../examples/customproxy/variantbardataproxy.cpp 0
+
+ In \c resolveDataSet() method we sort the variant data values into rows and columns based on the
+ mapping. This is very similar to how QItemModelBarDataProxy handles mapping, except we use
+ list indexes instead of item model roles here. Once the values are sorted, we generate \c QBarDataArray
+ out of them, and call \c resetArray() method on the parent class.
+
+ \section1 VariantBarDataMapping
+
+ \c VariantBarDataMapping stores the mapping information between \c VariantDataSet data item indexes
+ and rows, columns, and values of \c QBarDataArray. It also contains the lists of rows and columns to
+ be included in the resolved data:
+
+ \snippet ../examples/customproxy/variantbardatamapping.h 0
+ \dots 0
+ \codeline
+ \snippet ../examples/customproxy/variantbardatamapping.h 1
+ \dots 0
+ \codeline
+ \snippet ../examples/customproxy/variantbardatamapping.h 2
+ \dots 0
+ \codeline
+ \snippet ../examples/customproxy/variantbardatamapping.h 3
+
+ The primary way to use a \c VariantBarDataMapping object is to give the mappings already at the
+ constructor, though they can be set later individually or all together with \c remap() method.
+ A signal is emitted if mapping changes. It is basically a simplified version of
+ QItemModelBarDataMapping adapted to work with variant lists instead of item models.
+
+ \section1 RainfallGraph
+
+ \c RainfallGraph class handles the setup of the graph. The interesting part is the \c addDataSet()
+ method:
+
+ \snippet ../examples/customproxy/rainfallgraph.cpp 0
+
+ Bulk of that method is used for populating the variant data set. Once the set is populated,
+ visualizing the data is trivial with the help of our custom proxy:
+
+ \snippet ../examples/customproxy/rainfallgraph.cpp 1
+*/
diff --git a/examples/rainfall/main.cpp b/examples/customproxy/main.cpp
index 2b9b2861..54ea63e9 100644
--- a/examples/rainfall/main.cpp
+++ b/examples/customproxy/main.cpp
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -16,22 +16,22 @@
**
****************************************************************************/
-#include "rainfallchart.h"
+#include "rainfallgraph.h"
#include <QGuiApplication>
-using namespace QtDataVis3D;
+using namespace QtDataVisualization;
int main(int argc, char **argv)
{
QGuiApplication app(argc, argv);
- Q3DBars rainfall;
- rainfall.resize(1280, 800);
- rainfall.setPosition(QPoint(10, 30));
- rainfall.show();
+ Q3DBars *rainfall = new Q3DBars;
+ rainfall->resize(1280, 800);
+ rainfall->setPosition(QPoint(10, 30));
+ rainfall->show();
- RainfallChart *rainfallchart = new RainfallChart(&rainfall);
- rainfallchart->start();
+ RainfallGraph rainfallgraph(rainfall);
+ rainfallgraph.start();
return app.exec();
}
diff --git a/examples/rainfall/rainfallchart.cpp b/examples/customproxy/rainfallgraph.cpp
index f7bcd82b..3a9f820a 100644
--- a/examples/rainfall/rainfallchart.cpp
+++ b/examples/customproxy/rainfallgraph.cpp
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -16,22 +16,21 @@
**
****************************************************************************/
-#include "rainfallchart.h"
-#include <QtDataVis3D/qcategoryaxis.h>
-#include <QtDataVis3D/qvalueaxis.h>
+#include "rainfallgraph.h"
+#include <QtDataVisualization/q3dcategoryaxis.h>
+#include <QtDataVisualization/q3dvalueaxis.h>
+#include <QtDataVisualization/q3dscene.h>
+#include <QtDataVisualization/q3dcamera.h>
#include <QGuiApplication>
#include <QFont>
#include <QDebug>
#include <QTextStream>
#include <QFile>
-#define CHANGE_CITY_WITH_TIMER
+using namespace QtDataVisualization;
-using namespace QtDataVis3D;
-
-RainfallChart::RainfallChart(Q3DBars *rainfall)
- : m_chart(rainfall),
- m_city(2)
+RainfallGraph::RainfallGraph(Q3DBars *rainfall)
+ : m_graph(rainfall)
{
// In data file the months are in numeric format, so create custom list
for (int i = 1; i <= 12; i++)
@@ -40,120 +39,112 @@ RainfallChart::RainfallChart(Q3DBars *rainfall)
m_columnCount = m_numericMonths.size();
m_proxy = new VariantBarDataProxy;
- m_proxy->setItemLabelFormat(QStringLiteral(" mm"));
- m_chart->setDataProxy(m_proxy);
+ m_graph->setActiveDataProxy(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);
+ m_graph->setBarThickness(1.0);
+ m_graph->setBarSpacing(QSizeF(0.2, 0.2));
// 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);
+ m_graph->rowAxis()->setTitle("Year");
+ m_graph->columnAxis()->setTitle("Month");
+ m_graph->valueAxis()->setTitle("rainfall");
+ m_graph->valueAxis()->setLabelFormat("%d mm");
+ m_graph->valueAxis()->setSegmentCount(5);
+ m_graph->rowAxis()->setCategoryLabels(m_years);
+ m_graph->columnAxis()->setCategoryLabels(months);
// Set bar type to cylinder
- m_chart->setBarType(QDataVis::Cylinders, false);
+ m_graph->setBarType(QDataVis::MeshStyleCylinders, false);
// Set shadows to medium
- m_chart->setShadowQuality(QDataVis::ShadowMedium);
+ m_graph->setShadowQuality(QDataVis::ShadowQualityMedium);
// Set font
- m_chart->setFont(QFont("Century Gothic", 40));
+ m_graph->setFont(QFont("Century Gothic", 30));
// Set selection mode to bar and column
- //m_chart->setSelectionMode(ModeItemAndColumn);
- m_chart->setSelectionMode(QDataVis::ModeZoomColumn);
+ m_graph->setSelectionMode(QDataVis::SelectionModeSliceColumn);
// Set theme
- m_chart->setTheme(QDataVis::ThemeBlueNcs);
-
- // Set preset camera position
- m_chart->setCameraPreset(QDataVis::PresetIsometricRightHigh);
+ m_graph->setTheme(QDataVis::ThemeArmyBlue);
- // Disable grid
- m_chart->setGridVisible(false);
+ // Set camera position and zoom
+ m_graph->scene()->activeCamera()->setCameraPreset(QDataVis::CameraPresetIsometricRightHigh);
+ m_graph->scene()->activeCamera()->setZoomLevel(75);
// Set window title
- m_chart->setWindowTitle(QStringLiteral("Monthly rainfall in various cities"));
+ m_graph->setTitle(QStringLiteral("Monthly rainfall in Northern Finland"));
}
-RainfallChart::~RainfallChart()
+RainfallGraph::~RainfallGraph()
{
delete m_mapping;
delete m_dataSet;
- delete m_chart;
+ delete m_graph;
}
-void RainfallChart::start()
+void RainfallGraph::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)
+void RainfallGraph::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()
+//! [0]
+void RainfallGraph::addDataSet()
{
+ // Create a new variant data set and data item list
m_dataSet = new VariantDataSet;
VariantDataItemList *itemList = new VariantDataItemList;
+
+ // Read data from a data file into the data item list
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("#"))
+ if (line.startsWith("#")) // Ignore comments
continue;
QStringList strList = line.split(",", QString::SkipEmptyParts);
- if (strList.size() < 5) {
+ // Each line has three data items: Year, month, and rainfall value
+ if (strList.size() < 3) {
qWarning() << "Invalid row read from data:" << line;
continue;
}
+ // Store year and month as strings, and rainfall value as double
+ // into a variant data item and add the item to the item list.
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());
+ newItem->append(strList.at(2).trimmed().toDouble());
itemList->append(newItem);
}
} else {
qWarning() << "Unable to open data file:" << dataFile.fileName();
}
+ //! [1]
+ // Add items to the data set and set it to the proxy
m_dataSet->addItems(itemList);
-
m_proxy->setDataSet(m_dataSet);
- m_mapping = new VariantBarDataMapping(0, 1, m_city, m_years, m_numericMonths);
+ // Create new mapping for the data and set it to the proxy
+ m_mapping = new VariantBarDataMapping(0, 1, 2, m_years, m_numericMonths);
m_proxy->setMapping(m_mapping);
+ //! [1]
}
+//! [0]
diff --git a/examples/rainfall/rainfallchart.h b/examples/customproxy/rainfallgraph.h
index 585f2bd0..6317ab71 100644
--- a/examples/rainfall/rainfallchart.h
+++ b/examples/customproxy/rainfallgraph.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -16,41 +16,36 @@
**
****************************************************************************/
-#ifndef RAINFALLCHART_H
-#define RAINFALLCHART_H
+#ifndef RAINFALLGRAPH_H
+#define RAINFALLGRAPH_H
#include "variantbardataproxy.h"
-#include <QtDataVis3D/q3dbars.h>
-#include <QTimer>
+#include <QtDataVisualization/q3dbars.h>
-using namespace QtDataVis3D;
+using namespace QtDataVisualization;
-class RainfallChart : public QObject
+class RainfallGraph : public QObject
{
Q_OBJECT
public:
- explicit RainfallChart(Q3DBars *rainfall);
- ~RainfallChart();
+ explicit RainfallGraph(Q3DBars *rainfall);
+ ~RainfallGraph();
void addDataSet();
void start();
-public slots:
- void timeout();
private:
void updateYearsList(int start, int end);
- Q3DBars *m_chart;
+ Q3DBars *m_graph;
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
+#endif
diff --git a/examples/rainfall/variantbardatamapping.cpp b/examples/customproxy/variantbardatamapping.cpp
index 288a3b55..0c2f146c 100644
--- a/examples/rainfall/variantbardatamapping.cpp
+++ b/examples/customproxy/variantbardatamapping.cpp
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,9 +20,9 @@
VariantBarDataMapping::VariantBarDataMapping()
: QObject(0),
- m_rowIndex(0),
- m_columnIndex(1),
- m_valueIndex(2)
+ m_rowIndex(0),
+ m_columnIndex(1),
+ m_valueIndex(2)
{
}
@@ -36,8 +36,8 @@ VariantBarDataMapping::VariantBarDataMapping(const VariantBarDataMapping &other)
}
VariantBarDataMapping::VariantBarDataMapping(int rowIndex, int columnIndex, int valueIndex,
- const QStringList &rowCategories,
- const QStringList &columnCategories)
+ const QStringList &rowCategories,
+ const QStringList &columnCategories)
: QObject(0),
m_rowIndex(0),
m_columnIndex(1),
@@ -121,8 +121,8 @@ const QStringList &VariantBarDataMapping::columnCategories() const
}
void VariantBarDataMapping::remap(int rowIndex, int columnIndex, int valueIndex,
- const QStringList &rowCategories,
- const QStringList &columnCategories)
+ const QStringList &rowCategories,
+ const QStringList &columnCategories)
{
m_rowIndex = rowIndex;
m_columnIndex = columnIndex;
diff --git a/examples/rainfall/variantbardatamapping.h b/examples/customproxy/variantbardatamapping.h
index 616ee563..9ccf1610 100644
--- a/examples/rainfall/variantbardatamapping.h
+++ b/examples/customproxy/variantbardatamapping.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -19,25 +19,29 @@
#ifndef VARIANTBARDATAMAPPING_H
#define VARIANTBARDATAMAPPING_H
-#include "qdatavis3denums.h"
+#include "qdatavisualizationenums.h"
#include <QStringList>
-using namespace QtDataVis3D;
+using namespace QtDataVisualization;
class VariantBarDataMapping : public QObject
{
Q_OBJECT
+ //! [0]
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)
+ //! [0]
public:
explicit VariantBarDataMapping();
VariantBarDataMapping(const VariantBarDataMapping &other);
+ //! [1]
VariantBarDataMapping(int rowIndex, int columnIndex, int valueIndex,
const QStringList &rowCategories,
const QStringList &columnCategories);
+ //! [1]
virtual ~VariantBarDataMapping();
VariantBarDataMapping &operator=(const VariantBarDataMapping &other);
@@ -54,11 +58,15 @@ public:
void setColumnCategories(const QStringList &categories);
const QStringList &columnCategories() const;
+ //! [2]
void remap(int rowIndex, int columnIndex, int valueIndex,
const QStringList &rowCategories,
const QStringList &columnCategories);
+ //! [2]
signals:
+ //! [3]
void mappingChanged();
+ //! [3]
private:
// Indexes of the mapped items in the VariantDataItem
diff --git a/examples/rainfall/variantbardataproxy.cpp b/examples/customproxy/variantbardataproxy.cpp
index 79b5c67f..887115b8 100644
--- a/examples/rainfall/variantbardataproxy.cpp
+++ b/examples/customproxy/variantbardataproxy.cpp
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -18,7 +18,7 @@
#include "variantbardataproxy.h"
-using namespace QtDataVis3D;
+using namespace QtDataVisualization;
VariantBarDataProxy::VariantBarDataProxy() :
QBarDataProxy()
@@ -35,6 +35,7 @@ VariantBarDataProxy::VariantBarDataProxy(VariantDataSet *newSet,
VariantBarDataProxy::~VariantBarDataProxy()
{
+ delete m_dataSet;
}
void VariantBarDataProxy::setDataSet(VariantDataSet *newSet)
@@ -45,8 +46,10 @@ void VariantBarDataProxy::setDataSet(VariantDataSet *newSet)
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);
+ QObject::connect(m_dataSet.data(), &VariantDataSet::itemsAdded, this,
+ &VariantBarDataProxy::handleItemsAdded);
+ QObject::connect(m_dataSet.data(), &VariantDataSet::dataCleared, this,
+ &VariantBarDataProxy::handleDataCleared);
}
resolveDataSet();
}
@@ -59,12 +62,14 @@ VariantDataSet *VariantBarDataProxy::dataSet()
void VariantBarDataProxy::setMapping(VariantBarDataMapping *mapping)
{
if (!m_mapping.isNull())
- QObject::disconnect(m_mapping.data(), &VariantBarDataMapping::mappingChanged, this, &VariantBarDataProxy::handleMappingChanged);
+ 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);
+ QObject::connect(m_mapping.data(), &VariantBarDataMapping::mappingChanged, this,
+ &VariantBarDataProxy::handleMappingChanged);
resolveDataSet();
}
@@ -80,7 +85,7 @@ void VariantBarDataProxy::handleItemsAdded(int index, int count)
Q_UNUSED(count)
// Resolve new items
- resolveDataSet(); // TODO Resolving entire dataset is inefficient
+ resolveDataSet();
}
void VariantBarDataProxy::handleDataCleared()
@@ -95,9 +100,12 @@ void VariantBarDataProxy::handleMappingChanged()
}
// Resolve entire dataset into QBarDataArray.
+//! [0]
void VariantBarDataProxy::resolveDataSet()
{
- if (m_dataSet.isNull() || m_mapping.isNull() || !m_mapping->rowCategories().size() || !m_mapping->columnCategories().size()) {
+ // If we have no data or mapping, or the categories are not defined, simply clear the array
+ if (m_dataSet.isNull() || m_mapping.isNull() || !m_mapping->rowCategories().size()
+ || !m_mapping->columnCategories().size()) {
resetArray(0);
return;
}
@@ -112,10 +120,12 @@ void VariantBarDataProxy::resolveDataSet()
// 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();
+ foreach (const VariantDataItem *item, itemList) {
+ itemValueMap[item->at(rowIndex).toString()][item->at(columnIndex).toString()]
+ = item->at(valueIndex).toReal();
+ }
- // Create new data array from itemValueMap
+ // Create a new data array in format the parent class understands
QBarDataArray *newProxyArray = new QBarDataArray;
foreach (QString rowKey, rowList) {
QBarDataRow *newProxyRow = new QBarDataRow(columnList.size());
@@ -124,5 +134,7 @@ void VariantBarDataProxy::resolveDataSet()
newProxyArray->append(newProxyRow);
}
+ // Finally, reset the data array in the parent class
resetArray(newProxyArray);
}
+//! [0]
diff --git a/examples/rainfall/variantbardataproxy.h b/examples/customproxy/variantbardataproxy.h
index 2c80c0b1..6f6ba763 100644
--- a/examples/rainfall/variantbardataproxy.h
+++ b/examples/customproxy/variantbardataproxy.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -26,9 +26,11 @@
#include <QMap>
#include <QPointer>
-using namespace QtDataVis3D;
+using namespace QtDataVisualization;
+//! [0]
class VariantBarDataProxy : public QBarDataProxy
+//! [0]
{
Q_OBJECT
@@ -37,6 +39,7 @@ public:
explicit VariantBarDataProxy(VariantDataSet *newSet, VariantBarDataMapping *mapping);
virtual ~VariantBarDataProxy();
+ //! [1]
// Doesn't gain ownership of the dataset, but does connect to it to listen for data changes.
void setDataSet(VariantDataSet *newSet);
VariantDataSet *dataSet();
@@ -46,6 +49,7 @@ public:
// Modifying mapping that is set to proxy will trigger dataset re-resolving.
void setMapping(VariantBarDataMapping *mapping);
VariantBarDataMapping *mapping();
+ //! [1]
public slots:
void handleItemsAdded(int index, int count);
@@ -59,8 +63,6 @@ private:
QPointer<VariantBarDataMapping> m_mapping;
Q_DISABLE_COPY(VariantBarDataProxy)
-
- friend class VariantBarDataProxy;
};
#endif
diff --git a/examples/rainfall/variantdataset.cpp b/examples/customproxy/variantdataset.cpp
index 3fe4fa6b..f73d83f8 100644
--- a/examples/rainfall/variantdataset.cpp
+++ b/examples/customproxy/variantdataset.cpp
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
diff --git a/examples/rainfall/variantdataset.h b/examples/customproxy/variantdataset.h
index f3965978..6beb852f 100644
--- a/examples/rainfall/variantdataset.h
+++ b/examples/customproxy/variantdataset.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -19,14 +19,16 @@
#ifndef VARIANTDATASET_H
#define VARIANTDATASET_H
-#include "qdatavis3denums.h"
+#include "qdatavisualizationenums.h"
#include <QScopedPointer>
#include <QVariantList>
-using namespace QtDataVis3D;
+using namespace QtDataVisualization;
+//! [1]
typedef QVariantList VariantDataItem;
typedef QList<VariantDataItem *> VariantDataItemList;
+//! [1]
class VariantDataSet : public QObject
{
@@ -36,6 +38,7 @@ public:
explicit VariantDataSet();
~VariantDataSet();
+ //! [0]
void clear();
int addItem(VariantDataItem *item);
@@ -46,6 +49,7 @@ public:
signals:
void itemsAdded(int index, int count);
void dataCleared();
+ //! [0]
private:
VariantDataItemList m_variantData;
diff --git a/examples/examples.pri b/examples/examples.pri
index 48d2f29a..dc4add12 100644
--- a/examples/examples.pri
+++ b/examples/examples.pri
@@ -1,7 +1,7 @@
android {
target.path = /libs/$$ANDROID_TARGET_ARCH
} else {
- target.path = $$[QT_INSTALL_EXAMPLES]/datavis3d/$$TARGET
+ target.path = $$[QT_INSTALL_EXAMPLES]/datavisualization/$$TARGET
}
win32 {
@@ -13,11 +13,13 @@ win32 {
LIBS += -L$$OUT_PWD/../../lib
-QT += datavis3d
+TEMPLATE = app
+
+QT += datavisualization
contains(TARGET, qml.*) {
- uri = com.digia.QtDataVis3D
- lib_name = datavis3dqml2
+ uri = com.digia.QtDataVisualization
+ lib_name = datavisualizationqml2
uri_replaced = $$replace(uri, \\., $$QMAKE_DIR_SEP)
make_qmldir_path = $$DESTDIR/$$uri_replaced
@@ -25,11 +27,12 @@ contains(TARGET, qml.*) {
make_qmldir_target = \"$$replace(make_qmldir_path, /, $$QMAKE_DIR_SEP)\"
system($$QMAKE_MKDIR $$make_qmldir_target)
}
- copy_qmldir_examples.target = $$make_qmldir_path/qmldir
- copy_qmldir_examples.depends = $$_PRO_FILE_PWD_/../../src/$$lib_name/qmldir
- copy_qmldir_examples.commands = $(COPY_FILE) \"$$replace(copy_qmldir_examples.depends, /, $$QMAKE_DIR_SEP)\" \"$$replace(copy_qmldir_examples.target, /, $$QMAKE_DIR_SEP)\"
- QMAKE_EXTRA_TARGETS += copy_qmldir_examples
- PRE_TARGETDEPS += $$copy_qmldir_examples.target
+ copy_qmldir.target = $$make_qmldir_path/qmldir
+ copy_qmldir.depends = $$_PRO_FILE_PWD_/../../src/$$lib_name/qmldir
+ copy_qmldir_formatted = \"$$replace(copy_qmldir.depends, /, $$QMAKE_DIR_SEP)\" \"$$replace(copy_qmldir.target, /, $$QMAKE_DIR_SEP)\"
+ copy_qmldir.commands = $(COPY_FILE) $$copy_qmldir_formatted
+ QMAKE_EXTRA_TARGETS += copy_qmldir
+ PRE_TARGETDEPS += $$copy_qmldir.target
win32 {
CONFIG(debug, release|debug) {
@@ -56,13 +59,16 @@ contains(TARGET, qml.*) {
}
copy_lib.target = $$make_qmldir_path/$$src_lib
copy_lib.depends = $$OUT_PWD/../../src/$$lib_name/$$src_dir/$$src_lib
- copy_lib.commands = $(COPY_FILE) \"$$replace(copy_lib.depends, /, $$QMAKE_DIR_SEP)\" \"$$replace(copy_lib.target, /, $$QMAKE_DIR_SEP)\"
+ copy_lib_formatted = \"$$replace(copy_lib.depends, /, $$QMAKE_DIR_SEP)\" \"$$replace(copy_lib.target, /, $$QMAKE_DIR_SEP)\"
+ copy_lib.commands = $(COPY_FILE) $$copy_lib_formatted
QMAKE_EXTRA_TARGETS += copy_lib
PRE_TARGETDEPS += $$copy_lib.target
android {
- android_qmldir.files = $$copy_qmldir_examples.target
- android_qmldir.path = /assets/imports/$$make_qmldir_target
+ system($$QMAKE_COPY $$copy_qmldir_formatted)
+ system($$QMAKE_COPY $$copy_lib_formatted)
+ android_qmldir.files = $$copy_qmldir.target
+ android_qmldir.path = /assets/qml/$$uri_replaced
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 4db7ed2f..7d9f306a 100644
--- a/examples/examples.pro
+++ b/examples/examples.pro
@@ -1,12 +1,13 @@
TEMPLATE = subdirs
-SUBDIRS += barchart \
- rainfall \
- widget \
- mapdata \
- qmlbarchart \
- #qmlmaps \
+SUBDIRS += qmlbars \
qmlscatter \
- surfacechart \
- scatterchart
+ qmlsurface
+!android: {
+ SUBDIRS += bars \
+ customproxy \
+ itemmodel \
+ scatter \
+ surface
+}
-qtHaveModule(multimedia):!android: SUBDIRS += spectrum
+qtHaveModule(multimedia):!android: SUBDIRS += audiolevels
diff --git a/examples/itemmodel/doc/images/itemmodel-example-2.png b/examples/itemmodel/doc/images/itemmodel-example-2.png
new file mode 100644
index 00000000..7186b267
--- /dev/null
+++ b/examples/itemmodel/doc/images/itemmodel-example-2.png
Binary files differ
diff --git a/examples/itemmodel/doc/images/itemmodel-example.png b/examples/itemmodel/doc/images/itemmodel-example.png
new file mode 100644
index 00000000..03d7c386
--- /dev/null
+++ b/examples/itemmodel/doc/images/itemmodel-example.png
Binary files differ
diff --git a/examples/itemmodel/doc/src/itemmodel.qdoc b/examples/itemmodel/doc/src/itemmodel.qdoc
new file mode 100644
index 00000000..f014bfea
--- /dev/null
+++ b/examples/itemmodel/doc/src/itemmodel.qdoc
@@ -0,0 +1,182 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 itemmodel
+ \title Item Model Example
+ \ingroup qtdatavisualization_examples
+ \brief Using an item model as data source for Q3DBars.
+
+ The item model example shows how to make a simple 3D bar graph using Q3DBars and how to modify
+ the data being drawn at run-time. The example shows how to:
+
+ \list
+ \li How to create an application with Q3DBars and widgets
+ \li How to use QItemModelBarDataMapping and QItemModelBarDataProxy to set data to the graph
+ \li How to use a table widget to modify the data in the graph
+ \endlist
+
+ \image itemmodel-example-2.png
+
+ \section1 Creating the application
+
+ First, in main.cpp, we create a QApplication, instantiate Q3DBars and a window container for it:
+
+ \snippet ../examples/itemmodel/main.cpp 0
+
+ The call to QWidget::createWindowContainer is required, as all data visualization types
+ (Q3DBars, Q3DScatter, Q3DSurface) inherit QWindow. Any class inheriting QWindow cannot be used
+ as a widget any other way.
+
+ Then we'll create a layout and add the graph and the table widget into it:
+
+ \snippet ../examples/itemmodel/main.cpp 1
+
+ The table widget is going to be used to display the numerical data being inserted into the
+ graph, and to modify it (See \l {Adding data to the graph} and \l {Interacting with the data}).
+
+ We need to instantiate QItemModelBarDataMapping and QItemModelBarDataProxy and give them to the
+ graph:
+
+ \snippet ../examples/itemmodel/main.cpp 2
+
+ Here we tell the mapping object to directly map model's rows and columns into proxy's rows and
+ columns instead of defining row and column roles to map for them. Then we give the model from
+ the table widget and the mapping object to the proxy. Finally we set the proxy as the active
+ data proxy for the graph.
+
+ Next, let's create another class to handle the data addition and other interaction with the
+ graph. Let's call it GraphDataGenerator (See \l {Setting up the graph} and
+ \l {Adding data to the graph} for details) and connect some signals between Q3DBars,
+ GraphDataGenerator and QTableWidget (See \l {Interacting with the data} for a closer look):
+
+ \snippet ../examples/itemmodel/main.cpp 3
+
+ The application main is done and we can show the graph and start the event loop:
+
+ \snippet ../examples/itemmodel/main.cpp 4
+
+ \section1 Setting up the graph
+
+ Let's set up the visual attributes for the graph in the constructor of GraphDataGenerator:
+
+ \snippet ../examples/itemmodel/main.cpp 5
+ \snippet ../examples/itemmodel/main.cpp 6
+ \snippet ../examples/itemmodel/main.cpp 7
+
+ First we set bar thickness ratio to 1.0, which means bars will be as wide as they are deep. 1.0
+ is also the default value, so the line is basically unnecessary. It's left there so you could
+ easily try how changing it affects the graph. The second line sets bar spacings to 0.2, which
+ means there will be a gap of 20% of the bar's thickness between the bars in both directions.
+
+ Then, we set the bar type to flat pyramids, overriding the default bar type.
+ We want to be able to select rows of data for a closer inspection, so we set the selection mode
+ to slice row. This means that whenever we select a bar in the graph, the whole row will be
+ displayed separately.
+
+ Next line sets the font to \c Impact. If your system doesn't have it, it will be replaced by
+ system default.
+
+ And finally, we set theme to \c Digia and camera position to \c {Preset Front}. Now the initial
+ graph settings are done.
+
+ \note You do not need to set any of these in case you're happy with the defaults. You can
+ easily try them by commenting out the contents of the constructor.
+
+ \section1 Adding data to the graph
+
+ We created the data generator in the application main and gave it the graph and the table
+ widget as parameters:
+
+ \code GraphDataGenerator generator(graph, tableWidget); \endcode
+
+ We added a separate start method to the generator, so that it wouldn't start doing anything
+ until everything else is set up. We then called the method when starting the application:
+
+ \code generator.start(); \endcode
+
+ Let's have a look at the contents of the \c start() method:
+
+ \snippet ../examples/itemmodel/main.cpp 8
+
+ The main thing \c start() does is set up the data model. It also activates a timer for getting
+ the accurate dimensions of the table widget after it's been filled with data. The reason we
+ do this is that the widget doesn't know its final visual domensions until all the data has been
+ inserted to it and it has been shown. The whole data timer implementation is not vital for the
+ application, so we won't take a closer look at it. It's just there to make the table look better.
+
+ In \c setupModel() we first introduce the row and column labels, and the actual data:
+
+ \snippet ../examples/itemmodel/main.cpp 9
+
+ Then we set up the axes:
+
+ \snippet ../examples/itemmodel/main.cpp 10
+
+ The other lines there are pretty self-explanatory except for the one with the segment count.
+ We're setting it to five as we want the value axis (the Y-axis) to show more values than just
+ the lowest and the highest.
+
+ Next we will set up the table widget:
+
+ \snippet ../examples/itemmodel/main.cpp 11
+
+ After that all that's left is adding the data to the table widget:
+
+ \snippet ../examples/itemmodel/main.cpp 12
+
+ Now we have a bar graph and a table widget, both displaying the same data.
+
+ You're probably wondering how the data can be displayed in the graph, as the only thing we did
+ was add it to the table widget? That's because of what we did earlier, in the application main:
+
+ \snippet ../examples/itemmodel/main.cpp 2
+
+ We created QItemModelBarDataMapping and QItemModelBarDataProxy instances, and gave the proxy
+ the model of the table widget and the model mapping we just created. Then we set the proxy as
+ the active proxy for the graph. The proxy maps the rows and the columns in the model of the table
+ widget into rows and columns for itself using the model mapping, and the graph gets the data
+ to be displayed from its active proxy.
+
+ \section1 Interacting with the data
+
+ We made a couple of signal connections in the application main earlier:
+
+ \snippet ../examples/itemmodel/main.cpp 3
+
+ Now we'll find out what these were for.
+
+ The first one connects a signal from Q3DBars to the GraphDataGenerator. Signal
+ Q3DBars::selectedBarPosChanged() is emitted when a bar is selected from the graph. We connect
+ that to a method in the data generator that selects the same data item in the table widget:
+
+ \snippet ../examples/itemmodel/main.cpp 13
+
+ The second connection does the opposite; it connects a signal from the table widget to a
+ method in the data generator. The method then selects the corresponding bar in the graph:
+
+ \snippet ../examples/itemmodel/main.cpp 14
+
+ You can even select an item in the widget and change the value of it, and the new value is
+ updated to the graph. This is handled again by the active proxy with mapping between the data
+ in the table widget and itself.
+
+ \image itemmodel-example.png
+
+ \section1 Example contents
+*/
diff --git a/examples/barchart/barchart.pro b/examples/itemmodel/itemmodel.pro
index 12b296c5..f319f690 100644
--- a/examples/barchart/barchart.pro
+++ b/examples/itemmodel/itemmodel.pro
@@ -7,3 +7,6 @@ SOURCES += main.cpp
INSTALLS += target
QT += widgets
+
+OTHER_FILES += doc/src/* \
+ doc/images/*
diff --git a/examples/itemmodel/main.cpp b/examples/itemmodel/main.cpp
new file mode 100644
index 00000000..6ab685ed
--- /dev/null
+++ b/examples/itemmodel/main.cpp
@@ -0,0 +1,287 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 <QtDataVisualization/q3dbars.h>
+#include <QtDataVisualization/q3dcategoryaxis.h>
+#include <QtDataVisualization/qitemmodelbardataproxy.h>
+#include <QtDataVisualization/q3dvalueaxis.h>
+#include <QtDataVisualization/q3dscene.h>
+#include <QtDataVisualization/q3dcamera.h>
+
+#include <QApplication>
+#include <QVBoxLayout>
+#include <QTableWidget>
+#include <QScreen>
+#include <QTimer>
+#include <QFont>
+#include <QDebug>
+#include <QHeaderView>
+
+#define USE_STATIC_DATA
+
+using namespace QtDataVisualization;
+
+class GraphDataGenerator : public QObject
+{
+public:
+ explicit GraphDataGenerator(Q3DBars *bargraph, QTableWidget *tableWidget);
+ ~GraphDataGenerator();
+
+ void setupModel();
+ void addRow();
+ void changeStyle();
+ void changePresetCamera();
+ void changeTheme();
+ void start();
+ void selectFromTable(const QPoint &selection);
+ void selectedFromTable(int currentRow, int currentColumn, int previousRow, int previousColumn);
+ void fixTableSize();
+
+private:
+ Q3DBars *m_graph;
+ QTimer *m_dataTimer;
+ QTimer *m_styleTimer;
+ QTimer *m_presetTimer;
+ QTimer *m_themeTimer;
+ int m_columnCount;
+ int m_rowCount;
+ QTableWidget *m_tableWidget; // not owned
+};
+
+GraphDataGenerator::GraphDataGenerator(Q3DBars *bargraph, QTableWidget *tableWidget)
+ : m_graph(bargraph),
+ m_dataTimer(0),
+ m_styleTimer(0),
+ m_presetTimer(0),
+ m_themeTimer(0),
+ m_columnCount(100),
+ m_rowCount(50),
+ m_tableWidget(tableWidget)
+{
+ //! [5]
+ // Set up bar specifications; make the bars as wide as they are deep,
+ // and add a small space between them
+ m_graph->setBarThickness(1.0);
+ m_graph->setBarSpacing(QSizeF(0.2, 0.2));
+
+ // Set bar type to flat pyramids
+ m_graph->setBarType(QDataVis::MeshStylePyramids, false);
+
+ //! [5]
+
+#ifndef USE_STATIC_DATA
+ // Set up sample space; make it as deep as it's wide
+ m_graph->setDataWindow(m_rowCount, m_columnCount);
+ m_tableWidget->setColumnCount(m_columnCount);
+
+ // Set selection mode to full
+ m_graph->setSelectionMode(QDataVis::SelectionModeItemRowAndColumn);
+
+ // Hide axis labels by explicitly setting one empty string as label list
+ m_graph->rowAxis()->setCategoryLabels(QStringList(QString()));
+ m_graph->columnAxis()->setCategoryLabels(QStringList(QString()));
+
+ m_graph->activeDataProxy()->setItemLabelFormat(QStringLiteral("@valueLabel"));
+#else
+ //! [6]
+
+ // Set selection mode to slice row
+ m_graph->setSelectionMode(QDataVis::SelectionModeSliceRow);
+
+ // Set font
+ m_graph->setFont(QFont("Impact", 20));
+
+ //! [6]
+#endif
+
+ //! [7]
+
+ // Set theme
+ m_graph->setTheme(QDataVis::ThemeDigia);
+
+ // Set preset camera position
+ m_graph->scene()->activeCamera()->setCameraPreset(QDataVis::CameraPresetFront);
+ //! [7]
+}
+
+GraphDataGenerator::~GraphDataGenerator()
+{
+ if (m_dataTimer) {
+ m_dataTimer->stop();
+ delete m_dataTimer;
+ }
+ delete m_graph;
+}
+
+void GraphDataGenerator::start()
+{
+#ifndef USE_STATIC_DATA
+ m_dataTimer = new QTimer();
+ m_dataTimer->setTimerType(Qt::CoarseTimer);
+ QObject::connect(m_dataTimer, &QTimer::timeout, this, &GraphDataGenerator::addRow);
+ m_dataTimer->start(0);
+ m_tableWidget->setFixedWidth(m_graph->width());
+#else
+ //! [8]
+ setupModel();
+ // Table needs to be shown before the size of its headers can be accurately obtained,
+ // so we postpone it a bit
+ m_dataTimer = new QTimer();
+ m_dataTimer->setSingleShot(true);
+ QObject::connect(m_dataTimer, &QTimer::timeout, this, &GraphDataGenerator::fixTableSize);
+ m_dataTimer->start(0);
+ //! [8]
+#endif
+}
+
+void GraphDataGenerator::setupModel()
+{
+ //! [9]
+ // Set up row and column names
+ QStringList days;
+ days << "Monday" << "Tuesday" << "Wednesday" << "Thursday" << "Friday" << "Saturday" << "Sunday";
+ 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.0, 1.0, 3.0, 0.2, 1.0, 5.0, 10.0}, // week 1
+ {0.5, 1.0, 3.0, 1.0, 2.0, 2.0, 3.0}, // week 2
+ {1.0, 1.0, 2.0, 1.0, 4.0, 4.0, 4.0}, // week 3
+ {0.0, 1.0, 0.0, 0.0, 2.0, 2.0, 0.3}, // week 4
+ {3.0, 3.0, 6.0, 2.0, 2.0, 1.0, 1.0}}; // week 5
+ //! [9]
+
+ // Add labels
+ //! [10]
+ m_graph->rowAxis()->setTitle("Week of year");
+ m_graph->columnAxis()->setTitle("Day of week");
+ m_graph->valueAxis()->setTitle("Hours spent on the Internet");
+ m_graph->valueAxis()->setSegmentCount(5);
+ m_graph->valueAxis()->setLabelFormat("%.1f h");
+ //! [10]
+
+ //! [11]
+ m_tableWidget->setRowCount(5);
+ m_tableWidget->setColumnCount(7);
+ m_tableWidget->setHorizontalHeaderLabels(days);
+ m_tableWidget->setVerticalHeaderLabels(weeks);
+ m_tableWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ m_tableWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ m_tableWidget->setCurrentCell(-1, -1);
+ //! [11]
+
+ //! [12]
+ for (int week = 0; week < weeks.size(); week++) {
+ for (int day = 0; day < days.size(); day++) {
+ QModelIndex index = m_tableWidget->model()->index(week, day);
+ m_tableWidget->model()->setData(index, hours[week][day]);
+ }
+ }
+ //! [12]
+}
+
+void GraphDataGenerator::addRow()
+{
+ m_tableWidget->model()->insertRow(0);
+ if (m_tableWidget->model()->rowCount() > m_rowCount)
+ m_tableWidget->model()->removeRow(m_rowCount);
+ 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);
+ }
+ m_tableWidget->resizeColumnsToContents();
+}
+
+//! [13]
+void GraphDataGenerator::selectFromTable(const QPoint &selection)
+{
+ m_tableWidget->setFocus();
+ m_tableWidget->setCurrentCell(selection.x(), selection.y());
+}
+//! [13]
+
+//! [14]
+void GraphDataGenerator::selectedFromTable(int currentRow, int currentColumn,
+ int previousRow, int previousColumn)
+{
+ Q_UNUSED(previousRow)
+ Q_UNUSED(previousColumn)
+ m_graph->setSelectedBarPos(QPoint(currentRow, currentColumn));
+}
+//! [14]
+
+void GraphDataGenerator::fixTableSize()
+{
+ int width = m_tableWidget->horizontalHeader()->length();
+ width += m_tableWidget->verticalHeader()->width();
+ m_tableWidget->setFixedWidth(width + 2);
+ int height = m_tableWidget->verticalHeader()->length();
+ height += m_tableWidget->horizontalHeader()->height();
+ m_tableWidget->setFixedHeight(height + 2);
+}
+
+int main(int argc, char **argv)
+{
+ //! [0]
+ QApplication app(argc, argv);
+ Q3DBars *graph = new Q3DBars();
+ QWidget *container = QWidget::createWindowContainer(graph);
+ //! [0]
+
+ QSize screenSize = graph->screen()->size();
+ container->setMinimumSize(QSize(screenSize.width() / 2, screenSize.height() / 2));
+ container->setMaximumSize(screenSize);
+ container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ container->setFocusPolicy(Qt::StrongFocus);
+
+ //! [1]
+ QWidget widget;
+ QVBoxLayout *layout = new QVBoxLayout(&widget);
+ QTableWidget *tableWidget = new QTableWidget(&widget);
+ layout->addWidget(container, 1);
+ layout->addWidget(tableWidget, 1, Qt::AlignHCenter);
+ //! [1]
+
+ tableWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ tableWidget->setAlternatingRowColors(true);
+ widget.setWindowTitle(QStringLiteral("Hours spent on the Internet"));
+
+ //! [2]
+ // Since we are dealing with QTableWidget, the model will already have data sorted properly
+ // in rows and columns, so create a mapping to utilize this.
+ QItemModelBarDataMapping *mapping = new QItemModelBarDataMapping;
+ mapping->setUseModelCategories(true);
+ QItemModelBarDataProxy *proxy = new QItemModelBarDataProxy(tableWidget->model(), mapping);
+ graph->setActiveDataProxy(proxy);
+ //! [2]
+
+ //! [3]
+ GraphDataGenerator generator(graph, tableWidget);
+ QObject::connect(graph, &Q3DBars::selectedBarPosChanged, &generator,
+ &GraphDataGenerator::selectFromTable);
+ QObject::connect(tableWidget, &QTableWidget::currentCellChanged, &generator,
+ &GraphDataGenerator::selectedFromTable);
+ //! [3]
+
+ //! [4]
+ widget.show();
+ generator.start();
+ return app.exec();
+ //! [4]
+}
diff --git a/examples/mapdata/Suomi.karttapohja.svg b/examples/mapdata/Suomi.karttapohja.svg
deleted file mode 100644
index 85a449b0..00000000
--- a/examples/mapdata/Suomi.karttapohja.svg
+++ /dev/null
@@ -1,3018 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Creator: CorelDRAW -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- xml:space="preserve"
- width="1850"
- height="3220"
- style="fill-rule: evenodd;"
- viewBox="0 0 1850 3237.41"
- id="svg2"
- version="1.1"
- inkscape:version="0.47 r22583"
- sodipodi:docname="Suomi.karttapohja.svg"><metadata
- id="metadata650"><rdf:RDF><cc:Work
- rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><sodipodi:namedview
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1"
- objecttolerance="10"
- gridtolerance="10"
- guidetolerance="10"
- inkscape:pageopacity="0"
- inkscape:pageshadow="2"
- inkscape:window-width="1680"
- inkscape:window-height="1000"
- id="namedview648"
- showgrid="false"
- fit-margin-top="0"
- fit-margin-left="0"
- fit-margin-right="0"
- fit-margin-bottom="0"
- inkscape:zoom="1.2968944"
- inkscape:cx="1302.3906"
- inkscape:cy="240.52554"
- inkscape:window-x="-8"
- inkscape:window-y="-8"
- inkscape:window-maximized="1"
- inkscape:current-layer="_74312864" />
- <defs
- id="defs4"><inkscape:perspective
- sodipodi:type="inkscape:persp3d"
- inkscape:vp_x="0 : 1610 : 1"
- inkscape:vp_y="0 : 1000 : 0"
- inkscape:vp_z="1850 : 1610 : 1"
- inkscape:persp3d-origin="925 : 1073.3333 : 1"
- id="perspective611" />
- <style
- type="text/css"
- id="style6">
-
- .str3 {stroke:#C7C7A2;stroke-width:0.797991}
- .str1 {stroke:#8C8C60;stroke-width:1.70998}
- .str2 {stroke:#636347;stroke-width:2.27997}
- .str0 {stroke:#1F1A17;stroke-width:3.98996}
- .fil1 {fill:none}
- .fil0 {fill:#EEEED4}
-
- </style>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- <inkscape:perspective
- id="perspective3574"
- inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
- inkscape:vp_z="1 : 0.5 : 1"
- inkscape:vp_y="0 : 1000 : 0"
- inkscape:vp_x="0 : 0.5 : 1"
- sodipodi:type="inkscape:persp3d" /></defs>
- <g
- id="Layer_x0020_1"
- transform="translate(-14.0454, -0.00501389)">
- <metadata
- id="CorelCorpID_0Corel-Layer" />
- <g
- id="_91105008">
- <polygon
- id="_91167600"
- class="fil0 str0"
- points="734.897,442.02 741.874,456.449 771.196,443.235 798.888,433.452 809.986,413.882 830.941,402.881 872.378,433.58 916.245,452.767 940.503,482.635 946.707,469.967 964.057,470.073 961.225,434.135 986.507,396.951 1005.05,385.808 1025.49,391.044 1035.53,355.861 1031.81,293.372 1050.21,188.127 1059.65,170.934 1054.1,154.879 1068.55,131.72 1097.91,105.588 1115.32,64.1525 1143.85,54.1508 1193.47,67.0789 1236.46,33.0009 1247.21,17.3925 1262.71,22.4227 1278.39,12.5376 1306.22,51.2835 1333.06,68.1732 1335.1,87.2276 1422.82,130.452 1452.27,205.546 1400.14,273.285 1396.63,307.18 1406.98,343.479 1352.78,389.081 1385.74,388.966 1393.92,402.814 1387.41,449.541 1358.46,501.718 1383.06,604.25 1455.73,633.814 1503.25,730.84 1549.63,765.543 1545.9,810.813 1447.28,995.77 1439.79,1020.47 1504.59,1129.9 1535.44,1212.77 1560.34,1249.47 1590.01,1334.1 1598.77,1395.63 1579.48,1397.44 1551.11,1416.34 1561.84,1434.11 1552.94,1464.05 1550.79,1496.63 1539.81,1533.78 1566.06,1536.2 1574.25,1545.67 1565.67,1563.26 1572.7,1572.6 1565.07,1588.4 1545.72,1594.85 1540.33,1615.02 1555.24,1672.39 1605.92,1682.79 1601.44,1698.83 1612.08,1712.15 1611.43,1732.28 1600.37,1741.99 1600.45,1764.83 1615.98,1806.59 1670.36,1843.89 1681,1893.37 1646.69,1982.92 1614.27,2006.04 1669.04,2064.54 1687.17,2090.16 1732.19,2110.62 1764.11,2135.78 1789.18,2153.1 1800.82,2193.18 1836.01,2221.81 1848.18,2252.58 1806.45,2385.04 1771.2,2450.67 1752.19,2458.11 1723.31,2502.39 1683.21,2572.67 1661.79,2594.86 1649.79,2628.83 1619.63,2656.59 1599.34,2699.18 1573.78,2717.29 1568.01,2735.14 1530.07,2799.12 1485.65,2829.93 1469.78,2836.4 1450.69,2869.07 1448.29,2890.48 1427.77,2895.06 1389.32,2928.71 1381.94,2948.43 1327.85,3000.45 1327.36,3010.63 1316.96,3017.51 1304.85,3009.58 1300.01,3013.29 1296.24,3030.21 1290.9,3038.94 1282.82,3039.19 1273.05,3040.6 1266.64,3037.07 1260.75,3041.02 1253.67,3047.69 1244.57,3034.19 1220.98,3031.41 1192.37,3022.07 1180.78,3033.71 1181.12,3052.38 1176.95,3059.87 1165.21,3059.51 1151.75,3046.07 1143.89,3053.24 1133.83,3053.59 1127.53,3046.94 1120.87,3051.57 1103.91,3055.46 1090.52,3067.5 1083.02,3067.23 1082.31,3078.1 1073.44,3067.02 1059.82,3066.67 1063.67,3079.72 1057.59,3080.2 1052.42,3068.69 1041.49,3057.43 1025.88,3042.53 1024.52,3050.67 1034.09,3063.59 1036.74,3074.18 1046.13,3090.82 1040.51,3093.28 1032.88,3089.49 1027.92,3091.22 1028.85,3103.79 1023.72,3105.84 1015.33,3088.55 1011.12,3091.97 1015.81,3106.98 1011.54,3112.5 1003.29,3107.36 995.826,3115.4 990.8,3114.45 978.112,3098.68 974.135,3083.96 958.129,3085.77 957.765,3099.11 951.609,3106.69 927.23,3107.33 907.83,3112.67 905.564,3119.68 897.779,3130.24 886.92,3126.88 888.623,3139.49 877.758,3148.68 875.629,3136.95 870.838,3144.55 856.642,3144.36 846.544,3137.47 819.64,3146.92 814.402,3141.68 812.242,3146.82 812.282,3156.77 782.761,3193.85 773.2,3193.11 786.207,3176.04 780.156,3172.55 773.188,3178.62 768.431,3178.57 769.358,3159.3 747.17,3171.57 716.781,3172.24 679.897,3188.04 661.696,3189.71 664.258,3199.07 657.776,3204.03 645.171,3201.29 629.122,3204.72 621.295,3199.14 609.151,3197.57 599.173,3208.63 599.17,3215.85 586.153,3226.97 560.976,3226.77 540.143,3235.42 533.188,3226.63 539.698,3219.29 567.487,3209.5 573.125,3202.7 575.723,3183.32 570.936,3175.91 565.296,3180.45 564.876,3196.36 560.113,3201 542.296,3197.89 532.525,3184.98 534.937,3173.17 546.22,3172.67 555.331,3177.38 560.044,3137.2 544.117,3127.6 540.111,3106.4 569.635,3070.42 564.025,3061.07 528.397,3088.6 505.365,3095.39 495.474,3086.45 479.701,3086.82 479.662,3077.15 494.459,3053.5 485.448,3046.64 479.824,3051.51 441.956,3058.82 431.993,3049.37 423.925,3048.85 425.606,3027.77 422.098,3025.01 413.217,3030.73 402.264,3020.74 405.489,3016.74 412.964,3017.12 413.36,3009.16 405.308,3001.37 383.919,3002.04 367.22,3006.12 367.985,2998.1 375.283,2987.85 383.218,2988.61 390.139,2970.75 383.336,2967.69 363.077,2978.55 358.094,3000.15 346.88,3001.15 342.51,2982.42 328.157,2969.79 317.118,2940.85 317.44,2922.78 312.318,2914.66 311.779,2901.47 309.348,2892.27 311.198,2886.84 314.431,2884.63 316.01,2879.55 300.748,2870.3 299.889,2864.62 313.266,2861.92 313.722,2854.08 307.199,2847.1 311.04,2843.08 318.389,2842.59 324.87,2855.63 331.73,2861.06 333.992,2853.29 323.011,2841.9 318.655,2817.98 326.984,2813.34 331.534,2820.35 338.516,2806.33 345.896,2764.2 353.463,2769.24 357.298,2764.37 356.504,2757.75 361.247,2733.23 350.93,2709.05 352.877,2706.01 357.594,2704.47 364.653,2707.23 370.088,2706.24 366.434,2697.31 355.147,2691.36 354.27,2683.4 361.873,2683.69 373.855,2687.23 373.514,2682.72 366.895,2677.37 359.79,2662.94 362.789,2657.25 368.402,2657.65 377.325,2667.83 384.023,2668.06 371.05,2638.93 371.061,2612.51 357.59,2595.07 360.297,2589.1 368.184,2588.27 368.696,2583.58 362.645,2578.87 358.927,2555.16 349.954,2549.66 347.236,2539.57 339.362,2526.5 346.611,2498.97 354.361,2486.29 353.9,2475 365.851,2462.21 364.27,2454.11 349.269,2448.25 349.233,2436.92 359.461,2423.29 360.11,2416.17 338.319,2415.1 331.84,2405.05 337.853,2381.11 333.22,2376.18 335.43,2357.44 345.35,2341.23 344.328,2334.69 339.132,2330.79 332.311,2336.53 328.473,2331.91 331.715,2311.25 336.643,2305.46 343.06,2299.64 344.031,2290.92 337.303,2283.26 338.504,2278.41 349.848,2279 355.58,2272.87 358.574,2254.71 369.587,2250.92 370.303,2256.45 381.609,2255.16 385.901,2250.78 384.587,2240.35 395.125,2230.34 396.191,2218.55 391.702,2208.89 381.18,2200.87 385.845,2193.29 395.853,2199.94 402.206,2197.86 411.394,2200.31 416.553,2198.31 413.408,2190.53 403.459,2181.86 402.223,2173.97 410.657,2163.49 411.427,2141.71 419.5,2133.51 424.363,2148.04 435.891,2147.78 460.629,2137.37 495.38,2149.82 508.39,2146.78 516.539,2131.32 527.665,2131.1 532.104,2120.31 519.963,2093.06 514.431,2087.5 512.029,2079.73 516.005,2074.45 523.646,2074 528.625,2052.44 535.479,2048.67 542.07,2057.32 545.861,2040.72 554.878,2034.13 555.89,2029.24 565.518,2020.94 572.222,2018.05 574.065,2009.34 586.191,2001.6 587.76,1989.75 584.997,1973.56 594.918,1967 604.682,1952.39 617.806,1952.46 623.807,1959.69 630.435,1959.54 636.315,1950.95 684.379,1948.78 685.437,1902.79 693.471,1897.06 705.358,1908.41 714.896,1906.75 716.105,1883.13 733.448,1856.71 740.913,1850.69 749.922,1837.06 757.474,1842.06 763.625,1838.73 763.857,1823.97 771.579,1811.3 774.609,1804.09 794.931,1782.31 812.447,1770.7 813.334,1763.68 826.035,1753.87 836.256,1710.62 855.481,1697.25 860.633,1670.62 873.052,1669.18 877.301,1661.48 884.505,1655.08 906.039,1654.86 915.554,1647.45 933.954,1647.6 953.652,1659.04 955.431,1669.57 964.448,1670.35 969.609,1665.68 965.659,1653.85 946.032,1634.14 944.869,1625.57 947.233,1618.86 960.695,1620.02 975.171,1631.73 981.608,1632.03 982.389,1626.32 972.932,1616.68 969.772,1595.81 964.457,1586.08 951.99,1578.88 947.584,1569.28 956.308,1557.58 956.404,1526.28 950.936,1516.19 957.26,1508.46 957.234,1493.78 965.442,1485.06 966.46,1472.57 947.684,1439.17 943.014,1443.47 936.023,1443.43 935.451,1430.3 927.013,1421.66 918.091,1422.49 909.761,1411.71 895.771,1409.63 888.751,1415.36 880.458,1416.2 876.5,1403.43 866.303,1410.09 860.985,1403.94 868.363,1388.45 861.805,1378.74 840.805,1370.97 831.074,1359.29 823.287,1371.7 812.149,1372.98 811.888,1350.9 801.684,1323.4 800.196,1303.55 783.321,1276.01 782.238,1255.29 761.961,1235.63 754.073,1196.49 758.7,1184.48 754.505,1167.65 760.527,1149.03 765.291,1133.49 783.076,1118.06 786.503,1061.56 804.095,1042.11 756.34,931.753 757.445,900.132 781.291,887.737 775.935,869.381 783.001,853.424 755.287,848.647 743.601,827.609 758.747,788.675 757.551,731.659 757.953,713.103 766.703,698.359 777.759,685.217 751.185,657.554 745.169,628.899 730.742,630.925 724.506,613.838 724.42,584.796 677.125,541.217 633.583,521.252 600.882,513.796 591.826,487.604 569.502,476.682 560.728,454.646 536.845,447.227 504.106,379.259 481.261,373.099 479.491,346.63 449.668,308.064 472.929,285.304 505.76,310.727 510.988,292.53 500.788,265.596 518.159,244.839 544.067,232.093 585.676,246.547 656.063,389.248 654.014,423.839 671.82,416.349 702.653,438.674"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91167528"
- class="fil0 str0"
- points="892.558,1634.74 881.896,1628.14 870.453,1631.06 860.036,1606.73 866.113,1595.44 899.535,1587.62 908.877,1598.64 918.083,1598.51 923.98,1595.47 929.149,1600.17 928.93,1606.22 916.609,1611.27 904.132,1603 894.158,1605.66 901.318,1628.45"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91167456"
- class="fil0 str0"
- points="951.187,1592.83 944.242,1592.83 937.731,1587.19 941.204,1581.11 949.971,1584.43"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91167384"
- class="fil0 str0"
- points="720.706,1869.96 713.327,1870.39 715.497,1858.67 723.31,1855.63 725.133,1861.99"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91167312"
- class="fil0 str0"
- points="570.525,1995.92 565.75,1986.37 570.959,1969.43 577.903,1975.51 576.704,1989.53"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91167240"
- class="fil0 str0"
- points="452.897,2090.62 448.122,2078.89 457.238,2076.28 461.144,2080.19 460.813,2088.57"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91167168"
- class="fil0 str0"
- points="469.825,2119.28 479.808,2103.21 488.923,2103.21 494.523,2108.46 491.136,2114.13 481.213,2114.63 474.6,2119.72"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91167096"
- class="fil0 str0"
- points="478.94,2137.53 475.034,2128.84 488.055,2120.59 501.968,2126.49 508.455,2123.19 509.281,2133.22 503.724,2143.67 490.328,2137.22"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91167024"
- class="fil0 str0"
- points="426.42,2139.27 426.42,2128.84 434.233,2119.72 446.344,2130.17 444.259,2136.72 436.94,2129.83 432.063,2140.57"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91166952"
- class="fil0 str0"
- points="368.691,2091.92 374.291,2091.95 374.437,2101.6 368.257,2111.03 360.01,2111.03 363.483,2101.91"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91166880"
- class="fil0 str0"
- points="385.185,2100.61 392.521,2100.64 396.139,2108.98 389.96,2117.11 379.543,2117.11 374.768,2108.86"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91166808"
- class="fil0 str0"
- points="363.049,2158.81 356.104,2158.38 346.555,2121.89 353.065,2119.72 358.254,2125.56 367.337,2116.45 373.466,2121.89 373.643,2128.93 367.395,2134.92 370.679,2140.64 380.882,2140.97 384.805,2132.63 393.218,2134.91 400.059,2149.8 395.924,2160.55 384.637,2156.59 378.198,2166.66 369.228,2164.58"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91166736"
- class="fil0 str0"
- points="305.32,2207.46 311.788,2210.1 311.5,2217.57 308.792,2223.1 302.716,2223.1 299.243,2216.58"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91166664"
- class="fil0 str0"
- points="346.555,2225.7 346.555,2211.8 352.197,2208.33 359.013,2213.87 359.968,2221.39 357.943,2230.61 352.197,2230.48"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91166592"
- class="fil0 str0"
- points="340.478,2259.15 349.55,2254.84 353.602,2263.62 347.857,2267.84 342.648,2272.18 335.269,2267.84"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91166520"
- class="fil0 str0"
- points="326.588,2290.86 330.452,2290.02 336.24,2301.84 334.401,2304.76 327.891,2305.19 325.72,2300.85"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91166448"
- class="fil0 str0"
- points="324.809,2346.49 331.466,2353.97 331.797,2358.19 324.852,2362.09 319.644,2356.88 321.773,2350.78"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91166376"
- class="fil0 str0"
- points="325.245,2779.5 326.695,2776.72 330.018,2773.03 335.896,2776.72 337.44,2783.86 333.533,2789.08 327.891,2789.51"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91166304"
- class="fil0 str0"
- points="272.766,3011.9 264.519,3010.17 262.843,2978.21 269.052,2977.83 279.711,2993.66"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91166232"
- class="fil0 str0"
- points="247.784,2994.34 255.34,3006.32 252.8,3017.99 244.987,3022.33 238.476,3007.56 239.838,2999.49"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91166160"
- class="fil0 str0"
- points="264.712,3016.49 271.4,3024.56 268.86,3039.27 263.651,3044.05 257.14,3040.14 254.162,3025.55"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91166088"
- class="fil0 str0"
- points="240.646,3045.78 232.834,3047.96 227.625,3042.31 230.856,3032.13 240.582,3036.29"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91166016"
- class="fil0 str0"
- points="207.225,3045.35 207.225,3044.92 210.022,3036.03 215.841,3031.95 221.114,3037.1 217.208,3047.09 209.838,3048.7"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91165944"
- class="fil0 str0"
- points="211.131,3074.02 210.263,3069.67 210.022,3060.79 218.88,3056.71 224.153,3064.03 225.889,3068.37 215.915,3077.37"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91165872"
- class="fil0 str0"
- points="195.939,3087.92 192.901,3075.76 196.132,3070.35 202.386,3071.48 204.62,3077.06 204.609,3081.37 205.932,3087.8"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91165800"
- class="fil0 str0"
- points="200.289,3115.16 188.56,3114.41 185.836,3102.31 180.314,3096.17 186.149,3087.72 195.875,3093.63 202.016,3107.03 200.703,3110.04"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91165728"
- class="fil0 str0"
- points="163.395,3039.15 140.815,3037.53 141.249,3030.58 147.084,3026.04 163.374,3034.02"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91165656"
- class="fil0 str0"
- points="162.305,3068.36 154.259,3079.63 149.071,3079.54 149.935,3064.62 143.853,3058.38 150.798,3051.43 156.633,3046.89 160.407,3053.17 157.211,3060.58"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91165584"
- class="fil0 str0"
- points="151.655,3146.96 136.484,3146.44 133.441,3141.5 147.326,3130.05 154.897,3124.21 173.863,3126.57 178.914,3132.68 172.288,3140.89"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91165512"
- class="fil0 str0"
- points="166.183,3106.84 171.969,3107.92 178.799,3114.4 179,3119.16 166.867,3117.77 161.654,3111.96"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91165440"
- class="fil0 str0"
- points="123.462,3114.73 121.721,3099.37 131.459,3087.72 135.232,3088.35 136.811,3096.63 131.054,3107.45 134.293,3114.81"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91165368"
- class="fil0 str0"
- points="98.813,3085.09 90.3449,3105.11 92.4564,3108.56 100.794,3108.78 105.859,3105.46 122.12,3114.24 122.2,3120.94 118.794,3128.57 124.795,3134.78 123.752,3142.38 113.857,3149.22 111.359,3138.67 104.948,3139.89 100.309,3129.31 86.3825,3119.37 74.1171,3122.07 72.4157,3111.57 67.6728,3105.54 58.1744,3104.57 52.4884,3098.18 50.8534,3085.95 41.1199,3074.77 34.4915,3074.87 29.1595,3073.65 26.3728,3083.28 18.8654,3083.7 13.3646,3071.39 16.3306,3058.37 11.012,3052.68 14.3162,3043.96 33.5849,3035.75 42.3408,3038.52 51.701,3037.09 59.1953,3027.51 67.5138,3032.8 65.2332,3047.71 71.3886,3049.28 76.6471,3043.26 74.7148,3038.85 74.6712,3032.67 70.0742,3024.81 55.7411,3022.76 68.3286,3006.26 80.6746,3000.85 96.5307,3016.21 111.167,3018.9 117.585,3029.69 126.015,3033.32 127.334,3043.78 137.343,3055.96 129.954,3077.59 112.327,3080.44 101.229,3068.17 94.4933,3067.5 88.7378,3077.46"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91165296"
- class="fil0 str0"
- points="240.529,3169.96 238.749,3175.41 232.835,3175.24 227.614,3183.44 214.613,3173.8 217.212,3166.26 230.856,3159.83 234.906,3162.65 242.604,3166.52"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91165224"
- class="fil0 str0"
- points="925.18,3112.1 932.084,3112.1 935.15,3113.47 940.911,3113.82 938.458,3118.35 935.188,3121.94 924.874,3122.62 922.573,3118.73 920.359,3116.23"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91165152"
- class="fil0 str0"
- points="956.431,3114.27 958.424,3131.82 952.116,3132.8 950.352,3129.15 950.309,3119.71"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91165080"
- class="fil0 str0"
- points="970.755,3094.72 972.868,3106.03 978.467,3112.69 978.256,3120.46 976.76,3122.09 976.655,3125.74 971.522,3131.08 966.873,3127.16 966.412,3113.95 965.935,3096.25"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91165008"
- class="fil0 str0"
- points="1018.4,3119.64 1020.93,3124.87 1014.49,3131.51 1001.6,3129.76 1001.14,3125.24 1002.39,3118.84 1008.15,3117.26 1011.56,3114.27"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91164936"
- class="fil0 str0"
- points="1038.46,3103.96 1051.49,3097.33 1053.99,3108.34 1044.88,3110.23"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91164864"
- class="fil0 str0"
- points="1056.69,3091.36 1058.77,3084.39 1065.81,3084.3 1070.49,3094.88 1064.41,3098.07 1057.81,3094.22"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91164792"
- class="fil0 str0"
- points="1113.02,3078.37 1112.59,3085.47 1097.3,3082.93 1093.15,3076.16 1097.4,3070.49"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91164720"
- class="fil0 str0"
- points="1157.3,3082.72 1153.82,3088.51 1147.22,3084.67 1141.77,3080.94 1151.22,3073.1"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91107264"
- class="fil0 str0"
- points="1130.82,3055.78 1132.99,3063.75 1119.87,3073.81 1112.25,3067.04 1123.01,3055.72"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91107192"
- class="fil0 str0"
- points="1214.16,3108.49 1205.38,3108.12 1205.57,3100.48 1210.19,3095.95 1212.42,3096.12 1218.33,3101.66 1221.53,3104"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91107120"
- class="fil0 str0"
- points="1197.23,3075.77 1191.15,3075.91 1185.85,3063.38 1189.95,3049.66 1197.23,3052.25"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91107048"
- class="fil0 str0"
- points="344.384,2648.78 349.552,2643.54 351.287,2631.43 356.207,2632.83 366.087,2650.95 361.378,2656.18 351.329,2656.16"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91106976"
- class="fil0 str0"
- points="295.529,2971.31 308.358,2990.62 308.358,3000.61 299.677,3000.61 294.427,2993.64 291.924,2974.3"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91106904"
- class="fil0 str0"
- points="331.797,3006.69 324.877,3005.19 313.092,2990.17 313.193,2977.77 317.666,2973.92 328.759,2985.41 329.231,2987.11 336.138,2993.66"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91106832"
- class="fil0 str0"
- points="303.342,2946.12 310.095,2951.09 310.963,2966.3 304.018,2973.25 294.861,2963.67 293.66,2953.01"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91106760"
- class="fil0 str0"
- points="331.857,3205.19 341.683,3205.66 343.048,3210.35 335.282,3215.49 329.182,3220.36 321.389,3216.37"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91106688"
- class="fil0 str0"
- points="353.509,3179.88 358.325,3174.39 362.675,3167.4 368.594,3173.08 368.657,3186.46 365.666,3190.73 356.961,3189.96"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91106616"
- class="fil0 str0"
- points="287.09,3032.75 279.711,3027.11 281.073,3016.86 286.414,3013.45 291.366,3023.26"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91106544"
- class="fil0 str0"
- points="302.474,3033.43 308.728,3042.37 306.622,3046.22 297.507,3047.09 293.167,3041.44 295.831,3034.24"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91106472"
- class="fil0 str0"
- points="319.402,3019.96 321.38,3034.06 318.157,3035.15 315.303,3039.7 310.963,3033.62 312.325,3020.77"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91106400"
- class="fil0 str0"
- points="339.176,3031.45 339.236,3023.38 354.56,3013.88 356.538,3020.59 350.692,3028.72 348.107,3033.41 341.346,3033.62"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91106328"
- class="fil0 str0"
- points="321.801,3090.79 320.76,3098.6 315.034,3100.47 308.792,3103.12 288.826,3096.17 291.924,3078.11 298.568,3077.3 304.387,3084.07 322.248,3083.57"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91106256"
- class="fil0 str0"
- points="352.133,3102.75 350.33,3110.47 349.762,3116.42 347.41,3120.33 341.16,3124.66 328.055,3125.23 322.248,3117.89 330.061,3110.07 331.066,3108.12 341.406,3096.35 351.956,3095.54"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91106184"
- class="fil0 str0"
- points="304.886,3077.06 308.172,3073.76 308.791,3071.41 314.495,3065.51 322.007,3064.27 320.946,3074.45 314.869,3081.4 309.4,3080.19"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91106112"
- class="fil0 str0"
- points="338.742,3093.56 333.099,3089.22 333.593,3068.55 339.369,3065.14 350.192,3087.44"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91106040"
- class="fil0 str0"
- points="383.075,3010.35 393.191,3016.49 394.3,3021.89 411.428,3046.36 409.442,3055.33 408.692,3064.04 401.4,3071.3 391.758,3069.68 392.334,3063.18 394.302,3052.47 384.982,3044.8 376.938,3026.67 378.674,3014.08"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91105968"
- class="fil0 str0"
- points="368.071,3124.66 360.175,3121.75 362.605,3104.94 365.219,3094.43 383.208,3094.24 393.368,3101.45 388.961,3107.86 377.541,3110.77"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91105896"
- class="fil0 str0"
- points="355.915,3044.14 358.768,3039.89 372.356,3044.29 373.466,3050.56 374.131,3056.09 363.917,3058.38 354.802,3050.13"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91105824"
- class="fil0 str0"
- points="378.405,3129.14 375.192,3123.61 384.751,3114.41 404.653,3124.03 402.716,3129.45"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91105752"
- class="fil0 str0"
- points="400.107,3114.37 399.933,3104.07 415.135,3095.74 420.713,3099.27 415.303,3112.51"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91105680"
- class="fil0 str0"
- points="484.149,3064.9 449.426,3104.6 439.897,3105.42 433.162,3097.79 434.794,3088.66 423.633,3085.46 421.211,3076.19 428.723,3061.89 440.744,3064.9 451.221,3063.78 479.133,3056.88"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91105608"
- class="fil0 str0"
- points="445.687,3125.1 440.908,3120.02 454.189,3104.07 463.314,3103.56 468.892,3107.09 460.565,3119.08 459.171,3118.43 453.445,3125.11"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91105536"
- class="fil0 str0"
- points="476.587,3127.59 475.468,3120.93 469.524,3113.58 475.468,3108.33 475.527,3102.43 479.816,3098.14 488.937,3104.5 546.41,3090.76 531.026,3112.24 539.638,3131.74 524.275,3148.27 524.517,3158.02 518.462,3166.46 505.873,3168.41 490.262,3162.06 480.217,3168.39 464.774,3167.46 456.601,3155.12 459.535,3140.79"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91105464"
- class="fil0 str0"
- points="500.932,3186.84 497.368,3191.84 483.015,3188.96 477.802,3177.79 482.403,3174 493.264,3175.66"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91105392"
- class="fil0 str0"
- points="455.089,3173.51 455.969,3173.02 459.398,3170.09 466.353,3174.36 465.774,3182.06 464.38,3188.36 453.066,3188.09 450.891,3177.35"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91105320"
- class="fil0 str0"
- points="455.666,3214.27 468.513,3200.93 480.242,3201.72 479.663,3210.73 467.389,3219.36"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91105248"
- class="fil0 str0"
- points="537.701,3142.6 545.34,3134.91 552.295,3137.44 548.677,3145.58 539.905,3147.1"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91105176"
- class="fil0 str0"
- points="537.093,3150.98 545.35,3163.5 538.981,3167.25 531.315,3170.77 527.284,3159.11"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91105104"
- class="fil0 str0"
- points="623.04,3214.18 632.594,3211.71 629.263,3219.37 624.842,3220.55 619.862,3223.33 614.304,3221.84 610.188,3219.05 615.656,3212.66"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- <polygon
- id="_91105032"
- class="fil0 str0"
- points="709.416,3181.17 712.578,3182.96 718.244,3182.88 707.745,3191.88 698.859,3199.44 690.487,3195.16 695.955,3185.29 702.946,3181.16"
- style="fill: rgb(238, 238, 212); stroke: rgb(31, 26, 23); stroke-width: 3.98996;" />
- </g>
- <polygon
- class="fil1 str1"
- points="892.558,1634.74 881.896,1628.14 870.453,1631.06 860.036,1606.73 866.113,1595.44 899.535,1587.62 908.877,1598.64 918.083,1598.51 923.98,1595.47 929.149,1600.17 928.93,1606.22 916.609,1611.27 904.132,1603 894.158,1605.66 901.318,1628.45"
- id="polygon84"
- style="fill: none; stroke: rgb(140, 140, 96); stroke-width: 1.70998;" />
- <polygon
- class="fil1 str1"
- points="951.187,1592.83 944.242,1592.83 937.731,1587.19 941.204,1581.11 949.971,1584.43"
- id="polygon86"
- style="fill: none; stroke: rgb(140, 140, 96); stroke-width: 1.70998;" />
- <polygon
- class="fil1 str1"
- points="714.87,1862.05 715.497,1858.67 723.31,1855.63 725.133,1861.99 722.576,1866.59 720.706,1869.96 713.327,1870.39"
- id="polygon88"
- style="fill: none; stroke: rgb(140, 140, 96); stroke-width: 1.70998;" />
- <g
- id="_124239120">
- <polygon
- id="_124840120"
- class="fil1 str2"
- points="1266.81,1320.59 1280.73,1355.15 1348.52,1365.88 1378.48,1352.79 1379.62,1333.66 1364.8,1311.34 1383.24,1302.42 1401.44,1307.59 1406.94,1303.11 1406.59,1286.23 1393.99,1277.05 1394.3,1259.63 1403.72,1258.16 1408.29,1226.72 1389.74,1218.91 1377.03,1191.57 1381.94,1173.14 1397,1167.18 1396.51,1150.45 1471.15,1167.96 1516.62,1162.12 1504.59,1129.9 1439.79,1020.47 1447.28,995.77 1545.9,810.813 1549.63,765.543 1503.25,730.84 1455.73,633.814 1383.06,604.25 1358.46,501.718 1387.41,449.541 1393.92,402.814 1385.74,388.966 1352.78,389.081 1406.98,343.479 1396.63,307.18 1400.14,273.285 1452.27,205.546 1422.82,130.452 1335.1,87.2276 1333.06,68.1732 1306.22,51.2835 1278.39,12.5376 1262.71,22.4227 1247.21,17.3925 1236.46,33.0009 1193.47,67.0789 1143.85,54.1508 1115.32,64.1525 1097.91,105.588 1068.55,131.72 1054.1,154.879 1059.65,170.934 1050.21,188.127 1031.81,293.372 1035.53,355.861 1025.49,391.044 1005.05,385.808 986.507,396.951 961.225,434.135 964.057,470.073 946.707,469.967 940.503,482.635 916.245,452.767 872.378,433.58 830.941,402.881 809.986,413.882 798.888,433.452 771.196,443.235 741.874,456.449 734.897,442.02 702.653,438.674 671.82,416.349 654.014,423.839 656.063,389.248 585.676,246.547 544.067,232.093 518.159,244.839 500.788,265.596 510.988,292.53 505.76,310.727 472.929,285.304 449.668,308.064 479.491,346.63 481.261,373.099 504.106,379.259 536.845,447.227 560.728,454.646 569.502,476.682 591.826,487.604 600.882,513.796 633.583,521.252 677.125,541.217 724.42,584.796 724.506,613.838 730.742,630.925 745.169,628.899 751.185,657.554 777.759,685.217 766.703,698.359 757.953,713.103 757.551,731.659 758.747,788.675 743.601,827.609 755.287,848.647 783.001,853.424 775.935,869.381 781.291,887.737 757.445,900.132 756.34,931.753 804.095,1042.11 786.503,1061.56 783.076,1118.06 765.291,1133.49 760.527,1149.03 754.505,1167.65 758.7,1184.48 754.073,1196.49 761.961,1235.63 782.238,1255.29 783.321,1276.01 800.196,1303.55 801.684,1323.4 811.888,1350.9 812.149,1372.98 823.287,1371.7 831.074,1359.29 840.805,1370.97 861.805,1378.74 868.363,1388.45 860.985,1403.94 866.303,1410.09 876.5,1403.43 880.458,1416.2 888.751,1415.36 895.771,1409.63 909.761,1411.71 918.091,1422.49 927.013,1421.66 933.578,1428.39 932.974,1428.95 948.026,1413.68 969.415,1402.58 972.617,1387.74 1026.26,1390.81 1072.98,1361.38 1076.5,1391.52 1168.84,1399.51 1200.14,1388.84 1242.83,1319.3 1256.46,1325.5"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <path
- id="_124840072"
- class="fil1 str2"
- d="m 1556.25,1452.97 5.5914,-18.8591 -10.735,-17.7727 28.3729,-18.895 19.2912,-1.8143 -8.764,-61.5248 -29.6724,-84.6324 -24.8936,-36.6968 -18.8186,-50.6542 -45.4721,5.8399 -74.6438,-17.5068 0.4953,16.727 -15.0601,5.9613 -4.913,18.427 12.7111,27.3457 18.5473,7.806 -4.5671,31.4386 -9.4191,1.468 -0.3178,17.4253 12.6011,9.1832 0.3545,16.8795 -5.4959,4.4807 -18.2053,-5.1775 -18.4353,8.9232 14.8173,22.3207 -1.1397,19.1241 -29.9606,13.0916 -67.7902,-10.7227 -13.9232,-34.5616 -10.3497,4.9034 -13.6291,-6.2001 -42.6871,69.5464 -31.3063,10.6697 -92.3395,-7.9905 -3.5191,-30.1461 -46.7181,29.435 -53.6418,-3.0657 -3.20165,14.8349 -21.389,11.1046 -14.4268,14.7101 c 0.61645,0.6401 1.23375,1.2765 1.85162,1.9095 l 0.5717,13.1287 6.99154,0.034 4.66996,-4.3003 18.7756,33.4082 -1.01801,12.4857 -8.20819,8.7163 0.0265,14.6822 -6.32465,7.736 5.46852,10.0852 -0.0958,31.3038 -8.72432,11.6929 4.40577,9.607 12.4669,7.1978 5.31548,9.7304 3.15976,20.8652 9.45734,9.64 -0.78146,5.7139 -6.43722,-0.3027 -14.4753,-11.7085 -13.4618,-1.1616 -2.36462,6.7097 1.16336,8.5752 19.6272,19.7044 3.94949,11.8288 -5.16072,4.6786 -9.01673,-0.7858 -1.77952,-10.5332 -19.6978,-11.4364 -18.4003,-0.1485 -9.5149,7.4068 -21.5341,0.2203 -7.20358,6.4022 -4.24902,7.7049 -12.4196,1.4361 -5.15132,26.6321 -19.2253,13.3669 -10.2214,43.2491 -12.7003,9.811 -0.88691,7.0226 -17.5159,11.6039 -20.3226,21.7823 -3.03009,7.2107 -7.72227,12.6701 -0.23142,14.7626 -6.15109,3.3257 -7.55185,-5.0026 -9.00961,13.6377 -7.46492,6.0126 -7.46207,11.3685 -9.88027,15.0535 -1.20896,23.6197 19.9116,27.4683 12.4353,-0.1647 9.3744,8.4447 7.81005,-4.2502 -8.97085,-12.1762 8.12612,-15.2619 20.6295,-4.0073 9.47358,37.8285 10.8473,5.6421 5.0111,21.0644 14.8338,5.8418 16.5347,49.7114 62.192,75.7388 17.5817,-2.3324 6.51018,-40.4539 14.8007,-6.1471 46.9185,32.1875 23.71265,0.075 9.5391,7.9546 8.9601,18.917 31.0208,-0.2184 16.2223,-45.8976 8.3145,-4.9883 -7.4915,-76.0138 50.0064,-46.2031 34.5841,-11.6481 -10.8949,-13.7024 0.01,-70.4207 -15.6808,-10.4317 -11.7866,1.6365 -14.5631,-12.7616 2.2868,-14.2527 -7.4356,-16.466 -13.2895,-8.7172 25.1903,-25.7059 13.2824,-3.8956 4.9484,-16.0071 28.5114,-13.9073 10.0627,-29.1845 26.0262,-12.4088 0.8442,-7.4248 30.6067,7.05 5.7444,-15.4713 -2.4769,-41.0746 -17.2226,-14.4092 12.763,-20.9567 28.0135,0.1237 14.5759,-10.8689 16.226,2.1158 14.2766,9.8572 6.1377,-37.7196 14.9643,-9.1062 72.6517,-13.0435 3.3834,-33.7299 41.1154,-19.4029 8.7312,7.1346 14.8529,-4.4696 12.5002,-26.7863 6.0642,5.0325 35.1387,1.6572 36.9117,-7.1722 z"
- inkscape:connector-curvature="0"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124839760"
- class="fil1 str2"
- points="1646.69,1982.92 1681,1893.37 1670.36,1843.89 1615.98,1806.59 1600.45,1764.83 1600.37,1741.99 1611.43,1732.28 1612.08,1712.15 1601.44,1698.83 1605.92,1682.79 1555.24,1672.39 1540.33,1615.02 1545.72,1594.85 1565.07,1588.4 1572.7,1572.6 1565.67,1563.26 1574.25,1545.67 1566.06,1536.2 1539.81,1533.78 1550.79,1496.63 1552.94,1464.05 1556.39,1452.45 1519.34,1460.14 1484.2,1458.48 1478.14,1453.45 1465.64,1480.24 1450.78,1484.71 1442.05,1477.57 1400.94,1496.98 1397.55,1530.71 1324.9,1543.75 1309.94,1552.85 1303.8,1590.57 1289.52,1580.72 1273.3,1578.6 1258.72,1589.47 1230.71,1589.35 1217.95,1610.3 1235.17,1624.71 1237.65,1665.79 1231.9,1681.26 1201.29,1674.21 1200.45,1681.63 1174.42,1694.04 1164.36,1723.23 1135.85,1737.13 1130.9,1753.14 1117.62,1757.04 1092.43,1782.74 1105.72,1791.46 1113.15,1807.93 1110.87,1822.18 1125.43,1834.94 1137.22,1833.3 1152.9,1843.74 1152.89,1914.16 1163.78,1927.86 1207.19,1944.29 1258.55,1948.2 1320.53,1987.87 1360.91,2034.47 1387.76,1972.61 1455.48,1985.14 1556.27,1967.15 1577.17,2020.35 1590.75,2005.54 1616.07,2007.81 1614.27,2006.04"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124839736"
- class="fil1 str2"
- points="1485.88,2248.99 1464.08,2264.8 1481.78,2288.71 1463.16,2314.29 1438.17,2303.4 1434.12,2315.59 1421.03,2319.07 1438.93,2358.55 1451.15,2362.31 1479.1,2388 1481.01,2398.62 1495.39,2410.75 1489.33,2425.11 1503.41,2435.19 1517.62,2426.52 1526.07,2436.91 1526.09,2453.63 1544.88,2484.29 1556.03,2545.38 1575.32,2553.81 1583.06,2571.55 1576.69,2579.58 1588.01,2602.55 1575.24,2639.59 1665.27,2590.89 1683.08,2572.45 1723.18,2502.21 1752.06,2457.97 1771.07,2450.53 1806.32,2384.96 1848.05,2252.59 1835.88,2221.84 1800.69,2193.23 1789.05,2153.18 1763.98,2135.88 1732.06,2110.73 1687.04,2090.28 1668.91,2064.69 1615.81,2008.01 1590.62,2005.73 1577.04,2020.53 1556.13,1967.36 1455.35,1985.35 1387.63,1972.83 1371.85,2008.96 1391.5,2030.84 1407.04,2032.02 1411,2064.1 1419.71,2071.17 1413.09,2080.85 1417.03,2117.75 1432.35,2126.8 1432.73,2148.51 1419.08,2173.46 1430.02,2183.28 1453.3,2232.2"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124836256"
- class="fil1 str2"
- points="1110.41,2684 1091.63,2678 1088.98,2685.08 1078.95,2711.93 1075.46,2744.04 1085.02,2750.82 1085.72,2763.48 1100.22,2777.05 1108.9,2778.31 1110.07,2793.94 1120.95,2789.57 1137.1,2815.17 1152.26,2807.36 1152.52,2791.73 1172.74,2792.15 1172.81,2819.03 1200.87,2832.93 1217.13,2827.42 1238.68,2822.25 1231.64,2807.96 1237.75,2796.12 1219.84,2776.96 1201.56,2779.62 1182.67,2768.32 1189.19,2758.34 1204.56,2759.61 1208.29,2752.58 1246.36,2752.77 1270.32,2767.13 1291.58,2758.42 1324.79,2765.24 1374.61,2760.91 1400.05,2729.45 1407.65,2710.65 1421.92,2721.53 1459.43,2721.3 1464.27,2704.28 1494.89,2705.66 1525.75,2695.78 1544.82,2664.15 1569.12,2655.94 1574.78,2639.83 1575.24,2639.59 1588.01,2602.55 1576.69,2579.58 1583.06,2571.55 1575.32,2553.81 1556.03,2545.38 1544.88,2484.29 1526.09,2453.63 1526.07,2436.91 1517.62,2426.52 1503.41,2435.19 1489.33,2425.11 1495.39,2410.75 1481.01,2398.62 1479.1,2388 1451.15,2362.31 1438.93,2358.55 1428.86,2361.48 1402.76,2387.27 1389.03,2387.28 1389.08,2416.75 1377.16,2415.27 1367.72,2430.91 1378.59,2439.15 1372.33,2451.98 1390.09,2451.29 1391.34,2466.37 1408.03,2462.28 1431.03,2490.93 1423.76,2508.74 1377.71,2490.78 1349.11,2494.04 1331.64,2478.64 1306,2477.13 1291.23,2451.36 1240.04,2406.84 1215.45,2423.49 1204.84,2410.01 1183.37,2415.36 1177.82,2423.69 1162.88,2417.16 1146.97,2425.78 1136.42,2433.1 1153.07,2451.48 1138.33,2456.7 1129.62,2493.64 1111.94,2484.65 1087.34,2499.92 1073.45,2528.26 1095.71,2569.11 1089.18,2578.96 1094.35,2633.26 1115.66,2664.63"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124857376"
- class="fil1 str2"
- points="1430.02,2183.28 1419.08,2173.46 1432.73,2148.51 1432.35,2126.8 1417.03,2117.75 1413.09,2080.85 1419.71,2071.17 1411,2064.1 1407.04,2032.02 1391.5,2030.84 1371.85,2008.96 1360.87,2034.42 1320.53,1987.87 1258.55,1948.2 1207.19,1944.29 1163.78,1927.86 1129.2,1939.51 1079.2,1985.78 1086.69,2061.72 1078.37,2066.71 1062.15,2112.61 1055.07,2138.69 1065.73,2153.22 1069.09,2206.51 1089.65,2234.84 1077.41,2243.02 1087.11,2252.61 1079.04,2266.19 1049.57,2270.03 1091.51,2322.46 1103.87,2319.42 1121.72,2346.67 1126.64,2375.5 1106.95,2396.56 1107,2405.1 1129.41,2419.45 1140.29,2418.05 1146.97,2425.78 1162.88,2417.16 1177.82,2423.69 1183.37,2415.36 1204.84,2410.01 1215.45,2423.49 1240.04,2406.84 1291.23,2451.36 1306,2477.13 1331.64,2478.64 1349.11,2494.04 1377.71,2490.78 1423.76,2508.74 1431.03,2490.93 1408.03,2462.28 1391.34,2466.37 1390.09,2451.29 1372.33,2451.98 1378.59,2439.15 1367.72,2430.91 1377.16,2415.27 1389.08,2416.75 1389.03,2387.28 1402.76,2387.27 1428.86,2361.48 1438.93,2358.55 1421.03,2319.07 1434.12,2315.59 1438.17,2303.4 1463.16,2314.29 1481.78,2288.71 1464.08,2264.8 1485.88,2248.99 1453.3,2232.2"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124853848"
- class="fil1 str2"
- points="701.798,2879.74 696.659,2884.78 676.072,2862.29 645.998,2873.75 631.458,2873.97 629.168,2863.92 614.825,2853.04 604.484,2859.38 604.271,2867.68 616.528,2875.01 608.333,2894.11 593.691,2897.09 592.29,2911.08 600.574,2920.76 593.733,2926.89 594.498,2938.88 619.967,2951.96 639.263,2942.32 674.917,2969.69 706.523,2980.15 752.417,2988.06 758.077,3000.59 768.943,2992.27 780.117,2997.59 782.852,3008.01 810.923,3002.5 809.7,2988.07 817.6,2977.44 835.253,2980.06 865.162,2976.12 875.258,2971.8 895.324,2977.5 893.857,2968.57 907.1,2958.94 897.939,2952.53 888.946,2960.18 891.799,2947.46 902.202,2944.25 897.85,2933.28 891.37,2919.27 901.478,2910.74 883.856,2889.32 891.308,2858.88 918.923,2842.42 916.723,2804.85 901.898,2793.4 890.301,2798.88 893.515,2786.84 868.71,2776.92 851.034,2784.83 839.203,2773 833.758,2785.32 808.832,2775.62 780.133,2798.12 775.339,2794.5 771.866,2799.95 772.241,2806.46 775.576,2810.39 766.709,2820.94 697.552,2847.18"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124859200"
- class="fil1 str2"
- points="875.177,2729.06 952.598,2721.78 968.256,2665.41 991.77,2654.62 1004.25,2660.56 1020.62,2632.25 1038.87,2641.43 1059.76,2673.6 1089.21,2685.26 1079.08,2712.26 1075.59,2744.39 1085.15,2751.18 1085.86,2763.84 1100.35,2777.42 1109.03,2778.68 1110.2,2794.33 1100.89,2799.5 1092.94,2820.34 1071.79,2834.66 1049.87,2834.59 1046.16,2848.06 1052.01,2860.71 1056.41,2883.28 1043.9,2882.52 1038.47,2892.87 1054.6,2899.79 1046.81,2914.56 1047.42,2931.6 1061.07,2940.64 1063.31,2956.43 1067.62,2958.58 1065.96,2972.56 1052.68,2979.68 1039.93,2968.24 1019.93,2972.61 1019.16,2958.78 1005.74,2968.25 997.134,2966.83 968.842,2975.59 961.777,2966.76 960.302,2967.6 953.263,2942.05 948.506,2937.81 932.585,2954.49 912.046,2929.51 897.85,2933.28 891.37,2919.27 901.478,2910.74 883.856,2889.32 891.308,2858.88 918.923,2842.42 916.723,2804.85 901.898,2793.4 890.301,2798.88 893.515,2786.84 868.71,2776.92 866.502,2724.03"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <g
- id="g99">
- <polygon
- id="_124835824"
- class="fil1 str2"
- points="272.766,3011.9 264.519,3010.17 262.843,2978.21 269.052,2977.83 279.711,2993.66"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124854976"
- class="fil1 str2"
- points="247.784,2994.34 255.34,3006.32 252.8,3017.99 244.987,3022.33 238.476,3007.56 239.838,2999.49"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124848616"
- class="fil1 str2"
- points="264.712,3016.49 271.4,3024.56 268.86,3039.27 263.651,3044.05 257.14,3040.14 254.162,3025.55"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124852216"
- class="fil1 str2"
- points="240.646,3045.78 232.834,3047.96 227.625,3042.31 230.856,3032.13 240.582,3036.29"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124865992"
- class="fil1 str2"
- points="207.225,3045.35 207.225,3044.92 210.022,3036.03 215.841,3031.95 221.114,3037.1 217.208,3047.09 209.838,3048.7"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124847728"
- class="fil1 str2"
- points="211.131,3074.02 210.263,3069.67 210.022,3060.79 218.88,3056.71 224.153,3064.03 225.889,3068.37 215.915,3077.37"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124856152"
- class="fil1 str2"
- points="195.939,3087.92 192.901,3075.76 196.132,3070.35 202.386,3071.48 204.62,3077.06 204.609,3081.37 205.932,3087.8"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124861384"
- class="fil1 str2"
- points="200.289,3115.16 188.56,3114.41 185.836,3102.31 180.314,3096.17 186.149,3087.72 195.875,3093.63 202.016,3107.03 200.703,3110.04"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124839040"
- class="fil1 str2"
- points="163.395,3039.15 140.815,3037.53 141.249,3030.58 147.084,3026.04 163.374,3034.02"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124846792"
- class="fil1 str2"
- points="162.305,3068.36 154.259,3079.63 149.071,3079.54 149.935,3064.62 143.853,3058.38 150.798,3051.43 156.633,3046.89 160.407,3053.17 157.211,3060.58"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124864792"
- class="fil1 str2"
- points="151.655,3146.96 136.484,3146.44 133.441,3141.5 147.326,3130.05 154.897,3124.21 173.863,3126.57 178.914,3132.68 172.288,3140.89"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124846936"
- class="fil1 str2"
- points="166.183,3106.84 171.969,3107.92 178.799,3114.4 179,3119.16 166.867,3117.77 161.654,3111.96"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124848880"
- class="fil1 str2"
- points="123.462,3114.73 121.721,3099.37 131.459,3087.72 135.232,3088.35 136.811,3096.63 131.054,3107.45 134.293,3114.81"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124866136"
- class="fil1 str2"
- points="98.813,3085.09 90.3449,3105.11 92.4564,3108.56 100.794,3108.78 105.859,3105.46 122.12,3114.24 122.2,3120.94 118.794,3128.57 124.795,3134.78 123.752,3142.38 113.857,3149.22 111.359,3138.67 104.948,3139.89 100.309,3129.31 86.3825,3119.37 74.1171,3122.07 72.4157,3111.57 67.6728,3105.54 58.1744,3104.57 52.4884,3098.18 50.8534,3085.95 41.1199,3074.77 34.4915,3074.87 29.1595,3073.65 26.3728,3083.28 18.8654,3083.7 13.3646,3071.39 16.3306,3058.37 11.012,3052.68 14.3162,3043.96 33.5849,3035.75 42.3408,3038.52 51.701,3037.09 59.1953,3027.51 67.5138,3032.8 65.2332,3047.71 71.3886,3049.28 76.6471,3043.26 74.7148,3038.85 74.6712,3032.67 70.0742,3024.81 55.7411,3022.76 68.3286,3006.26 80.6746,3000.85 96.5307,3016.21 111.167,3018.9 117.585,3029.69 126.015,3033.32 127.334,3043.78 137.343,3055.96 129.954,3077.59 112.327,3080.44 101.229,3068.17 94.4933,3067.5 88.7378,3077.46"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124838896"
- class="fil1 str2"
- points="240.529,3169.96 238.749,3175.41 232.835,3175.24 227.614,3183.44 214.613,3173.8 217.212,3166.26 230.856,3159.83 234.906,3162.65 242.604,3166.52"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- </g>
- <g
- id="g116">
- <polygon
- id="_124848376"
- class="fil1 str2"
- points="443.893,2886.79 438.309,2878.57 411.303,2875.96 400.797,2846.4 389.267,2836 368.196,2851.22 367.103,2825.2 354.009,2835.06 342.792,2835.93 331.517,2820.04 326.984,2813.34 318.655,2817.98 323.011,2841.9 333.992,2853.29 331.73,2861.06 324.87,2855.63 318.389,2842.59 311.04,2843.08 307.199,2847.1 313.722,2854.08 313.266,2861.92 299.889,2864.62 300.748,2870.3 316.01,2879.55 314.431,2884.63 311.198,2886.84 309.348,2892.27 311.779,2901.47 312.318,2914.66 317.44,2922.78 317.118,2940.85 328.157,2969.79 342.51,2982.42 346.88,3001.15 358.094,3000.15 363.077,2978.55 383.336,2967.69 390.139,2970.75 383.218,2988.61 375.283,2987.85 367.985,2998.1 367.22,3006.12 383.919,3002.04 405.308,3001.37 413.36,3009.16 412.964,3017.12 405.489,3016.74 402.264,3020.74 413.217,3030.73 422.098,3025.01 425.606,3027.77 423.925,3048.85 431.993,3049.37 441.956,3058.82 479.824,3051.51 485.448,3046.64 494.459,3053.5 479.662,3077.15 479.701,3086.82 495.474,3086.45 505.365,3095.39 528.397,3088.6 564.025,3061.07 569.635,3070.42 561.105,3080.81 540.111,3106.4 544.117,3127.6 550.845,3131.65 560.044,3137.2 559.508,3141.76 584.629,3141.3 603.544,3121.5 613.217,3129.19 641.986,3114.91 658.085,3122.45 656.979,3088.1 671.961,3082.95 674.926,3063.09 684.832,3062.04 681.624,3042.72 671.403,3038.58 672.733,3024.74 696.041,3021.54 707.161,2996.65 701.625,2987.16 706.523,2980.15 674.917,2969.69 639.263,2942.32 619.967,2951.96 594.498,2938.88 593.733,2926.89 600.574,2920.76 592.29,2911.08 593.691,2897.09 608.333,2894.11 616.528,2875.01 604.271,2867.68 604.381,2859.88 596.51,2860.89 597.864,2850.36 578.371,2854.16 566.618,2840.33 550.978,2835.08 548.953,2862.17 523.876,2855.3 500.239,2862.47 505.417,2869 478.834,2876.05 459.805,2872.48"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124847464"
- class="fil1 str2"
- points="299.677,3000.61 295.944,2995.66 294.427,2993.64 291.924,2974.3 295.529,2971.31 308.358,2990.62 308.358,2996.39 308.358,3000.61"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124847848"
- class="fil1 str2"
- points="329.031,2986.39 329.231,2987.11 336.138,2993.66 333.051,3002.93 331.797,3006.69 324.877,3005.19 313.092,2990.17 313.193,2977.77 317.666,2973.92 328.759,2985.41"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124847872"
- class="fil1 str2"
- points="304.018,2973.25 297.507,2966.44 294.861,2963.67 293.66,2953.01 303.342,2946.12 310.095,2951.09 310.596,2959.87 310.963,2966.3"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124847752"
- class="fil1 str2"
- points="335.282,3215.49 330.944,3218.96 329.182,3220.36 321.389,3216.37 331.857,3205.19 341.683,3205.66 342.471,3208.36 343.048,3210.35"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124863352"
- class="fil1 str2"
- points="368.657,3186.46 365.666,3190.73 359.476,3190.18 356.961,3189.96 353.509,3179.88 358.325,3174.39 362.675,3167.4 368.594,3173.08 368.63,3180.81"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124864144"
- class="fil1 str2"
- points="280.679,3019.82 281.073,3016.86 286.414,3013.45 291.366,3023.26 288.896,3028.74 287.09,3032.75 279.711,3027.11"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124853872"
- class="fil1 str2"
- points="297.507,3047.09 294.421,3043.07 293.167,3041.44 295.831,3034.24 302.474,3033.43 308.728,3042.37 307.512,3044.59 306.622,3046.22"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124845808"
- class="fil1 str2"
- points="315.303,3039.7 312.217,3035.38 310.963,3033.62 312.325,3020.77 319.402,3019.96 321.38,3034.06 319.518,3034.69 318.157,3035.15"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124853584"
- class="fil1 str2"
- points="350.692,3028.72 348.107,3033.41 343.299,3033.56 341.346,3033.62 339.176,3031.45 339.236,3023.38 354.56,3013.88 356.538,3020.59 353.161,3025.29"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124858600"
- class="fil1 str2"
- points="304.387,3084.07 314.704,3083.78 322.248,3083.57 321.801,3090.79 321.06,3096.34 320.76,3098.6 315.034,3100.47 308.792,3103.12 288.826,3096.17 291.924,3078.11 298.568,3077.3"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124854832"
- class="fil1 str2"
- points="341.406,3096.35 351.956,3095.54 352.133,3102.75 351.092,3107.21 350.33,3110.47 349.762,3116.42 348.089,3119.2 347.41,3120.33 341.16,3124.66 328.055,3125.23 322.248,3117.89 330.061,3110.07 331.066,3108.12"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124841248"
- class="fil1 str2"
- points="317.436,3078.47 314.869,3081.4 309.4,3080.19 306.19,3077.96 304.886,3077.06 308.172,3073.76 308.791,3071.41 314.495,3065.51 322.007,3064.27 320.946,3074.45"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124855624"
- class="fil1 str2"
- points="333.45,3074.53 333.593,3068.55 339.369,3065.14 350.192,3087.44 343.578,3090.98 338.742,3093.56 333.099,3089.22"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124855696"
- class="fil1 str2"
- points="376.938,3026.67 378.674,3014.08 383.075,3010.35 393.191,3016.49 394.3,3021.89 404.193,3036.03 411.428,3046.36 409.442,3055.33 408.908,3061.53 408.692,3064.04 401.4,3071.3 391.758,3069.68 392.334,3063.18 394.302,3052.47 384.982,3044.8"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124855120"
- class="fil1 str2"
- points="390.822,3105.15 388.961,3107.86 377.541,3110.77 370.807,3120.65 368.071,3124.66 360.175,3121.75 362.605,3104.94 365.219,3094.43 383.208,3094.24 393.368,3101.45"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124851424"
- class="fil1 str2"
- points="374.131,3056.09 363.917,3058.38 357.435,3052.51 354.802,3050.13 355.915,3044.14 358.768,3039.89 372.356,3044.29 373.466,3050.56 373.85,3053.76"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124857712"
- class="fil1 str2"
- points="381.989,3117.07 384.751,3114.41 404.653,3124.03 402.716,3129.45 388.673,3129.27 378.405,3129.14 375.192,3123.61"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124849816"
- class="fil1 str2"
- points="410.742,3098.14 415.135,3095.74 420.713,3099.27 415.303,3112.51 406.526,3113.58 400.107,3114.37 399.933,3104.07"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124849072"
- class="fil1 str2"
- points="451.221,3063.78 479.133,3056.88 484.149,3064.9 464.092,3087.83 449.426,3104.6 439.897,3105.42 435.108,3099.99 433.162,3097.79 434.794,3088.66 423.633,3085.46 421.211,3076.19 428.723,3061.89 440.744,3064.9"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124849864"
- class="fil1 str2"
- points="459.76,3118.71 459.171,3118.43 453.445,3125.11 447.928,3125.11 445.687,3125.1 440.908,3120.02 454.189,3104.07 463.314,3103.56 468.892,3107.09 460.565,3119.08"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124849672"
- class="fil1 str2"
- points="477.802,3177.79 481.074,3175.09 482.403,3174 493.264,3175.66 500.932,3186.84 497.368,3191.84 489.077,3190.17 483.015,3188.96"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124848568"
- class="fil1 str2"
- points="457.845,3188.2 453.066,3188.09 450.891,3177.35 453.876,3174.62 455.089,3173.51 455.969,3173.02 459.398,3170.09 466.353,3174.36 465.774,3182.06 464.38,3188.36"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124849720"
- class="fil1 str2"
- points="476.853,3201.49 480.242,3201.72 479.663,3210.73 467.389,3219.36 460.618,3216.42 455.666,3214.27 468.513,3200.93"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124858408"
- class="fil1 str2"
- points="550.285,3136.71 552.295,3137.44 548.677,3145.58 539.905,3147.1 538.632,3144.5 537.701,3142.6 545.34,3134.91"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124849504"
- class="fil1 str2"
- points="540.821,3166.16 538.981,3167.25 531.315,3170.77 527.284,3159.11 532.95,3154.41 537.093,3150.98 545.35,3163.5"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124858072"
- class="fil1 str2"
- points="456.601,3155.12 459.535,3140.79 476.587,3127.59 475.468,3120.93 469.524,3113.58 475.468,3108.33 475.527,3102.43 479.816,3098.14 488.937,3104.5 546.41,3090.76 531.026,3112.24 536,3123.5 539.638,3131.74 524.275,3148.27 524.447,3155.21 524.517,3158.02 518.462,3166.46 505.873,3168.41 490.262,3162.06 480.217,3168.39 464.774,3167.46"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- </g>
- <polygon
- id="_124860688"
- class="fil1 str2"
- points="645.754,2416.75 673.61,2427.63 677.504,2417.78 698.495,2420.78 724.382,2399.46 735.962,2406.83 738.921,2431.19 750.321,2435.93 770.715,2412.47 797.152,2416.3 803.266,2405.07 825.52,2404.73 831.235,2365.9 823.655,2355.54 829.202,2347.65 823.967,2331.65 806.687,2286.3 815.776,2279.18 802.543,2261.43 797.81,2223.04 808.231,2208.56 778.643,2194.57 791.702,2189.18 766.274,2157.05 741.564,2149.62 714.195,2113.64 699.942,2096.18 682.31,2087.69 658.233,2087.36 649.109,2114.14 637.041,2124.73 619.645,2119.72 586.682,2125.52 555.396,2140.77 555.031,2165.28 563.071,2165.56 569.468,2193.63 553.069,2193.43 518.675,2253.04 521.205,2270.12 491.621,2301.21 454.775,2288.95 431.183,2264.34 424.509,2272.14 420.961,2308.75 428.463,2316.31 404.054,2342.78 384.527,2400.54 392.2,2419.5 403.237,2423.14 403.809,2451.54 410.475,2454.41 417.712,2464.96 402.523,2474.65 405.334,2489.15 397.085,2495.68 393.829,2524.51 407.269,2536.82 440.787,2542.76 479.433,2509.9 491.272,2509.84 512.035,2477.97 527.667,2477.44 541.062,2450.11 559.474,2459.25 570.796,2459.34 599.722,2459.44 631.338,2442.18"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124854568"
- class="fil1 str2"
- points="855.993,2624.48 863.048,2625.71 862.962,2632.14 855.746,2632.58 853.548,2626.45 848.018,2630.15 850.892,2639.92 849.764,2652.02 857.353,2656.57 859.788,2655.2 869.772,2661.13 860.037,2667.95 855.727,2677.44 857.886,2690.29 876.373,2705.54 875.177,2729.06 952.598,2721.78 968.256,2665.41 991.77,2654.62 1004.25,2660.56 1020.62,2632.25 1038.87,2641.43 1059.76,2673.6 1089.12,2685.39 1091.76,2678.3 1110.54,2684.31 1115.79,2664.92 1094.48,2633.52 1089.31,2579.19 1095.84,2569.33 1073.58,2528.45 1087.47,2500.09 1112.07,2484.81 1129.75,2493.81 1138.47,2456.84 1153.2,2451.62 1136.55,2433.22 1147.1,2425.9 1140.42,2418.16 1129.54,2419.56 1107.13,2405.2 1107.08,2396.66 1126.77,2375.58 1121.85,2346.73 1104,2319.46 1091.64,2322.51 1049.7,2270.03 1079.17,2266.2 1087.24,2252.6 1077.54,2243.01 1089.78,2234.82 1069.22,2206.47 1065.73,2153.22 1055.2,2138.59 1062.15,2112.61 1031.13,2112.83 1022.17,2093.91 1012.63,2085.96 988.916,2085.88 941.998,2053.69 927.197,2059.84 920.687,2100.29 902.573,2102.34 890.26,2104.44 866.13,2130.15 863.575,2199.98 840.551,2194.96 814.137,2204.71 807.95,2208.76 797.81,2223.04 802.543,2261.43 815.776,2279.18 806.687,2286.3 824.237,2332.36 829.202,2347.65 823.655,2355.54 831.235,2365.9 825.52,2404.73 803.266,2405.07 797.152,2416.3 770.715,2412.47 750.148,2435.87 750.251,2464.15 771.722,2477 782.995,2474.88 790.749,2497.03 811.397,2501.12 824.279,2496.5 846.796,2520.41 853.961,2546.7 839.501,2569.81 835.201,2562.17 821.734,2581.68"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124851472"
- class="fil1 str2"
- points="555.341,2497.17 554.459,2523.43 536.267,2525.2 527.031,2540.67 540.911,2547.49 540.927,2561.29 556.397,2572.87 562.553,2594.72 553.841,2625.16 540.705,2620.89 536.228,2644.07 547.471,2654.9 533.606,2666.6 524.204,2695.59 543.685,2709.22 541.029,2722.35 516.578,2725.93 507.308,2732.96 508.209,2746.41 521.353,2778.54 547.643,2787.26 556.244,2777.91 571.268,2793.24 564.401,2817.34 576.782,2838.73 566.618,2840.33 578.371,2854.16 597.864,2850.36 596.51,2860.89 604.484,2859.38 614.825,2853.04 629.168,2863.92 631.458,2873.97 645.998,2873.75 676.072,2862.29 696.659,2884.78 701.798,2879.74 697.552,2847.18 766.709,2820.94 775.576,2810.39 772.241,2806.46 771.866,2799.95 775.339,2794.5 780.133,2798.12 808.832,2775.62 833.758,2785.32 839.203,2773 851.034,2784.83 868.71,2776.92 866.502,2724.03 875.177,2729.06 876.373,2705.54 857.886,2690.29 855.727,2677.44 860.037,2667.95 869.772,2661.13 859.788,2655.2 857.353,2656.57 849.764,2652.02 850.892,2639.92 848.018,2630.15 853.548,2626.45 855.746,2632.58 862.962,2632.14 863.048,2625.71 855.993,2624.48 821.734,2581.68 835.201,2562.17 839.501,2569.81 853.961,2546.7 846.796,2520.41 824.279,2496.5 811.397,2501.12 790.749,2497.03 782.995,2474.88 771.722,2477 750.251,2464.15 750.321,2435.93 738.921,2431.19 735.962,2406.83 724.382,2399.46 698.495,2420.78 677.504,2417.78 673.61,2427.63 645.754,2416.75 631.338,2442.18 599.722,2459.44 570.925,2459.2 570.936,2489.64"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <path
- id="_124852264"
- class="fil1 str2"
- d="m 330.018,2773.03 5.87806,3.6842 0.89147,4.1264 0.65207,3.0179 -3.90645,5.2123 -4.01247,0.3086 -1.63018,0.1257 -2.64563,-10.0094 1.45035,-2.7836 3.32278,-3.6821 z m 21.2685,-141.603 4.92019,1.3962 5.70678,10.4659 4.17349,7.6536 -4.70929,5.2377 -7.14544,-0.018 -2.90298,-0.01 -6.9448,-7.3843 5.16728,-5.2314 1.73478,-12.1124 z m -19.6668,188.75 6.89607,-13.8531 7.37999,-42.1245 7.56752,5.0399 3.83492,-4.8703 -0.794,-6.6211 4.74292,-24.518 -10.3172,-24.1871 1.9471,-3.0372 4.71698,-1.5401 7.05852,2.7619 5.43546,-0.9924 -3.65423,-8.9301 -11.287,-5.953 -0.87722,-7.9605 7.60372,0.299 11.9813,3.5325 -0.34086,-4.5086 -6.61905,-5.3514 -7.10469,-14.4245 2.99874,-5.6943 5.61301,0.4024 8.92354,10.1747 6.698,0.2337 -12.9731,-29.1292 0.0108,-26.4175 -13.4715,-17.4435 2.70719,-5.9678 7.88757,-0.8359 0.51129,-4.6836 -6.05077,-4.707 -3.7175,-23.7106 -8.97313,-5.505 -2.06765,-7.6733 15.2106,-13.8608 30.7315,-3.6103 13.4402,12.3033 33.5185,5.947 38.6456,-32.8695 11.8388,-0.054 20.7637,-31.8695 15.6312,-0.5336 13.3957,-27.3312 18.4117,9.1425 11.4512,-0.048 0.0108,30.4422 -15.5953,7.5271 -0.88207,26.2619 -18.1913,1.7684 -9.23646,15.4676 13.8805,6.8188 0.0154,13.803 15.4705,11.5774 6.15593,21.8547 -8.7115,30.4391 -13.1364,-4.2698 -4.47759,23.1751 11.2437,10.8367 -13.8648,11.6991 -9.40262,28.9876 19.481,13.6291 -2.65617,13.1287 -24.4507,3.5818 -9.27009,7.0315 0.90116,13.4541 13.1441,32.122 26.2895,8.7234 8.60177,-9.3541 15.0236,15.3354 -6.86671,24.0939 12.3811,21.3936 -10.1641,1.6011 -15.6406,-5.2471 -2.0249,27.0827 -25.0769,-6.8693 -23.6365,7.1762 5.17782,6.5253 -26.5834,7.0506 -19.0284,-3.5705 -15.9119,14.3154 -5.5848,-8.227 -27.0052,-2.6114 -10.5064,-29.5513 -11.5298,-10.403 -21.0715,15.2223 -1.09239,-26.0202 -13.0942,9.8563 -11.2172,0.8664 -11.1722,-15.7441 z"
- inkscape:connector-curvature="0"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <g
- id="g149">
- <polygon
- id="_124852096"
- class="fil1 str2"
- points="1046.81,2914.56 1054.6,2899.79 1038.47,2892.87 1043.9,2882.52 1056.41,2883.28 1052.01,2860.71 1046.16,2848.06 1049.87,2834.59 1071.79,2834.66 1092.94,2820.34 1100.89,2799.5 1110.2,2794.33 1121.08,2789.95 1137.23,2815.57 1152.39,2807.76 1152.65,2792.11 1172.87,2792.53 1172.94,2819.43 1201,2833.34 1217.28,2827.87 1227.47,2851 1211.5,2856.94 1206.37,2874.25 1220.88,2891.94 1212.85,2896.74 1220.55,2909.89 1246.24,2917.38 1253.16,2929.55 1272.39,2939.79 1294.15,2939.26 1301.48,2954.11 1317.8,2956.53 1325.69,2975.93 1343.75,2985.16 1327.85,3000.45 1327.36,3010.63 1316.96,3017.51 1304.85,3009.58 1300.01,3013.29 1296.24,3030.21 1290.9,3038.94 1282.82,3039.19 1273.05,3040.6 1266.64,3037.07 1260.75,3041.02 1253.67,3047.69 1244.57,3034.19 1220.98,3031.41 1192.37,3022.07 1180.78,3033.71 1181.12,3052.38 1176.95,3059.87 1165.21,3059.51 1151.75,3046.07 1143.89,3053.24 1133.83,3053.59 1127.53,3046.94 1120.87,3051.57 1104.46,3054.96 1100.75,3043.55 1118.41,3009.43 1116.35,3006.32 1106.42,3004.64 1101.11,2986.67 1087.65,2984.09 1083.5,2966.13 1067.17,2958.28 1063.31,2956.43 1061.07,2940.64 1047.42,2931.6"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124856392"
- class="fil1 str2"
- points="1157.3,3082.72 1153.82,3088.51 1147.22,3084.67 1141.77,3080.94 1151.22,3073.1"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124840984"
- class="fil1 str2"
- points="1130.82,3055.78 1132.99,3063.75 1119.87,3073.81 1112.25,3067.04 1123.01,3055.72"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124850200"
- class="fil1 str2"
- points="1214.16,3108.49 1205.38,3108.12 1205.57,3100.48 1210.19,3095.95 1212.42,3096.12 1218.33,3101.66 1221.53,3104"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124846864"
- class="fil1 str2"
- points="1197.23,3075.77 1191.15,3075.91 1185.85,3063.38 1189.95,3049.66 1197.23,3052.25"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- </g>
- <polygon
- id="_124848544"
- class="fil1 str2"
- points="1211.5,2856.94 1227.47,2851 1217.26,2827.83 1238.81,2822.65 1231.77,2808.35 1237.88,2796.5 1219.97,2777.33 1201.69,2779.99 1182.8,2768.68 1189.32,2758.7 1204.69,2759.97 1208.42,2752.94 1246.49,2753.13 1270.46,2767.5 1291.71,2758.78 1324.92,2765.61 1374.74,2761.27 1400.18,2729.79 1407.78,2710.97 1422.05,2721.86 1459.56,2721.64 1464.4,2704.6 1495.02,2705.98 1525.89,2696.09 1544.95,2664.44 1569.25,2656.22 1574.91,2640.11 1664.71,2591.89 1661.79,2594.86 1649.79,2628.83 1619.63,2656.59 1599.34,2699.18 1573.78,2717.29 1568.01,2735.14 1530.07,2799.12 1485.65,2829.93 1469.78,2836.4 1450.69,2869.07 1448.29,2890.48 1427.77,2895.06 1389.32,2928.71 1381.94,2948.43 1343.75,2985.16 1325.69,2975.93 1317.8,2956.53 1301.48,2954.11 1294.15,2939.26 1272.39,2939.79 1253.16,2929.55 1246.24,2917.38 1220.55,2909.89 1212.85,2896.74 1220.88,2891.94 1206.37,2874.25"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <path
- id="_124846648"
- class="fil1 str2"
- d="m 902.573,2102.34 -61.6602,-75.4558 -16.5347,-49.7114 -14.8338,-5.8419 -5.0111,-21.0641 -10.8473,-5.6423 -9.47358,-37.8285 -20.6295,4.0073 -8.12612,15.2619 8.97085,12.1759 -7.81005,4.2507 -9.3744,-8.445 -12.4353,0.1644 -19.9116,-27.4683 -9.53827,1.6604 -11.8875,-11.3437 -8.03378,5.7268 -1.05734,45.9874 -48.0644,2.1745 -5.88005,8.5924 -6.6276,0.1484 -6.00146,-7.2283 -13.1235,-0.077 c -0.33117,0.4954 -0.40555,0.04 -0.73586,0.535 l 14.3502,39.4746 6.25511,-8.4744 32.8707,24.5459 23.2158,-11.3209 6.08098,9.0449 10.6797,-8.2831 36.9741,29.7283 -8.41767,9.0256 -17.3546,0.3961 -10.8128,-8.8127 -13.8161,8.9352 9.11904,16.1191 8.46156,-2.409 20.5309,37.2579 -7.83798,26.1533 27.3184,35.3211 24.7101,7.4236 25.4286,32.1328 -13.0591,5.3904 29.5875,13.9871 5.90656,-3.8517 26.4138,-9.7466 23.024,5.017 2.555,-69.8268 24.1298,-25.7087 12.313,-2.0975 z"
- inkscape:connector-curvature="0"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <g
- id="g158">
- <path
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.26771;"
- d="m 898.15625,2913.75 -14.125,3.75 4.3125,10.9062 -10.8125,3.125 -2.375,12.7188 8.96875,-7.5938 9.09375,6.375 -13.15625,9.5626 1.4375,8.875 -19.9375,-5.6563 -10.0625,4.3125 -29.71875,3.9062 -17.5625,-2.5937 -7.875,10.5625 1.21875,14.3438 -27.90625,5.5 -2.71875,-10.375 -11.125,-5.2813 -10.8125,8.25 -5.625,-12.4375 -45.65625,-7.875 -4.875,6.9688 5.53125,9.4374 -11.0625,24.75 -23.1875,3.1876 -1.3125,13.75 10.15625,4.125 3.1875,19.2187 -9.84375,1.0625 -2.96875,19.75 -14.90625,5.125 1.125,34.1562 -16.03125,-7.5 -28.59375,14.1876 -9.625,-7.625 -18.8125,19.6874 -25,0.4688 -4.15625,35.4062 -9.0625,-4.6874 -11.21875,0.5 -2.40625,11.75 9.71875,12.8437 17.71875,3.0937 4.75,-4.625 0.40625,-15.8124 5.625,-4.5313 4.75,7.375 -2.5625,19.2813 -5.625,6.7812 -27.625,9.7188 -6.5,7.3124 6.9375,8.75 20.71875,-8.625 25.03125,0.2188 12.9375,-11.0625 0.0312,-7.1875 9.90625,-11 12.09375,1.5625 7.78125,5.5313 15.96875,-3.4063 12.53125,2.7187 6.4375,-4.9062 -2.53125,-9.3125 18.09375,-1.6875 36.6875,-15.6875 30.21875,-0.6875 22.0625,-12.1875 -0.90625,19.1563 4.71875,0.062 6.9375,-6.0624 6,3.5 -12.9375,16.9687 9.53125,0.7187 29.34375,-36.875 -0.0312,-9.875 2.15625,-5.125 5.21875,5.2188 26.75,-9.4062 10.03125,6.8437 14.125,0.1875 4.78125,-7.5625 2.09375,11.6875 10.8125,-9.1562 -1.6875,-12.5313 10.8125,3.3437 7.71875,-10.5 2.25,-6.9687 5.6875,-1.5625 13.625,-3.75 24.25,-0.6562 6.125,-7.5313 0.34375,-13.2813 15.9375,-1.7812 3.9375,14.625 12.625,15.6875 5,0.9687 7.4375,-8 8.1875,5.0938 4.25005,-5.4688 -4.6563,-14.9374 4.1875,-3.4063 8.3438,17.1875 5.0937,-2.0312 -0.9063,-12.5 4.9376,-1.7188 7.5624,3.75 5.5938,-2.4375 -9.3438,-16.5313 -2.625,-10.5312 -9.5312,-12.875 1.375,-8.0938 15.5312,14.8126 10.8438,11.2187 5.1562,11.4375 6.0626,-0.4688 -3.8438,-12.9687 13.5312,0.3437 8.8438,11 0.6875,-10.8124 7.4687,0.2812 13.3126,-11.9688 -3.125,-11.8437 17.5624,-33.9375 -2.0624,-3.0938 -9.875,-1.6874 -5.2813,-17.875 -13.375,-2.5626 -4.125,-17.8437 -15.8125,-7.5313 -1.6562,13.9063 -13.1876,7.0937 -12.6874,-11.375 -19.9063,4.3438 -0.75,-13.75 -13.34375,9.4062 -8.5625,-1.4062 -28.15625,8.7188 -7.03125,-8.7813 -1.4375,0.8125 -7,-25.4062 -4.75,-4.2188 -15.84375,16.5938 -20.40625,-24.8438 z"
- transform="matrix(1.00541, 0, 0, 1.00541, 9.04408, 0.00501389)"
- id="_124858432"
- sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" />
- <polygon
- id="_124862656"
- class="fil1 str2"
- points="925.18,3112.1 932.084,3112.1 935.15,3113.47 940.911,3113.82 938.458,3118.35 935.188,3121.94 924.874,3122.62 922.573,3118.73 920.359,3116.23"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124867096"
- class="fil1 str2"
- points="956.431,3114.27 958.424,3131.82 952.116,3132.8 950.352,3129.15 950.309,3119.71"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124213728"
- class="fil1 str2"
- points="970.755,3094.72 972.868,3106.03 978.467,3112.69 978.256,3120.46 976.76,3122.09 976.655,3125.74 971.522,3131.08 966.873,3127.16 966.412,3113.95 965.935,3096.25"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124211160"
- class="fil1 str2"
- points="1018.4,3119.64 1020.93,3124.87 1014.49,3131.51 1001.6,3129.76 1001.14,3125.24 1002.39,3118.84 1008.15,3117.26 1011.56,3114.27"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124241040"
- class="fil1 str2"
- points="1038.46,3103.96 1051.49,3097.33 1053.99,3108.34 1044.88,3110.23"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124219728"
- class="fil1 str2"
- points="1056.69,3091.36 1058.77,3084.39 1065.81,3084.3 1070.49,3094.88 1064.41,3098.07 1057.81,3094.22"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124230192"
- class="fil1 str2"
- points="1113.02,3078.37 1112.59,3085.47 1097.3,3082.93 1093.15,3076.16 1097.4,3070.49"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- </g>
- <g
- id="g168">
-
- <polygon
- id="_124228272"
- class="fil1 str2"
- points="623.04,3214.18 632.594,3211.71 629.263,3219.37 624.842,3220.55 619.862,3223.33 614.304,3221.84 610.188,3219.05 615.656,3212.66"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124212648"
- class="fil1 str2"
- points="709.416,3181.17 712.578,3182.96 718.244,3182.88 707.745,3191.88 698.859,3199.44 690.487,3195.16 695.955,3185.29 702.946,3181.16"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- </g>
- <g
- id="g173">
- <polygon
- id="_124851736"
- class="fil1 str2"
- points="569.454,1974.32 570.959,1969.43 577.903,1975.51 576.704,1989.53 573.135,1993.22 570.525,1995.92 565.75,1986.37"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124221384"
- class="fil1 str2"
- points="454.604,2077.04 457.238,2076.28 461.144,2080.19 460.813,2088.57 456.24,2089.75 452.897,2090.62 448.122,2078.89"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124218600"
- class="fil1 str2"
- points="491.136,2114.13 481.213,2114.63 476.51,2118.25 474.6,2119.72 469.825,2119.28 479.808,2103.21 488.923,2103.21 494.523,2108.46 492.567,2111.73"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124231944"
- class="fil1 str2"
- points="506.071,2139.25 503.724,2143.67 490.328,2137.22 482.23,2137.44 478.94,2137.53 475.034,2128.84 488.055,2120.59 501.968,2126.49 508.455,2123.19 509.281,2133.22"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124213416"
- class="fil1 str2"
- points="444.259,2136.72 436.94,2129.83 433.472,2137.47 432.063,2140.57 426.42,2139.27 426.42,2128.84 434.233,2119.72 446.344,2130.17 445.139,2133.95"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124237632"
- class="fil1 str2"
- points="368.257,2111.03 362.393,2111.03 360.01,2111.03 363.483,2101.91 368.691,2091.92 374.291,2091.95 374.375,2097.52 374.437,2101.6"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124223424"
- class="fil1 str2"
- points="389.96,2117.11 382.552,2117.11 379.543,2117.11 374.768,2108.86 385.185,2100.61 392.521,2100.64 394.611,2105.46 396.139,2108.98"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124242240"
- class="fil1 str2"
- points="378.198,2166.66 369.228,2164.58 363.049,2158.81 356.104,2158.38 346.555,2121.89 353.065,2119.72 358.254,2125.56 367.337,2116.45 373.466,2121.89 373.643,2128.93 370.034,2132.39 367.395,2134.92 370.679,2140.64 377.934,2140.87 380.882,2140.97 384.805,2132.63 393.218,2134.91 400.059,2149.8 395.924,2160.55 384.637,2156.59"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124211352"
- class="fil1 str2"
- points="308.792,2223.1 304.471,2223.1 302.716,2223.1 299.243,2216.58 305.32,2207.46 311.788,2210.1 311.621,2214.42 311.5,2217.57"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124227576"
- class="fil1 str2"
- points="359.968,2221.39 357.943,2230.61 353.857,2230.52 352.197,2230.48 346.555,2225.7 346.555,2211.8 352.197,2208.33 359.013,2213.87 359.564,2218.22"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124229952"
- class="fil1 str2"
- points="347.857,2267.84 344.153,2270.93 342.648,2272.18 335.269,2267.84 340.478,2259.15 349.55,2254.84 351.891,2259.91 353.602,2263.62"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124236048"
- class="fil1 str2"
- points="334.401,2304.76 329.772,2305.07 327.891,2305.19 325.72,2300.85 326.588,2290.86 330.452,2290.02 333.795,2296.85 336.24,2301.84"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124228464"
- class="fil1 str2"
- points="324.852,2362.09 321.148,2358.39 319.644,2356.88 321.773,2350.78 324.809,2346.49 331.466,2353.97 331.657,2356.4 331.797,2358.19"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- <polygon
- id="_124220496"
- class="fil1 str2"
- points="657.422,2008.47 624.552,1983.92 618.297,1992.4 604.111,1953.24 594.918,1967 584.997,1973.56 587.76,1989.75 586.191,2001.6 574.065,2009.34 572.222,2018.05 565.518,2020.94 555.89,2029.24 554.878,2034.13 545.861,2040.72 542.07,2057.32 535.479,2048.67 528.625,2052.44 523.646,2074 516.005,2074.45 512.029,2079.73 514.431,2087.5 519.963,2093.06 532.104,2120.31 527.665,2131.1 516.539,2131.32 508.39,2146.78 495.38,2149.82 460.629,2137.37 435.891,2147.78 424.363,2148.04 419.5,2133.51 411.427,2141.71 410.657,2163.49 402.223,2173.97 403.459,2181.86 413.408,2190.53 416.553,2198.31 411.394,2200.31 402.206,2197.86 395.853,2199.94 385.845,2193.29 381.18,2200.87 391.702,2208.89 396.191,2218.55 395.125,2230.34 384.587,2240.35 385.901,2250.78 381.609,2255.16 370.303,2256.45 369.587,2250.92 358.574,2254.71 355.58,2272.87 349.848,2279 338.504,2278.41 337.303,2283.26 344.031,2290.92 343.06,2299.64 336.643,2305.46 331.715,2311.25 328.473,2331.91 332.311,2336.53 339.132,2330.79 344.328,2334.69 345.35,2341.23 335.43,2357.44 333.22,2376.18 337.853,2381.11 331.84,2405.05 338.319,2415.1 360.11,2416.17 359.461,2423.29 349.233,2436.92 349.269,2448.25 364.27,2454.11 365.851,2462.21 353.9,2475 354.361,2486.29 346.611,2498.97 339.362,2526.5 347.236,2539.57 347.887,2541.99 363.097,2528.12 393.829,2524.51 397.085,2495.68 405.334,2489.15 402.523,2474.65 417.712,2464.96 410.475,2454.41 403.809,2451.54 403.237,2423.14 392.2,2419.5 384.527,2400.54 404.054,2342.78 428.463,2316.31 420.961,2308.75 424.509,2272.14 431.183,2264.34 454.775,2288.95 491.621,2301.21 521.205,2270.12 518.675,2253.04 553.069,2193.43 569.468,2193.63 563.071,2165.56 555.031,2165.28 555.396,2140.77 586.682,2125.52 619.645,2119.72 637.041,2124.73 649.109,2114.14 658.233,2087.36 682.31,2087.69 699.942,2096.18 714.195,2113.64 722.083,2088.15 701.553,2050.89 693.091,2053.3 683.972,2037.18 697.788,2028.25 708.601,2037.06 725.955,2036.66 734.373,2027.64 697.399,1997.91 686.719,2006.19 680.638,1997.15"
- style="fill: none; stroke: rgb(99, 99, 71); stroke-width: 2.27997;" />
- </g>
- </g>
- <g
- id="_159700104">
- <polygon
- id="_159701568"
- class="fil1 str3"
- points="830.941,402.881 809.986,413.882 798.888,433.452 771.196,443.235 741.874,456.449 734.897,442.02 702.653,438.674 671.82,416.349 654.014,423.838 656.063,389.248 585.676,246.547 544.067,232.093 518.159,244.839 500.788,265.596 510.988,292.53 505.76,310.727 472.929,285.304 449.668,308.064 479.491,346.63 481.261,373.098 504.106,379.259 536.845,447.227 560.728,454.646 569.502,476.682 591.826,487.604 600.882,513.796 633.583,521.252 677.125,541.217 724.42,584.796 724.506,613.838 730.742,630.925 745.169,628.899 756.209,611.08 799.401,608.259 832.34,619.678 832.373,628.156 854.877,619.641 889.179,571.282 913.23,550.482 957.998,550.637 940.503,482.635 916.245,452.767 872.378,433.58"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <path
- id="_159701496"
- class="fil1 str3"
- d="m 844.926,622.977 3.04947,9.96206 -3.07084,7.73054 5.26532,3.25694 4.30203,12.1335 1.01259,15.5201 -5.95187,15.6483 7.54672,100.688 -23.0047,-6.0767 -79.2223,64.6364 -11.252,-18.8674 15.1462,-38.9343 -1.19613,-57.0159 0.4027,-18.5559 8.74912,-14.7435 11.0562,-13.1423 -26.5734,-27.6635 -6.016,-28.6544 11.0394,-17.8191 43.1924,-2.82118 32.9394,11.4195 0.0325,8.47723 c 4.28151,-1.61964 9.251,-3.77706 12.5533,-5.17811 z"
- inkscape:connector-curvature="0"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159701424"
- class="fil1 str3"
- points="1306.58,153.038 1285.89,179.766 1219.45,208.406 1210.75,221.372 1033.34,319.14 1035.53,355.861 1025.49,391.044 1005.05,385.808 986.507,396.951 961.225,434.135 964.057,470.073 946.707,469.967 940.503,482.635 957.998,550.637 1066.51,591.022 1093.21,576.148 1241.78,567.229 1334.38,532.257 1341.47,536.564 1364.26,525.223 1358.46,501.718 1387.41,449.541 1393.92,402.814 1385.74,388.966 1352.78,389.081 1406.98,343.479 1396.63,307.18 1400.14,273.285 1452.27,205.546 1422.82,130.452 1335.1,87.2276"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159701352"
- class="fil1 str3"
- points="1262.71,22.4227 1278.39,12.5376 1306.22,51.2835 1333.06,68.1732 1335.1,87.2276 1306.58,153.038 1285.89,179.766 1219.45,208.406 1210.75,221.372 1033.31,318.568 1031.81,293.372 1050.21,188.127 1059.65,170.934 1054.1,154.879 1068.55,131.72 1097.91,105.588 1115.32,64.1525 1143.85,54.1508 1193.47,67.0789 1236.46,33.0009 1247.21,17.3925"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159701280"
- class="fil1 str3"
- points="910.526,938.136 919.759,1009.8 845.438,990.214 840.15,982.822 778.951,982.805 756.34,931.753 757.445,900.132 781.291,887.737 775.935,869.381 783.001,853.424 755.287,848.647 754.853,846.476 834.075,781.84 857.08,787.917 860.305,834.435 864.918,851.355"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159701208"
- class="fil1 str3"
- points="1324.01,1140.37 1336.29,1109.06 1331.73,1083.64 1310.73,1079.13 1295.55,1023.01 1303.43,983.233 1351.09,954.848 1389.31,947.416 1454.25,813.119 1459.88,791.214 1479.05,776.938 1503.25,730.84 1549.63,765.543 1545.9,810.813 1447.28,995.77 1439.79,1020.47 1504.59,1129.9 1516.62,1162.12 1471.15,1167.96 1396.51,1150.45 1363.15,1149.31 1341.06,1171.64 1329.32,1171.72"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159701136"
- class="fil1 str3"
- points="1308.26,937.013 1351.09,954.848 1389.31,947.416 1454.25,813.119 1459.88,791.214 1479.05,776.938 1503.25,730.84 1455.73,633.814 1383.06,604.25 1282.31,784.33 1236.53,816.298 1216.86,857.497 1282.53,900.717 1296.64,936.237"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159701064"
- class="fil1 str3"
- points="1069.32,696.928 1055.83,645.759 1066.51,591.022 957.998,550.637 913.23,550.482 889.179,571.282 875.78,590.172 862.062,609.511 857.347,616.159 854.877,619.641 844.926,622.977 847.976,632.94 844.905,640.67 850.17,643.927 854.472,656.06 855.485,671.581 849.533,687.229 857.08,787.917 860.305,834.435 864.918,851.355 892.71,904.237 910.526,938.136 927.341,930.388 984.701,940.259 998.343,895.468 1014.46,887.082 1016.77,875.004 1039.78,855.903 1034.01,817.427"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159700992"
- class="fil1 str3"
- points="1189.58,934.581 1133.78,1005.88 1117.02,1008.51 1048.93,951.218 984.701,940.259 998.343,895.468 1014.46,887.082 1016.77,875.004 1039.78,855.903 1034.01,817.427 1069.32,696.928 1055.83,645.759 1066.51,591.022 1093.21,576.148 1241.78,567.229 1334.38,532.257 1341.47,536.564 1364.26,525.223 1383.06,604.25 1282.31,784.33 1236.53,816.298 1216.86,857.497 1215.4,876.774 1198.93,884.29"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159700920"
- class="fil1 str3"
- points="1215.4,876.774 1216.86,857.497 1282.53,900.717 1296.64,936.237 1308.26,937.013 1351.09,954.848 1303.43,983.233 1295.55,1023.01 1272.24,1008.21 1256.83,989.742 1238.48,990.369 1226.17,976.883 1206.43,993.921 1175.33,995.138 1133.78,1005.88 1189.58,934.581 1198.93,884.29"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159700848"
- class="fil1 str3"
- points="919.759,1009.8 845.438,990.214 840.15,982.822 778.951,982.805 804.095,1042.11 786.503,1061.56 783.076,1118.06 774.948,1125.11 800.949,1150.15 829.999,1136.38 850.512,1108.4 879.438,1097.2 879.421,1073.07 906.527,1062.97 931.407,1065.34"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159700776"
- class="fil1 str3"
- points="906.527,1062.97 879.421,1073.07 879.438,1097.2 850.512,1108.4 829.999,1136.38 800.949,1150.15 774.948,1125.11 765.291,1133.49 760.527,1149.03 754.505,1167.65 758.7,1184.48 754.073,1196.49 761.961,1235.63 782.238,1255.29 787,1229.8 904.756,1196.58 935.423,1157.82 931.407,1065.34"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159700704"
- class="fil1 str3"
- points="904.756,1196.58 787,1229.8 782.238,1255.29 783.321,1276.01 800.196,1303.55 801.684,1323.4 811.888,1350.9 812.149,1372.98 823.287,1371.7 831.074,1359.29 840.805,1370.97 854.438,1376.02 867.731,1347.95 863.258,1246.66"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159700632"
- class="fil1 str3"
- points="1178.97,1212.74 1181.92,1228.73 1193.14,1240.96 1220.26,1243.07 1224.26,1228.34 1218.34,1222.89 1218.47,1198.86 1200.67,1189.34 1148.62,1125.15 1142.92,1050.23 1117.02,1008.51 1048.93,951.218 984.701,940.259 927.341,930.388 910.526,938.136 919.759,1009.8 931.407,1065.34 935.423,1157.82 904.756,1196.58 967.983,1236.02 1026.79,1236.37 1066.31,1257.97 1084.68,1240.98 1107.47,1235.82 1114.1,1249.56 1135.74,1237.75 1132.91,1215.39"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159700560"
- class="fil1 str3"
- points="1324.01,1140.37 1336.29,1109.06 1331.73,1083.64 1310.73,1079.13 1295.55,1023.01 1272.24,1008.21 1256.83,989.742 1238.48,990.369 1226.17,976.883 1206.43,993.921 1175.33,995.138 1133.78,1005.88 1117.02,1008.51 1142.92,1050.23 1148.62,1125.15 1200.67,1189.34 1218.47,1198.86 1238.22,1213.29 1247.72,1190.74 1260.92,1178.94 1282.03,1170.39 1304.33,1172.6 1329.32,1171.72"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159700488"
- class="fil1 str3"
- points="1242.83,1319.3 1256.46,1325.5 1266.81,1320.59 1280.73,1355.15 1348.52,1365.88 1378.48,1352.79 1379.62,1333.66 1364.8,1311.34 1383.24,1302.42 1401.44,1307.59 1406.94,1303.11 1406.59,1286.23 1393.99,1277.05 1394.3,1259.63 1403.72,1258.16 1408.29,1226.72 1389.74,1218.91 1377.03,1191.57 1381.94,1173.14 1397,1167.18 1396.51,1150.45 1363.15,1149.31 1341.06,1171.64 1329.32,1171.72 1304.33,1172.6 1282.03,1170.39 1260.92,1178.94 1247.72,1190.74 1238.22,1213.29 1218.47,1198.86 1218.34,1222.89 1224.26,1228.34 1220.26,1243.07 1220.93,1254.53 1245.07,1273.46"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159700416"
- class="fil1 str3"
- points="1066.31,1257.97 1028.13,1279.26 1033.68,1304.93 1013.64,1341.07 1048.31,1376.91 1072.98,1361.38 1076.5,1391.52 1168.84,1399.51 1200.14,1388.84 1242.83,1319.3 1245.07,1273.46 1220.93,1254.53 1220.26,1243.07 1193.14,1240.96 1181.92,1228.73 1178.97,1212.74 1132.91,1215.39 1135.74,1237.75 1114.1,1249.56 1107.47,1235.82 1084.68,1240.98"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159700344"
- class="fil1 str3"
- points="880.458,1416.2 901.322,1377.63 917.538,1377.33 921.192,1354.57 934.532,1349.41 958.132,1325.83 988.105,1278.48 1002.35,1270.4 1028.13,1279.26 1033.68,1304.93 1013.64,1341.07 1048.31,1376.91 1026.26,1390.81 972.617,1387.74 969.415,1402.58 948.026,1413.68 932.974,1428.95 933.578,1428.39 927.013,1421.66 918.091,1422.49 909.761,1411.71 895.771,1409.63 888.751,1415.36"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159700272"
- class="fil1 str3"
- points="904.756,1196.58 967.983,1236.02 1026.79,1236.37 1066.31,1257.97 1028.13,1279.26 1002.35,1270.4 988.105,1278.48 963.135,1317.93 941.832,1307.89 894.524,1311.66 865.372,1294.53 863.258,1246.66"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159700200"
- class="fil1 str3"
- points="863.281,1357.34 854.438,1376.02 880.637,1366.66 894.337,1390.54 901.322,1377.63 917.538,1377.33 921.192,1354.57 934.532,1349.41 958.132,1325.83 963.135,1317.93 948.964,1311.25 941.832,1307.89 894.524,1311.66 865.372,1294.53 867.731,1347.95"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159700128"
- class="fil1 str3"
- points="861.805,1378.74 868.363,1388.45 860.985,1403.94 866.303,1410.09 876.5,1403.43 880.458,1416.2 894.337,1390.54 880.637,1366.66 854.438,1376.02"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- </g>
- <g
- id="_159699432">
- <polygon
- id="_159700032"
- class="fil1 str3"
- points="1540.33,1728.66 1600.37,1741.99 1611.43,1732.28 1612.08,1712.15 1601.44,1698.83 1605.92,1682.79 1555.24,1672.39 1540.33,1615.02 1545.72,1594.85 1565.07,1588.4 1572.7,1572.6 1565.67,1563.26 1574.25,1545.67 1566.06,1536.2 1539.81,1533.78 1550.79,1496.63 1552.94,1464.05 1556.39,1452.45 1519.34,1460.14 1484.2,1458.48 1478.14,1453.45 1465.64,1480.24 1450.78,1484.71 1442.05,1477.57 1400.94,1496.98 1397.55,1530.71 1324.9,1543.75 1309.94,1552.85 1343.45,1556.25 1350.6,1569.8 1341.77,1575.96 1336.49,1589.78 1353.21,1613.03 1359.56,1649.64 1428.05,1706.65 1438.94,1703.54 1485.49,1720.34 1520.45,1747.45 1520.38,1742.18"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159699960"
- class="fil1 str3"
- points="1494.42,1943.21 1488.74,1979.2 1556.27,1967.15 1577.17,2020.35 1590.75,2005.54 1616.07,2007.81 1614.27,2006.04 1646.69,1982.92 1681,1893.37 1670.36,1843.89 1615.98,1806.59 1600.45,1764.83 1600.37,1741.99 1540.33,1728.66 1520.38,1742.18 1520.02,1747.45 1516.69,1768.98 1480.62,1789.12 1451.87,1778.26 1444.64,1768.92 1431.81,1780.17 1442.45,1797.99 1441.24,1819.68 1426.96,1839.2 1441.38,1854.34 1451.75,1905.5 1468.04,1929.41"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159699888"
- class="fil1 str3"
- points="1520.02,1747.45 1516.69,1768.98 1480.62,1789.12 1451.87,1778.26 1444.64,1768.92 1440.54,1772.52 1381.01,1737.54 1366.27,1744.65 1344.03,1729.12 1334.92,1732.92 1331.21,1678.01 1344.15,1678.12 1359.56,1649.64 1428.05,1706.65 1438.94,1703.54 1467.3,1713.78 1485.49,1720.34"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159699816"
- class="fil1 str3"
- points="1353.21,1613.03 1336.49,1589.78 1341.77,1575.96 1350.6,1569.8 1343.45,1556.25 1309.94,1552.85 1303.8,1590.57 1289.52,1580.72 1273.3,1578.6 1258.72,1589.47 1230.71,1589.35 1217.95,1610.3 1235.17,1624.71 1237.65,1665.79 1231.9,1681.26 1201.29,1674.21 1200.45,1681.63 1230.93,1709.32 1222.15,1712.23 1237.51,1757.31 1257.78,1776.69 1299.21,1765.71 1306.63,1753.35 1312.37,1743.79 1334.92,1732.92 1331.21,1678.01 1344.15,1678.12 1359.56,1649.64"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159699744"
- class="fil1 str3"
- points="1334.92,1732.92 1312.37,1743.79 1306.63,1753.35 1318.4,1753.42 1331.59,1766.21 1333.62,1788.04 1426.96,1839.2 1441.24,1819.68 1442.45,1797.99 1431.81,1780.17 1440.54,1772.52 1381.01,1737.54 1366.27,1744.65 1344.03,1729.12"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159699672"
- class="fil1 str3"
- points="1333.62,1788.04 1331.59,1766.21 1318.4,1753.42 1306.63,1753.35 1299.21,1765.71 1257.78,1776.69 1237.51,1757.31 1225.97,1778.79 1217.54,1779.01 1208.55,1798.46 1217.95,1812.39 1225.49,1823.55 1221.52,1834.82 1248.66,1840.68 1251.64,1832.12 1271.25,1836.15 1277.65,1822.96 1292.5,1825.65 1300.69,1818.49 1321.5,1827.14 1338.46,1838.26 1350.57,1828.77 1371.83,1828.94 1385.43,1816.43"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159699600"
- class="fil1 str3"
- points="1494.42,1943.21 1468.04,1929.41 1451.75,1905.5 1441.38,1854.34 1426.96,1839.2 1385.43,1816.43 1371.83,1828.94 1350.57,1828.77 1338.46,1838.26 1311.41,1863.41 1305.1,1877.01 1303.24,1903.57 1308.29,1926.04 1326.97,1939.46 1343.7,1971.11 1320.53,1987.87 1360.91,2034.47 1387.76,1972.61 1455.48,1985.14 1488.74,1979.2"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159699528"
- class="fil1 str3"
- points="1292.5,1825.65 1277.65,1822.96 1271.25,1836.15 1251.64,1832.12 1248.66,1840.68 1221.52,1834.82 1218.44,1852.12 1188.13,1850.14 1186.68,1840.27 1172.87,1832.48 1152.9,1843.74 1152.89,1914.16 1163.78,1927.86 1207.19,1944.29 1225.58,1945.69 1258.55,1948.2 1320.53,1987.87 1343.7,1971.11 1326.97,1939.46 1308.29,1926.04 1303.24,1903.57 1305.1,1877.01 1311.41,1863.41 1338.46,1838.26 1321.5,1827.14 1300.69,1818.49"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159699456"
- class="fil1 str3"
- points="1125.43,1834.94 1110.87,1822.18 1113.15,1807.93 1105.72,1791.46 1092.43,1782.74 1117.62,1757.04 1130.9,1753.14 1135.85,1737.13 1164.36,1723.23 1174.42,1694.04 1200.45,1681.63 1230.93,1709.32 1222.15,1712.23 1237.51,1757.31 1225.97,1778.79 1217.54,1779.01 1208.55,1798.46 1225.49,1823.55 1221.48,1834.77 1218.44,1852.12 1188.13,1850.14 1186.68,1840.27 1172.87,1832.48 1152.9,1843.74 1137.22,1833.3"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- </g>
- <g
- id="_159697896">
- <polygon
- id="_159699360"
- class="fil1 str3"
- points="1123.9,1944.4 1079.19,1985.71 1086.69,2061.72 1078.37,2066.71 1067,2098.89 1100.17,2104.47 1114.73,2111.37 1133.43,2105.15 1141.24,2114.72 1152.48,2105.94 1160.39,2095.96 1165.99,2048.31 1172.68,2039.71 1167.97,2002 1155.66,1990.63 1153.06,1967.92"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159699288"
- class="fil1 str3"
- points="1183.68,2057.16 1165.99,2048.31 1172.68,2039.71 1167.97,2002 1155.66,1990.63 1153.06,1967.92 1123.9,1944.4 1129.2,1939.51 1163.78,1927.86 1207.19,1944.29 1216.89,1954.73 1226.6,1954.58 1231.39,1962.95 1224.06,1973.56 1236.65,1985.33 1239.01,2003.12 1220.71,2012.42 1219.04,2025.35 1227.34,2036.49 1214.54,2047.17 1199.5,2039.49"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159699216"
- class="fil1 str3"
- points="1258.55,1948.2 1207.19,1944.29 1216.89,1954.73 1226.6,1954.58 1231.39,1962.95 1224.06,1973.56 1236.65,1985.33 1239.01,2003.12 1220.71,2012.42 1219.04,2025.35 1227.34,2036.49 1236.69,2050.27 1251.41,2055.15 1265.87,2071.26 1275.12,2090.58 1288.36,2088.61 1316.2,2084.46 1319.86,2090.85 1338.13,2076.41 1336.07,2058.75 1352.47,2024.72 1320.53,1987.87"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159699144"
- class="fil1 str3"
- points="1336.07,2058.75 1352.47,2024.72 1360.91,2034.47 1372.03,2008.84 1391.5,2030.84 1407.04,2032.02 1411,2064.1 1419.71,2071.17 1413.09,2080.85 1417.03,2117.75 1432.35,2126.8 1432.73,2148.51 1419.08,2173.46 1392.71,2161.81 1387.97,2130.55 1381.07,2129.43 1378.42,2146.08 1370.21,2146.01 1367.6,2134.03 1341.53,2120.5 1341.8,2115.52 1342.18,2103.98 1349.54,2097.33 1338.13,2076.41"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159699072"
- class="fil1 str3"
- points="1262.93,2094.59 1267.07,2100.49 1275.12,2090.58 1265.87,2071.26 1251.41,2055.15 1236.69,2050.27 1227.34,2036.49 1214.54,2047.17 1199.5,2039.49 1183.68,2057.16 1165.99,2048.31 1160.39,2095.96 1181.22,2112.45 1181.14,2132.98 1191.04,2135.02 1191.13,2146.22 1206.79,2154.76 1206.38,2150.3 1214.46,2142.46 1209.04,2129.24 1216.49,2111.13 1231.91,2115.3 1242.5,2094.28"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159699000"
- class="fil1 str3"
- points="1267.07,2100.49 1275.12,2090.58 1288.36,2088.61 1316.2,2084.46 1319.86,2090.85 1338.13,2076.41 1349.54,2097.33 1342.18,2103.98 1341.8,2115.52 1325.78,2140.96 1304.25,2165.54 1282.37,2172.4 1275.52,2193.62 1265.61,2193.46 1259.02,2201.73 1238.84,2193.02 1233.27,2165.02 1214.46,2142.46 1209.04,2129.24 1216.49,2111.13 1231.91,2115.3 1242.5,2094.28 1262.93,2094.59"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159698928"
- class="fil1 str3"
- points="1089.65,2234.84 1120.67,2255.67 1132.77,2236.78 1120.75,2220.97 1109.93,2173.15 1094.05,2159.54 1095.44,2135.05 1084.83,2120.65 1062.15,2112.61 1055.2,2138.59 1065.73,2153.22 1069.09,2206.51"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159698856"
- class="fil1 str3"
- points="1084.83,2120.65 1062.15,2112.61 1067,2098.89 1100.17,2104.47 1114.73,2111.37 1133.43,2105.15 1141.24,2114.72 1152.48,2105.94 1160.39,2095.96 1181.22,2112.45 1181.14,2132.98 1191.04,2135.02 1191.13,2146.22 1206.79,2154.76 1206.77,2169.28 1197.06,2169.51 1197.05,2182.9 1186.18,2208.51 1170.13,2213.11 1170.4,2225.78 1132.77,2236.78 1120.75,2220.97 1109.93,2173.15 1094.05,2159.54 1095.44,2135.05"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159698784"
- class="fil1 str3"
- points="1135.26,2265.63 1140.7,2275.76 1139.97,2297.38 1104,2319.46 1091.64,2322.51 1049.57,2270.03 1079.04,2266.19 1087.11,2252.61 1077.41,2243.02 1089.78,2234.82 1120.67,2255.67"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159698712"
- class="fil1 str3"
- points="1197.06,2169.51 1197.05,2182.9 1186.18,2208.51 1210.13,2246.6 1247.95,2240.99 1253.67,2235.47 1262,2216.58 1253.99,2208.93 1259.02,2201.73 1238.84,2193.02 1233.27,2165.02 1214.46,2142.46 1206.38,2150.3 1206.79,2154.76 1206.77,2169.28"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159698640"
- class="fil1 str3"
- points="1265.61,2193.46 1259.02,2201.73 1253.99,2208.93 1262,2216.58 1253.67,2235.47 1247.95,2240.99 1252.52,2253.7 1268.62,2260.23 1295.58,2259.92 1309.62,2265.5 1313.56,2248.05 1321.66,2245.7 1301.12,2235.27 1308.72,2219.08 1307.91,2198.02 1282.37,2172.4 1275.52,2193.62"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159698568"
- class="fil1 str3"
- points="1370.21,2146.01 1367.6,2134.03 1341.53,2120.5 1341.8,2115.52 1325.78,2140.96 1304.25,2165.54 1282.37,2172.4 1307.91,2198.02 1308.72,2219.08 1301.12,2235.27 1321.66,2245.7 1331.09,2234.56 1330.16,2221.81 1350.23,2217.25 1362.14,2199.11 1374.65,2207.34 1386.6,2200.93 1381.06,2174.3 1392.71,2161.22 1387.97,2130.55 1381.07,2129.43 1378.42,2146.08"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159698496"
- class="fil1 str3"
- points="1104,2319.46 1139.97,2297.38 1151.47,2299.72 1164.18,2314.17 1182.91,2374.34 1166.39,2379.08 1168.65,2419.74 1163.01,2417.28 1147.1,2425.9 1140.29,2418.05 1129.41,2419.45 1107,2405.1 1106.95,2396.56 1126.64,2375.5 1121.72,2346.67"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159698424"
- class="fil1 str3"
- points="1135.26,2265.63 1120.67,2255.67 1132.77,2236.78 1170.4,2225.78 1170.13,2213.11 1186.18,2208.51 1210.13,2246.6 1188.52,2259.62 1181.47,2251.41 1173.01,2259.04 1181.53,2287.22 1176.1,2302.98 1174.41,2307.9 1164.18,2314.17 1151.47,2299.72 1139.97,2297.38 1140.7,2275.76"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159698352"
- class="fil1 str3"
- points="1256.57,2356.74 1266.35,2363.2 1250.56,2378.16 1240.17,2406.95 1215.58,2423.61 1204.97,2410.12 1183.5,2415.47 1177.95,2423.8 1168.65,2419.74 1166.39,2379.08 1182.91,2374.34 1164.18,2314.17 1174.41,2307.9 1176.1,2302.98 1186.23,2308.99 1182.55,2324.82 1195.81,2330.66 1205.12,2325 1231.94,2341.95 1254.14,2342.2"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159698280"
- class="fil1 str3"
- points="1392.71,2161.81 1381.06,2174.3 1386.6,2200.93 1374.65,2207.34 1362.14,2199.11 1350.23,2217.25 1330.16,2221.81 1331.09,2234.56 1344.63,2243.27 1351.01,2260.22 1373.95,2265.84 1394.21,2254.04 1399.16,2239.14 1389.45,2228.15 1396.27,2211.19 1414.34,2204.71 1441.82,2208.08 1430.02,2183.28 1419.08,2173.46"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159698208"
- class="fil1 str3"
- points="1399.16,2239.14 1394.21,2254.04 1433.45,2281.73 1438.17,2303.4 1463.16,2314.29 1481.78,2288.71 1464.08,2264.8 1485.88,2248.99 1453.3,2232.2 1441.82,2208.08 1414.34,2204.71 1396.27,2211.19 1389.45,2228.15"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159698136"
- class="fil1 str3"
- points="1433.45,2281.73 1394.21,2254.04 1373.95,2265.84 1373.53,2284.78 1360.87,2287.82 1371.05,2306.22 1377.55,2303.58 1385.85,2368.25 1411.19,2378.94 1428.86,2361.48 1438.93,2358.55 1421.03,2319.07 1434.12,2315.59 1438.17,2303.4"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159698064"
- class="fil1 str3"
- points="1351.01,2260.22 1344.63,2243.27 1331.09,2234.56 1321.66,2245.7 1313.56,2248.05 1309.62,2265.5 1295.58,2259.92 1268.62,2260.23 1252.52,2253.7 1247.95,2240.99 1210.13,2246.6 1188.52,2259.62 1181.47,2251.41 1173.01,2259.04 1181.53,2287.22 1176.1,2302.98 1186.23,2308.99 1182.55,2324.82 1195.81,2330.66 1205.12,2325 1231.94,2341.95 1254.14,2342.2 1278.78,2342.09 1304.93,2358.89 1323.67,2346.4 1362.03,2360.63 1365.68,2375.21 1385.85,2368.25 1377.55,2303.58 1371.05,2306.22 1360.87,2287.82 1373.53,2284.78 1373.95,2265.84"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159697992"
- class="fil1 str3"
- points="1240.17,2406.95 1250.56,2378.16 1266.35,2363.2 1256.57,2356.74 1254.14,2342.2 1278.78,2342.09 1304.93,2358.89 1323.67,2346.4 1362.03,2360.63 1365.68,2375.21 1385.85,2368.25 1411.19,2378.94 1402.76,2387.27 1389.03,2387.28 1389.08,2416.75 1377.16,2415.27 1367.72,2430.91 1378.59,2439.15 1372.33,2451.98 1355.86,2452.02 1342.35,2465.65 1321.89,2441.27 1311.53,2449.46 1291.36,2451.5"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159697920"
- class="fil1 str3"
- points="1342.35,2465.65 1321.89,2441.27 1311.53,2449.46 1291.36,2451.5 1306,2477.13 1331.64,2478.64 1349.11,2494.04 1377.71,2490.78 1423.89,2508.92 1431.16,2491.09 1408.16,2462.43 1391.47,2466.52 1390.09,2451.29 1372.33,2451.98 1355.86,2452.02"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- </g>
- <g
- id="_159696864">
- <polygon
- id="_159697824"
- class="fil1 str3"
- points="1371.85,2008.96 1391.5,2030.84 1407.17,2031.85 1411.13,2063.96 1419.85,2071.03 1436.24,2063.03 1449.2,2068.98 1468.11,2054.46 1458.53,2039.9 1467.73,2014.69 1493.43,2007.79 1493.29,1995.74 1484.34,1992.07 1486.87,1979.72 1455.35,1985.35 1387.63,1972.83"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159697752"
- class="fil1 str3"
- points="1432.35,2126.8 1449.2,2126.77 1464.73,2109.24 1484.01,2104.35 1502.54,2112.96 1520.23,2130.08 1539.12,2132.48 1550.1,2113.39 1535.84,2066.3 1544.99,2040.14 1577.04,2020.53 1556.13,1967.36 1486.87,1979.72 1484.34,1992.07 1493.29,1995.74 1493.43,2007.79 1467.73,2014.69 1458.53,2039.9 1468.11,2054.46 1449.2,2068.98 1436.24,2063.03 1419.85,2071.03 1413.22,2080.72 1417.03,2117.75"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159697680"
- class="fil1 str3"
- points="1664.78,2236.03 1686.02,2228.36 1700.27,2197.3 1716.54,2200.72 1746.88,2188.14 1755.11,2167.8 1789.05,2153.18 1763.98,2135.88 1732.06,2110.73 1687.04,2090.28 1668.91,2064.69 1615.81,2008.01 1590.62,2005.73 1577.17,2020.35 1544.99,2040.14 1535.84,2066.3 1550.1,2113.39 1539.12,2132.48 1548.54,2137.08 1547.92,2149.32 1555.01,2174.6 1566.26,2178 1565.15,2192.49 1577.47,2214.84 1587.64,2219.9 1597.52,2219.99 1609.65,2234.64 1619.32,2223.35 1658.58,2224.26"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159697608"
- class="fil1 str3"
- points="1432.73,2148.51 1432.35,2126.8 1449.2,2126.77 1464.73,2109.24 1484.01,2104.35 1502.54,2112.96 1520.23,2130.08 1539.12,2132.48 1548.54,2137.08 1547.92,2149.32 1555.01,2174.6 1566.26,2178 1565.15,2192.49 1577.47,2214.84 1587.64,2219.9 1559.39,2254.75 1551.18,2247.92 1549.13,2229.58 1533.14,2213.89 1516.75,2228.41 1499.79,2232.19 1498.67,2248.26 1486.01,2248.98 1453.43,2232.17 1430.15,2183.22 1419.21,2173.4"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159697536"
- class="fil1 str3"
- points="1765.79,2389.01 1772.74,2397.32 1763.82,2406.54 1766.76,2415.05 1790.19,2414.95 1806.32,2384.96 1848.05,2252.59 1835.88,2221.84 1800.69,2193.23 1789.05,2153.18 1755.11,2167.8 1746.88,2188.14 1716.54,2200.72 1700.27,2197.3 1686.02,2228.36 1664.78,2236.03 1677.29,2251.42 1701.56,2310.8 1693.62,2326.58 1699.62,2334.41 1707.67,2334.15 1708.96,2341.54 1728.83,2350.72 1723.05,2360.38 1738.67,2371.98 1746.45,2370.72 1755.24,2387.4"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159697464"
- class="fil1 str3"
- points="1625.64,2298.16 1630.61,2314.35 1653.49,2322.57 1667.51,2348.19 1659.82,2354.15 1651.69,2350.13 1649.09,2348.85 1619.19,2369.46 1609.15,2357.41 1568.02,2352.34 1563.26,2367.29 1591.47,2388.54 1593.86,2425.12 1626.36,2436.42 1636.18,2424.51 1652.32,2428.01 1656.49,2421.66 1663.69,2421.61 1670.17,2438.37 1689.29,2442.96 1724.62,2435.47 1726.89,2443.66 1736.85,2442.96 1745.14,2468.57 1752.06,2457.97 1771.07,2450.53 1790.19,2414.95 1766.76,2415.05 1763.82,2406.54 1772.74,2397.32 1765.79,2389.01 1755.24,2387.4 1746.45,2370.72 1738.67,2371.98 1723.05,2360.38 1728.83,2350.72 1724.03,2348.5 1708.96,2341.54 1707.67,2334.15 1699.62,2334.41 1693.62,2326.58 1701.56,2310.8 1677.29,2251.42 1664.78,2236.03 1658.58,2224.26 1619.32,2223.35 1609.65,2234.64 1614.32,2251.47 1610.69,2278.05"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159697392"
- class="fil1 str3"
- points="1630.61,2314.35 1625.64,2298.16 1610.69,2278.05 1614.32,2251.47 1609.65,2234.64 1597.52,2219.99 1587.64,2219.9 1559.39,2254.75 1575.62,2274.88 1575.64,2291.93 1556.5,2308.61 1559.84,2326.23 1567.79,2352.37 1609.15,2357.41 1619.19,2369.46 1649.09,2348.85 1659.82,2354.15 1667.51,2348.19 1653.49,2322.57"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159697320"
- class="fil1 str3"
- points="1516.75,2228.41 1499.79,2232.19 1498.67,2248.26 1486.01,2248.98 1464.21,2264.81 1481.91,2288.72 1507.77,2299.84 1517.6,2332.33 1532.56,2339.8 1559.84,2326.23 1556.5,2308.61 1575.64,2291.93 1575.62,2274.88 1559.39,2254.75 1551.18,2247.92 1549.13,2229.58 1533.14,2213.89"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159697248"
- class="fil1 str3"
- points="1463.29,2314.33 1481.91,2288.72 1507.77,2299.84 1517.6,2332.33 1522.2,2334.63 1517.42,2345.65 1508.19,2346.44 1489.03,2337.82 1473.06,2356.29 1483.37,2367.29 1472.33,2381.74 1451.15,2362.31 1438.93,2358.55 1421.16,2319.11 1434.25,2315.62 1438.3,2303.43"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159697176"
- class="fil1 str3"
- points="1473.06,2356.29 1489.03,2337.82 1508.19,2346.44 1517.42,2345.65 1522.2,2334.63 1532.56,2339.8 1559.84,2326.23 1568.02,2352.34 1563.26,2367.29 1591.47,2388.54 1593.86,2425.12 1574.18,2445.35 1560.87,2432.19 1526.07,2436.91 1517.62,2426.52 1503.41,2435.19 1489.33,2425.11 1495.39,2410.75 1481.01,2398.62 1479.1,2388 1472.33,2381.74 1483.37,2367.29"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159697104"
- class="fil1 str3"
- points="1656.49,2421.66 1663.69,2421.61 1670.17,2438.37 1689.29,2442.96 1724.62,2435.47 1726.89,2443.66 1736.85,2442.96 1745.14,2468.57 1723.6,2501.57 1707.85,2529.06 1688.17,2519.82 1684.29,2509.96 1664.89,2509.08 1659.65,2477.7 1640.91,2471.35 1628.18,2475.73 1623.57,2459.14 1630.09,2455.65 1626.36,2436.42 1636.18,2424.51 1652.32,2428.01"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159697032"
- class="fil1 str3"
- points="1602.13,2555.55 1636.74,2570.42 1649.57,2599.38 1665.27,2590.89 1683.08,2572.45 1707.85,2529.06 1688.17,2519.82 1684.29,2509.96 1664.89,2509.08 1659.65,2477.7 1640.91,2471.35 1629.36,2475.73 1613.58,2483.99 1624.26,2486.92 1615.31,2499.72 1596.08,2490.67 1583.28,2501.24 1555.61,2482.22 1544.88,2484.29 1551.22,2518.59 1565.06,2522.92 1582.07,2516.84 1595.2,2522.07"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159696960"
- class="fil1 str3"
- points="1615.31,2499.72 1596.08,2490.67 1583.28,2501.24 1555.61,2482.22 1544.88,2484.29 1526.09,2453.63 1526.07,2436.91 1560.87,2432.19 1574.18,2445.35 1593.86,2425.12 1626.36,2436.42 1630.09,2455.65 1623.57,2459.14 1628.18,2475.73 1613.58,2483.99 1624.26,2486.92"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159696888"
- class="fil1 str3"
- points="1565.06,2522.92 1551.22,2518.59 1556.03,2545.38 1575.32,2553.81 1583.06,2571.55 1576.69,2579.58 1588.01,2602.55 1575.24,2639.59 1649.57,2599.38 1636.74,2570.42 1602.13,2555.55 1595.2,2522.07 1582.07,2516.84"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- </g>
- <g
- id="_159695184">
- <polygon
- id="_159696792"
- class="fil1 str3"
- points="1008.31,2158.9 1000.6,2167.73 985.741,2167.58 951.776,2158.08 920.687,2100.29 927.197,2059.84 941.998,2053.69 954.771,2062.46 988.916,2085.88 1012.63,2085.96 1022.17,2093.91 1031.13,2112.83 1062.02,2112.72 1055.2,2138.59 1065.73,2153.22 1066.42,2163.77 1030.06,2155.63"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159696720"
- class="fil1 str3"
- points="864.99,2161.31 866.13,2130.15 890.26,2104.44 902.573,2102.34 920.687,2100.29 951.776,2158.08 914.11,2173.68 880.3,2170.79"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159696648"
- class="fil1 str3"
- points="1052.71,2273.96 1038.94,2290.88 1001.68,2272.63 997.067,2260.99 985.818,2262.87 972.074,2248.54 977.676,2239.46 974.56,2228.24 954.129,2216.64 951.776,2158.08 985.741,2167.58 1000.6,2167.73 1008.31,2158.9 1030.06,2155.63 1066.42,2163.77 1069.22,2206.47 1089.65,2234.84 1077.54,2243.01 1087.11,2252.61 1079.17,2266.2 1049.7,2270.03"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159696576"
- class="fil1 str3"
- points="864.99,2161.31 880.3,2170.79 914.11,2173.68 951.776,2158.08 954.129,2216.64 926.402,2219.2 925.593,2235.61 911.808,2235.74 905.184,2228.21 884.096,2228.41 884.342,2220.69 863.575,2199.98"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159696504"
- class="fil1 str3"
- points="967.874,2278.37 946.189,2301.32 925.339,2279.61 925.471,2266.71 910.22,2265.53 911.808,2235.74 925.593,2235.61 926.402,2219.2 954.129,2216.64 974.56,2228.24 977.676,2239.46 972.074,2248.54 985.818,2262.87 997.067,2260.99 1001.68,2272.63 986.718,2287.75 977.87,2277.21"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159696432"
- class="fil1 str3"
- points="911.836,2294.35 899.929,2291.6 886,2298.19 884.918,2308.96 891.319,2317.5 885.861,2321.39 867.589,2315.07 849.88,2314.85 824.237,2332.36 806.687,2286.3 815.776,2279.18 802.543,2261.43 801.596,2253.75 830.301,2259.6 848.196,2244.3 860.427,2247.2 884.096,2228.41 905.184,2228.21 911.808,2235.74 910.22,2265.53 925.471,2266.71 925.339,2279.61 946.189,2301.32 928.206,2307.26"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159696360"
- class="fil1 str3"
- points="808.231,2208.56 814.137,2204.71 840.551,2194.96 863.575,2199.98 884.342,2220.69 884.096,2228.41 860.427,2247.2 848.196,2244.3 830.301,2259.6 801.596,2253.75 800.65,2246.07 797.81,2223.04"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159696288"
- class="fil1 str3"
- points="967.874,2278.37 946.189,2301.32 928.504,2307.16 911.836,2294.35 899.929,2291.6 886,2298.19 884.918,2308.96 891.319,2317.5 885.861,2321.39 867.589,2315.07 849.88,2314.85 824.237,2332.36 829.202,2347.65 856.512,2388.56 884.617,2373.15 889.963,2380.49 922.859,2378.53 928.514,2389.62 957.576,2393.78 969.151,2385.03 966.099,2345.53 970.099,2332.71 996.348,2325.83 997.801,2311.28 986.718,2287.75 977.87,2277.21"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159696216"
- class="fil1 str3"
- points="970.099,2332.71 996.348,2325.83 997.801,2311.28 986.718,2287.75 1001.68,2272.63 1038.94,2290.88 1052.71,2273.96 1072.23,2298.22 1042.22,2302.25 1063.82,2325.34 1063.76,2338.85 1073.45,2347.16 1047.26,2381 1038.31,2386.71 1031.45,2398.98 1009.25,2394.92 988.733,2403.29 985.841,2389.84 969.151,2385.03 966.099,2345.53"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159696144"
- class="fil1 str3"
- points="928.514,2389.62 957.576,2393.78 969.151,2385.03 985.841,2389.84 988.698,2403.13 981.52,2411.1 979.778,2424.44 975.248,2436.05 956.504,2434.66 939.318,2437.22 926.471,2428.87 914.596,2426.75"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159696072"
- class="fil1 str3"
- points="1073.45,2347.16 1063.76,2338.85 1063.82,2325.34 1042.22,2302.25 1072.23,2298.22 1091.64,2322.51 1103.87,2319.42 1121.72,2346.67 1126.77,2375.58 1107.08,2396.66 1071.18,2389.21 1072.48,2414.23 1064.9,2414.13 1048.17,2391.95 1047.26,2381"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159696000"
- class="fil1 str3"
- points="1063.14,2493.35 1047.57,2501.09 1034.58,2476.96 1017.26,2458.72 1016.58,2438.05 1003.01,2438.1 979.778,2424.44 981.52,2411.1 988.961,2402.84 1009.25,2394.92 1031.45,2398.98 1038.31,2386.71 1047.26,2381 1048.17,2391.95 1064.9,2414.13 1072.48,2414.23 1072.76,2430.94 1083.59,2437.61 1070.72,2452.13 1087.34,2499.92"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159695928"
- class="fil1 str3"
- points="1070.72,2452.13 1083.59,2437.61 1072.76,2430.94 1072.48,2414.23 1071.18,2389.21 1107.08,2396.66 1107,2405.1 1129.41,2419.45 1140.42,2418.16 1146.97,2425.78 1136.55,2433.22 1153.07,2451.48 1138.33,2456.7 1129.75,2493.81 1112.07,2484.81 1087.34,2499.92"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159695856"
- class="fil1 str3"
- points="833.086,2422.25 825.52,2404.73 831.235,2365.9 823.655,2355.54 829.202,2347.65 856.512,2388.56 884.617,2373.15 889.963,2380.49 922.859,2378.53 928.514,2389.62 914.596,2426.75 908.87,2425.68 900.712,2436.03 900.477,2457.55 884.521,2457.69 875.308,2445.56 862.272,2452.35"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159695784"
- class="fil1 str3"
- points="870.839,2541.65 853.961,2546.7 847.065,2520.15 824.279,2496.5 811.397,2501.12 790.749,2497.03 782.995,2474.88 771.722,2477 750.251,2464.15 750.148,2435.87 770.715,2412.47 797.152,2416.3 803.266,2405.07 825.52,2404.73 833.356,2421.99 862.541,2452.09 875.308,2445.56 884.521,2457.69 900.477,2457.55 900.341,2483.95 887.282,2492.83 868.514,2516.56"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159695712"
- class="fil1 str3"
- points="900.341,2483.95 900.477,2457.55 900.712,2436.03 908.87,2425.68 926.471,2428.87 939.318,2437.22 941.784,2450.95 953.513,2450.58 963.669,2460.6 957.427,2486.08 943.734,2486.09 940.679,2503.45 931.284,2509.22 921.582,2509.1 887.282,2492.83"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159695640"
- class="fil1 str3"
- points="1031.85,2580.61 1030.62,2559.06 1007.3,2543.59 964.979,2530.08 969.126,2510.5 960.181,2505.4 964.376,2489.08 978.249,2488.99 982.95,2498.63 996.419,2500.25 1005.99,2509.55 987.476,2513.4 987.67,2519.82 988.978,2523.69 1009.75,2528.11 1016.88,2520.54 1019.92,2523.62 1030.88,2531.04 1032.97,2515.32 1047.57,2501.09 1034.58,2476.96 1017.26,2458.72 1016.58,2438.05 1003.01,2438.1 979.778,2424.44 975.248,2436.05 956.504,2434.66 939.318,2437.22 941.784,2450.95 953.513,2450.58 963.669,2460.6 957.427,2486.08 943.734,2486.09 940.679,2503.45 931.284,2509.22 941.95,2529.11 933.362,2545.84 942.795,2555.4 937.717,2566.33 971.397,2606.13 997.357,2608.59 1001.21,2597.28 1018.1,2598.86"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159695568"
- class="fil1 str3"
- points="960.181,2505.4 964.376,2489.08 978.249,2488.99 982.95,2498.63 996.419,2500.25 1005.99,2509.55 987.476,2513.4 987.67,2519.82 988.978,2523.69 1009.75,2528.11 1007.3,2543.59 964.979,2530.08 969.126,2510.5"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159695496"
- class="fil1 str3"
- points="1009.75,2528.11 1016.88,2520.54 1019.92,2523.62 1030.8,2531.21 1032.97,2515.32 1047.57,2501.09 1063.14,2493.35 1087.34,2499.92 1073.58,2528.45 1081.62,2543.21 1064.93,2546.84 1055.8,2560.61 1046.12,2549.84 1032.9,2549.89 1030.62,2559.06 1007.22,2543.76"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159695424"
- class="fil1 str3"
- points="997.357,2608.59 1001.21,2597.28 1018.1,2598.86 1023.8,2608.45 1020.62,2632.25 1004.25,2660.56 991.77,2654.62 968.256,2665.41 963.368,2633.49 971.397,2606.13"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159695352"
- class="fil1 str3"
- points="855.727,2677.44 860.037,2667.95 882.17,2677.44 877.316,2648.33 888.537,2627.54 919.156,2642.82 943.918,2644.78 951.19,2635.95 963.368,2633.49 968.256,2665.41 952.598,2721.78 875.177,2729.06 876.373,2705.54 857.886,2690.29"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159695280"
- class="fil1 str3"
- points="1030.62,2559.06 1032.9,2549.89 1046.12,2549.84 1055.8,2560.61 1064.93,2546.84 1081.62,2543.21 1095.71,2569.11 1089.18,2578.96 1089.51,2581.31 1094.35,2633.26 1115.79,2664.92 1110.41,2684 1091.63,2678 1089.21,2685.26 1059.76,2673.6 1038.87,2641.43 1020.62,2632.25 1023.8,2608.45 1018.1,2598.86 1031.85,2580.61"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159695208"
- class="fil1 str3"
- points="863.048,2625.71 862.962,2632.14 855.746,2632.58 853.548,2626.45 848.018,2630.15 850.892,2639.92 849.764,2652.02 857.353,2656.57 859.788,2655.2 869.772,2661.13 860.037,2667.95 882.17,2677.44 877.316,2648.33 888.537,2627.54 919.156,2642.82 943.918,2644.78 951.19,2635.95 963.368,2633.49 971.397,2606.13 937.348,2566.23 942.795,2555.4 933.362,2545.84 941.95,2529.11 931.284,2509.22 921.582,2509.1 887.282,2492.83 868.514,2516.56 870.839,2541.65 853.961,2546.7 839.501,2569.81 835.201,2562.17 821.734,2581.68 855.993,2624.48"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- </g>
- <g
- id="_123528456">
- <polygon
- id="_159695112"
- class="fil1 str3"
- points="1494.89,2705.66 1479.58,2704.97 1465.08,2692.85 1464.8,2685.67 1467.17,2674.77 1483.92,2659.63 1506.16,2671.56 1528.56,2644.05 1503.1,2621.1 1522.22,2601.11 1532.64,2604.47 1545,2619.18 1561.43,2584.84 1576.69,2579.58 1588.01,2602.55 1575.24,2639.59 1574.78,2639.83 1569.12,2655.94 1544.82,2664.15 1525.75,2695.78"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159695040"
- class="fil1 str3"
- points="1263.4,2498.37 1271.98,2514.83 1282.3,2515.17 1282.39,2549.63 1260.51,2553.29 1247.99,2543.27 1244.6,2558.92 1208.71,2506.55 1193.04,2511.38 1184.93,2508.8 1179.53,2520.31 1167.49,2524.11 1137.18,2461.61 1138.33,2456.7 1153.07,2451.48 1136.42,2433.1 1146.97,2425.78 1162.88,2417.16 1168.65,2419.74 1177.82,2423.69 1183.37,2415.36 1204.84,2410.01 1215.45,2423.49 1240.04,2406.84 1291.36,2451.5 1280.47,2470.46 1261.34,2473.82"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_159694968"
- class="fil1 str3"
- points="1282.39,2552.58 1282.39,2549.63 1282.3,2515.17 1271.98,2514.83 1263.4,2498.37 1261.34,2473.82 1280.47,2470.46 1291.23,2451.36 1306,2477.13 1331.77,2478.8 1344.76,2490.21 1338.57,2505.2 1347.2,2528.48 1323.72,2536.79 1312.79,2548.68 1310.29,2561.53 1308.91,2568.64"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_88495024"
- class="fil1 str3"
- points="1188.93,2704.97 1198.08,2683.25 1238.38,2693.07 1260.97,2690.62 1269.3,2707.13 1280.39,2707.17 1279.58,2719.23 1296.67,2728.08 1321.5,2707.48 1318.4,2669.02 1299.04,2657.84 1277.23,2654.5 1249.26,2600.19 1256.04,2592.11 1258.98,2579.17 1244.6,2558.92 1208.71,2506.55 1193.04,2511.38 1184.93,2508.8 1179.53,2520.31 1167.49,2524.11 1163.68,2539.7 1209.92,2576.34 1177.08,2589.71 1160.81,2609.65 1166.55,2637.15 1187.77,2677.45"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123235464"
- class="fil1 str3"
- points="1089.4,2581.34 1089.18,2578.96 1095.71,2569.11 1081.62,2543.21 1073.45,2528.26 1087.34,2499.92 1111.94,2484.65 1129.62,2493.64 1137.18,2461.61 1167.49,2524.11 1163.68,2539.7 1209.92,2576.34 1177.08,2589.71 1160.81,2609.65 1143.63,2619.77 1124.87,2609.28 1092.36,2612.4"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_124843672"
- class="fil1 str3"
- points="1490.44,2458.02 1483.8,2451.46 1470.87,2458.58 1474.53,2468.67 1470.61,2477.94 1460.27,2476.77 1449.22,2466.58 1443.62,2474.97 1451.96,2491.29 1448.15,2493.32 1436.53,2480.17 1431.03,2490.93 1408.03,2462.28 1391.34,2466.37 1390.09,2451.29 1372.33,2451.98 1378.59,2439.15 1367.72,2430.91 1377.16,2415.27 1389.08,2416.75 1389.03,2387.28 1402.76,2387.27 1428.86,2361.48 1438.93,2358.55 1451.29,2362.39 1472.33,2381.74 1479.1,2388 1481.01,2398.62 1495.39,2410.75 1489.33,2425.11 1503.41,2435.19 1507.46,2450.69"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_124866928"
- class="fil1 str3"
- points="1503.1,2621.1 1483.5,2572.15 1471.14,2561.72 1497.94,2551.71 1503.39,2532.56 1529.7,2524.43 1526.52,2510.37 1548.95,2506.62 1556.03,2545.38 1575.32,2553.81 1583.06,2571.55 1576.69,2579.58 1561.43,2584.84 1545,2619.18 1532.64,2604.47 1522.22,2601.11"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_124851856"
- class="fil1 str3"
- points="1507.46,2450.69 1490.44,2458.02 1483.8,2451.46 1470.87,2458.58 1474.53,2468.67 1470.61,2477.94 1460.27,2476.77 1449.22,2466.58 1443.62,2474.97 1451.96,2491.29 1448.15,2493.32 1436.53,2480.17 1431.03,2490.93 1423.76,2508.74 1393.72,2497.02 1387.84,2510.31 1400.24,2518.03 1407.61,2517.24 1427.22,2529.12 1448.66,2567.59 1436.71,2580.38 1419.47,2575.41 1400.23,2596.23 1400.52,2604.94 1421.43,2615.35 1429.66,2636.27 1424.43,2649.2 1431.74,2658.48 1431.12,2669.58 1464.8,2685.67 1467.17,2674.77 1483.92,2659.63 1506.16,2671.56 1528.56,2644.05 1503.1,2621.1 1483.5,2572.15 1471.14,2561.72 1450.61,2545.74 1457.9,2536.79 1428.78,2512.87 1435.15,2487.46 1440.1,2487.72 1448.25,2496.23 1453.71,2490.52 1449.91,2483.43 1447.73,2474.6 1449.54,2470.34 1460.92,2480.02 1470.46,2479.68 1469.36,2492.46 1492.04,2523.26 1503.39,2532.56 1529.7,2524.43 1526.52,2510.37 1548.95,2506.62 1544.88,2484.29 1526.09,2453.63 1526.07,2436.91 1517.62,2426.52 1503.41,2435.19"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123522888"
- class="fil1 str3"
- points="1497.94,2551.71 1471.14,2561.72 1450.61,2545.74 1457.9,2536.79 1428.78,2512.87 1435.15,2487.46 1440.1,2487.72 1448.25,2496.23 1453.71,2490.52 1449.91,2483.43 1447.73,2474.6 1449.54,2470.34 1460.92,2480.02 1470.46,2479.68 1469.36,2492.46 1492.04,2523.26 1503.39,2532.56"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_124857088"
- class="fil1 str3"
- points="1367.29,2574.42 1356.68,2567.39 1344.75,2574.98 1310.29,2561.53 1312.79,2548.68 1323.72,2536.79 1347.2,2528.48 1338.57,2505.2 1344.76,2490.21 1349.11,2494.04 1377.71,2490.78 1393.72,2497.02 1387.84,2510.31 1400.24,2518.03 1407.61,2517.24 1427.22,2529.12 1448.66,2567.59 1436.71,2580.38 1419.47,2575.41 1400.23,2596.23"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123535488"
- class="fil1 str3"
- points="1410.76,2687.38 1405.52,2673.33 1367.27,2659.2 1353.24,2641.51 1370.42,2638.05 1352.33,2620.25 1363.08,2603.32 1352.86,2595.01 1367.29,2574.42 1400.23,2596.23 1400.52,2604.94 1421.43,2615.35 1429.66,2636.27 1424.43,2649.2 1431.74,2658.48 1431.12,2669.58 1464.8,2685.67 1465.08,2692.85 1479.58,2704.97 1464.27,2704.28"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123522696"
- class="fil1 str3"
- points="1363.08,2603.32 1352.33,2620.25 1370.42,2638.05 1353.24,2641.51 1367.27,2659.2 1351.42,2676.96 1335.69,2670.87 1329.03,2679.21 1334.37,2692.89 1331.75,2701.94 1321.5,2707.48 1318.4,2669.02 1299.04,2657.84 1277.23,2654.5 1249.26,2600.19 1256.04,2592.11 1258.98,2579.17 1244.6,2558.92 1247.99,2543.27 1260.51,2553.29 1282.39,2549.63 1282.39,2552.58 1308.91,2568.64 1310.29,2561.53 1344.75,2574.98 1356.68,2567.39 1367.29,2574.42 1352.86,2595.01"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123509784"
- class="fil1 str3"
- points="1295.86,2759.3 1292.87,2747.67 1301.05,2740.55 1296.67,2728.08 1321.5,2707.48 1331.75,2701.94 1334.37,2692.89 1329.03,2679.21 1335.69,2670.87 1351.42,2676.96 1367.27,2659.2 1405.52,2673.33 1410.76,2687.38 1464.27,2704.28 1459.43,2721.3 1421.92,2721.53 1407.65,2710.65 1400.05,2729.45 1374.61,2760.91 1324.79,2765.24"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123521664"
- class="fil1 str3"
- points="1246.36,2752.77 1208.29,2752.58 1196.11,2738.55 1195.8,2726.88 1188.33,2726.88 1185.03,2716.33 1188.93,2704.97 1198.08,2683.25 1238.38,2693.07 1260.97,2690.62 1269.3,2707.13 1280.39,2706.58 1279.58,2719.23 1296.67,2728.08 1301.05,2740.55 1292.87,2747.67 1295.86,2759.3 1291.58,2758.42 1270.32,2767.13"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_124238256"
- class="fil1 str3"
- points="1208.29,2752.58 1204.56,2759.61 1189.19,2758.34 1182.67,2768.32 1201.56,2779.62 1219.84,2776.96 1237.75,2796.12 1231.64,2807.96 1238.68,2822.25 1217.13,2827.42 1200.87,2832.93 1172.81,2819.03 1172.74,2792.15 1152.52,2791.73 1152.26,2807.36 1137.1,2815.17 1120.95,2789.57 1110.07,2793.94 1108.9,2778.31 1100.22,2777.05 1085.72,2763.48 1124.21,2763.37 1124.06,2742.75 1119.68,2732.6 1133.83,2723.52 1133.76,2706.02 1140.43,2694.65 1159.04,2696.69 1165.29,2714.69 1185.03,2716.33 1188.33,2726.88 1195.8,2726.88 1196.11,2738.55"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123525384"
- class="fil1 str3"
- points="1127.32,2711.51 1118.47,2704.69 1110.41,2684 1115.66,2664.63 1094.35,2633.26 1092.36,2612.4 1124.87,2609.28 1143.63,2619.77 1160.81,2609.65 1166.55,2637.15 1187.77,2677.45 1188.93,2704.97 1185.03,2716.33 1165.29,2714.69 1159.04,2696.69 1140.43,2694.65 1133.76,2706.02"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_124863688"
- class="fil1 str3"
- points="1078.95,2711.93 1091.63,2678 1110.41,2684 1118.47,2704.69 1127.32,2711.51 1133.76,2706.02 1133.83,2723.52 1119.68,2732.6 1124.06,2742.75 1124.21,2763.37 1085.72,2763.48 1085.02,2750.82 1075.46,2744.04"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- </g>
- <g
- id="_123515016">
- <polygon
- id="_123514800"
- class="fil1 str3"
- points="708.601,2037.06 725.955,2036.66 734.373,2027.64 697.399,1997.91 686.719,2006.19 680.638,1997.15 657.422,2008.47 624.552,1983.92 618.297,1992.4 609.406,2001.45 625.958,2026.78 650.048,2036.58 682.31,2087.69 699.942,2096.18 714.195,2113.64 722.083,2088.15 701.553,2050.89 693.091,2053.3 683.972,2037.18 697.788,2028.25"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123507216"
- class="fil1 str3"
- points="602.732,2104.25 604.143,2072.32 560.912,2033.72 591.47,2034.67 599.345,2005.73 606.724,2003.75 609.406,2001.45 625.958,2026.78 650.048,2036.58 682.31,2087.69 658.233,2087.36 649.109,2114.14 637.041,2124.73 619.645,2119.72"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123531504"
- class="fil1 str3"
- points="574.065,2009.34 586.191,2001.6 599.345,2005.73 591.47,2034.67 560.912,2033.72 555.89,2029.24 565.518,2020.94 572.222,2018.05"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <g
- id="g304">
- <polygon
- id="_123532512"
- class="fil1 str3"
- points="569.454,1974.32 570.959,1969.43 577.903,1975.51 576.704,1989.53 573.135,1993.22 570.525,1995.92 565.75,1986.37"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123522432"
- class="fil1 str3"
- points="606.724,2003.75 609.406,2001.45 618.297,1992.4 609.713,1968.71 604.111,1953.24 594.918,1967 584.997,1973.56 587.76,1989.75 586.191,2001.6 599.345,2005.73"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- </g>
- <polygon
- id="_123529656"
- class="fil1 str3"
- points="586.682,2125.52 619.645,2119.72 602.732,2104.25 604.143,2072.32 560.912,2033.72 555.89,2029.24 554.878,2034.13 545.861,2040.72 542.07,2057.32 535.479,2048.67 528.625,2052.44 523.646,2074 516.005,2074.45 512.029,2079.73 514.431,2087.5 519.963,2093.06 532.104,2120.31 555.396,2140.77"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <g
- id="g309">
- <polygon
- id="_123518352"
- class="fil1 str3"
- points="497.993,2124.8 501.968,2126.49 508.455,2123.19 509.281,2133.22 506.071,2139.25 503.452,2143.4 494.267,2138.97 490.328,2137.22 482.23,2137.44 478.94,2137.53 475.034,2128.84 488.055,2120.59"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123526800"
- class="fil1 str3"
- points="454.604,2077.04 457.238,2076.28 461.144,2080.19 460.813,2088.57 456.24,2089.75 452.897,2090.62 448.122,2078.89"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123532416"
- class="fil1 str3"
- points="491.136,2114.13 481.213,2114.63 476.51,2118.25 474.6,2119.72 469.825,2119.28 479.808,2103.21 488.923,2103.21 494.523,2108.46 492.567,2111.73"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123509688"
- class="fil1 str3"
- points="527.665,2131.1 532.104,2120.31 555.396,2140.77 555.031,2165.28 563.071,2165.56 569.468,2193.63 553.069,2193.43 535.39,2198.79 521.204,2212.05 504.679,2205.76 479.858,2180.12 478.448,2170.6 469.279,2140.47 495.38,2149.82 508.39,2146.78 516.539,2131.32"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- </g>
- <polygon
- id="_123526632"
- class="fil1 str3"
- points="521.204,2212.05 535.39,2198.79 553.069,2193.43 518.675,2253.04 521.205,2270.12 505.575,2286.54 497.439,2253.13 486.195,2236.05 504.679,2205.76"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123534936"
- class="fil1 str3"
- points="504.679,2205.76 486.195,2236.05 456.831,2205.46 479.858,2180.12"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <g
- id="g317">
- <polygon
- id="_123523032"
- class="fil1 str3"
- points="444.259,2136.72 436.94,2129.83 433.472,2137.47 432.063,2140.57 426.42,2139.27 426.42,2128.84 434.233,2119.72 446.344,2130.17 445.139,2133.95"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123521784"
- class="fil1 str3"
- points="368.257,2111.03 362.393,2111.03 360.01,2111.03 363.483,2101.91 368.691,2091.92 374.291,2091.95 374.375,2097.52 374.437,2101.6"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123524160"
- class="fil1 str3"
- points="389.96,2117.11 382.552,2117.11 379.543,2117.11 374.768,2108.86 385.185,2100.61 392.521,2100.64 394.611,2105.46 396.139,2108.98"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123532392"
- class="fil1 str3"
- points="378.198,2166.66 369.228,2164.58 363.049,2158.81 356.104,2158.38 346.555,2121.89 353.065,2119.72 358.254,2125.56 367.337,2116.45 373.466,2121.89 373.643,2128.93 370.034,2132.39 367.395,2134.92 370.679,2140.64 377.934,2140.87 380.882,2140.97 384.805,2132.63 393.218,2134.91 400.059,2149.8 395.924,2160.55 384.637,2156.59"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123521928"
- class="fil1 str3"
- points="460.629,2137.37 469.279,2140.47 478.448,2170.6 479.858,2180.12 456.831,2205.46 437.999,2253.13 405.042,2221.35 422.274,2202.18 436.107,2205.5 443.336,2190.18 445.199,2172.29 435.458,2167.51 427.14,2175.11 410.657,2163.49 411.427,2141.71 419.5,2133.51 424.363,2148.04 435.891,2147.78"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- </g>
- <polygon
- id="_123515736"
- class="fil1 str3"
- points="395.853,2199.94 385.845,2193.29 381.18,2200.87 391.702,2208.89 396.191,2218.55 405.042,2221.35 422.274,2202.18 436.107,2205.5 443.336,2190.18 445.199,2172.29 435.458,2167.51 427.14,2175.11 410.657,2163.49 402.223,2173.97 403.459,2181.86 413.408,2190.53 416.553,2198.31 411.394,2200.31 402.206,2197.86"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123525312"
- class="fil1 str3"
- points="431.183,2264.34 437.999,2253.13 456.831,2205.46 486.195,2236.05 497.439,2253.13 505.575,2286.54 491.621,2301.21 454.775,2288.95"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <g
- id="g326">
- <polygon
- id="_123512136"
- class="fil1 str3"
- points="308.792,2223.1 304.471,2223.1 302.716,2223.1 299.243,2216.58 305.32,2207.46 311.788,2210.1 311.621,2214.42 311.5,2217.57"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123518040"
- class="fil1 str3"
- points="359.968,2221.39 357.943,2230.61 353.857,2230.52 352.197,2230.48 346.555,2225.7 346.555,2211.8 352.197,2208.33 359.013,2213.87 359.564,2218.22"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123506688"
- class="fil1 str3"
- points="437.999,2253.13 431.183,2264.34 424.509,2272.14 422.735,2290.44 368.826,2294.62 367.633,2271.65 371.529,2267.62 370.303,2256.45 381.609,2255.16 385.901,2250.78 384.587,2240.35 395.125,2230.34 396.191,2218.55 405.042,2221.35"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- </g>
- <g
- id="g331">
- <polygon
- id="_123526896"
- class="fil1 str3"
- points="347.857,2267.84 344.153,2270.93 342.648,2272.18 335.269,2267.84 340.478,2259.15 349.55,2254.84 351.891,2259.91 353.602,2263.62"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123530064"
- class="fil1 str3"
- points="334.401,2304.76 329.772,2305.07 327.891,2305.19 325.72,2300.85 326.588,2290.86 330.452,2290.02 333.795,2296.85 336.24,2301.84"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123524664"
- class="fil1 str3"
- points="331.973,2310.95 331.011,2315.73 362.649,2315.76 368.826,2294.62 367.633,2271.65 371.529,2267.62 370.303,2256.45 369.587,2250.92 358.574,2254.71 355.58,2272.87 349.848,2279 338.504,2278.41 337.303,2283.26 344.031,2290.92 343.06,2299.64"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- </g>
- <g
- id="g336">
- <polygon
- id="_123526992"
- class="fil1 str3"
- points="324.852,2362.09 321.148,2358.39 319.644,2356.88 321.773,2350.78 324.809,2346.49 331.466,2353.97 331.657,2356.4 331.797,2358.19"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123528384"
- class="fil1 str3"
- points="347.952,2415.57 358.025,2401.86 350.075,2389.46 332.954,2400.61 337.853,2381.11 333.22,2376.18 335.43,2357.44 345.35,2341.23 344.328,2334.69 339.132,2330.79 332.311,2336.53 328.473,2331.91 331.011,2315.73 362.649,2315.76 368.826,2294.62 422.735,2290.44 421.21,2308.62 428.463,2316.31 404.054,2342.78 384.527,2400.54 372.634,2422.35 349.233,2436.92 359.461,2423.29 360.11,2416.17"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- </g>
- <polygon
- id="_123504672"
- class="fil1 str3"
- points="332.954,2400.61 350.075,2389.46 358.025,2401.86 347.952,2415.57 338.319,2415.1 331.84,2405.05"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123528288"
- class="fil1 str3"
- points="363.097,2528.12 347.887,2541.99 347.236,2539.57 339.362,2526.5 346.611,2498.97 354.361,2486.29 353.9,2475 365.851,2462.21 364.27,2454.11 349.269,2448.25 349.233,2436.92 372.634,2422.35 384.527,2400.54 392.2,2419.5 403.237,2423.14 403.809,2451.54 410.475,2454.41 417.712,2464.96 402.523,2474.65 405.334,2489.15 397.085,2495.68 393.829,2524.51"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- </g>
- <g
- id="_123507120">
- <g
- id="g343">
- <polygon
- id="_123516168"
- class="fil1 str3"
- points="951.99,1578.88 947.584,1569.28 956.308,1557.58 956.364,1539.27 964.998,1535.58 995.78,1539.13 1006.02,1540.57 1026.35,1524.47 1049.79,1525.04 1057.21,1535.21 1061.89,1556.18 1052.16,1556.41 1014.05,1547.56 999.253,1557.49 995.823,1568.69 1006.78,1577.38 1009.75,1587.79 1004.51,1600.44 980.109,1590.58 969.772,1595.81 964.457,1586.08"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123524544"
- class="fil1 str3"
- points="951.187,1592.83 944.242,1592.83 937.731,1587.19 941.204,1581.11 949.971,1584.43"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- </g>
- <polygon
- id="_123511296"
- class="fil1 str3"
- points="892.558,1634.74 881.896,1628.14 870.453,1631.06 860.036,1606.73 866.113,1595.44 899.535,1587.62 908.877,1598.64 918.083,1598.51 923.98,1595.47 929.149,1600.17 928.93,1606.22 916.609,1611.27 904.132,1603 894.158,1605.66 901.318,1628.45"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <g
- id="g348">
- <polygon
- id="_123532296"
- class="fil1 str3"
- points="723.31,1855.63 715.497,1858.67 714.87,1862.05 713.327,1870.39 720.706,1869.96 722.576,1866.59 725.133,1861.99"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123513816"
- class="fil1 str3"
- points="757.474,1842.06 749.922,1837.06 740.913,1850.69 733.448,1856.71 725.828,1868.31 716.105,1883.13 714.896,1906.75 734.808,1934.22 747.243,1934.05 756.618,1942.5 764.428,1938.25 755.457,1926.07 763.583,1910.81 784.212,1906.8 790.68,1932.63 813.538,1928.76 820.94,1917.54 805.498,1897.4 795.716,1869.35 807.846,1863.11 805.145,1847.66 816.72,1831.45 771.579,1811.3 763.857,1823.97 763.625,1838.73"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- </g>
- <polygon
- id="_123511080"
- class="fil1 str3"
- points="1001.06,1906.9 1018.13,1898.21 1004.95,1874.74 981.21,1828.82 976.195,1818.34 955.644,1835.42 941.487,1835.27 941.464,1849.9 932.232,1856.91 920.747,1879.77 899.164,1883.46 893.508,1893.31 918.623,1909 964.779,1954.89 987.348,1958.71 985.131,1947.28 987.934,1933.85 997.203,1932.51"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123504864"
- class="fil1 str3"
- points="1551.11,1416.34 1579.48,1397.44 1598.77,1395.63 1590.01,1334.1 1560.34,1249.47 1535.44,1212.77 1516.62,1162.12 1471.15,1167.96 1396.51,1150.45 1397,1167.18 1381.94,1173.14 1377.03,1191.57 1389.74,1218.91 1408.29,1226.72 1403.72,1258.16 1394.3,1259.63 1393.99,1277.05 1406.59,1286.23 1406.94,1303.11 1401.44,1307.59 1383.24,1302.42 1364.8,1311.34 1379.62,1333.66 1378.48,1352.79 1392.79,1360.37 1402.99,1382.63 1403.3,1420.9 1417.27,1430.13 1431.56,1429.74 1440.15,1420.73 1478.14,1453.45 1484.2,1458.48 1519.34,1460.14 1556.25,1452.97 1561.84,1434.11"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123533808"
- class="fil1 str3"
- points="1465.64,1480.24 1478.14,1453.45 1440.15,1420.73 1431.56,1429.74 1417.27,1430.13 1403.3,1420.9 1402.99,1382.63 1392.79,1360.37 1378.48,1352.79 1348.52,1365.88 1280.73,1355.15 1277.61,1368.71 1294.04,1430.21 1291.28,1474.28 1305.57,1493.61 1317.92,1493.78 1336.46,1512.05 1340.51,1540.95 1397.55,1530.71 1400.94,1496.98 1442.05,1477.57 1450.78,1484.71"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123520872"
- class="fil1 str3"
- points="1294.04,1430.21 1277.61,1368.71 1280.73,1355.15 1266.81,1320.59 1256.46,1325.5 1242.83,1319.3 1200.14,1388.84 1168.84,1399.51 1076.5,1391.52 1078.92,1441.61 1075.93,1487.6 1095,1498.02 1101.28,1497.21 1107.57,1510.27 1102.29,1526.69 1084.87,1532.4 1101.52,1559.96 1131.27,1585.48 1230.71,1589.35 1258.72,1589.47 1273.3,1578.6 1289.52,1580.72 1303.8,1590.57 1309.94,1552.85 1324.9,1543.75 1340.51,1540.95 1336.46,1512.05 1317.92,1493.78 1305.57,1493.61 1291.28,1474.28"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <path
- id="_123507576"
- class="fil1 str3"
- d="m 959.934,1460.96 6.52643,11.6125 -1.01801,12.4857 -8.20819,8.7163 0.0265,14.6825 -6.32465,7.7357 5.46852,10.0852 -0.0396,12.9904 8.63312,-3.6944 30.7828,3.5576 31.42888,-91.9069 30.9951,-8.8973 20.7187,3.2786 -2.427,-50.0862 -3.5192,-30.1461 -46.7181,29.4353 -53.64175,-3.066 -3.20165,14.8349 -21.389,11.1046 -14.4268,14.7101 c 0.61645,0.6401 1.23375,1.2765 1.85162,1.9095 l 0.5717,13.1287 6.99154,0.034 4.66996,-4.3003 12.2492,21.7957 z"
- inkscape:connector-curvature="0"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123531072"
- class="fil1 str3"
- points="1058.2,1438.33 1027.21,1447.23 995.78,1539.13 1006.02,1540.57 1026.35,1524.47 1049.79,1525.04 1057.21,1535.21 1084.87,1532.4 1102.29,1526.69 1107.57,1510.27 1101.28,1497.21 1095,1498.02 1075.93,1487.6 1078.92,1441.61"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123522384"
- class="fil1 str3"
- points="1084.02,1729.21 1091.23,1748.68 1109.12,1743.81 1116.82,1747.93 1117.62,1757.04 1130.9,1753.14 1135.85,1737.13 1164.36,1723.23 1174.42,1694.04 1200.45,1681.63 1201.29,1674.21 1231.9,1681.26 1237.65,1665.79 1235.17,1624.71 1217.95,1610.3 1230.71,1589.35 1131.27,1585.48 1138.85,1609.63 1157,1630.55 1139.03,1656.24 1129.65,1655.35 1125.19,1664.37 1112,1670.37 1118.12,1679.46 1109.37,1686.42 1086.03,1669.08 1075.33,1674.57 1102.38,1725.9"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123510912"
- class="fil1 str3"
- points="1032.7,1611.22 1047.11,1600.88 1058.39,1582.72 1049.38,1564.88 1052.16,1556.41 1014.05,1547.56 999.253,1557.49 995.823,1568.69 1006.78,1577.38 1009.75,1587.79 1004.51,1600.44"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123525168"
- class="fil1 str3"
- points="1058.39,1582.72 1049.38,1564.88 1052.16,1556.41 1061.89,1556.18 1057.21,1535.21 1084.87,1532.4 1101.52,1559.96 1131.27,1585.48 1138.85,1609.63 1157,1630.55 1139.03,1656.24 1129.65,1655.35 1125.19,1664.37 1112,1670.37 1088.95,1662 1063.35,1627.69 1024.22,1657.93 1012.89,1642.69 978.389,1631.88 981.608,1632.03 982.389,1626.32 972.932,1616.68 969.772,1595.81 980.109,1590.58 1004.51,1600.44 1032.7,1611.22 1047.11,1600.88"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123515184"
- class="fil1 str3"
- points="960.695,1620.02 947.233,1618.86 944.869,1625.57 946.032,1634.14 965.659,1653.85 967.439,1659.18 977.006,1661.59 974.448,1652.55 974.344,1643.03 978.389,1631.88 975.171,1631.73"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123504984"
- class="fil1 str3"
- points="1012.89,1642.69 978.389,1631.88 974.344,1643.03 974.448,1652.55 977.006,1661.59 993.27,1669.89 1008.08,1668.63 1018.27,1649.93"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123528000"
- class="fil1 str3"
- points="1086.03,1669.08 1109.37,1686.42 1118.12,1679.46 1112,1670.37 1088.95,1662 1063.35,1627.69 1024.22,1657.93 1055.73,1715.72 1049.94,1722.8 1073.54,1748.12 1092.43,1782.74 1117.62,1757.04 1116.82,1747.93 1109.12,1743.81 1091.23,1748.68 1084.02,1729.21 1102.38,1725.9 1075.33,1674.57"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123513528"
- class="fil1 str3"
- points="1066.99,1752.89 1041.43,1732.49 1049.94,1722.8 1055.73,1715.72 1024.22,1657.93 1018.27,1649.93 1008.08,1668.63 993.27,1669.89 987.276,1673.01 993.835,1704.17 982.278,1704.51 980.537,1718.27 1011.99,1752.76 1019.43,1746.77 1009.48,1736.94 1017.42,1729.03 1036.07,1743.71 1047.58,1757.86 1063.95,1761.05"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123515952"
- class="fil1 str3"
- points="1066.99,1752.89 1063.95,1761.05 1047.58,1757.86 1036.07,1743.71 1017.42,1729.03 1009.48,1736.94 1019.43,1746.77 1011.99,1752.76 980.537,1718.27 982.278,1704.51 993.835,1704.17 987.276,1673.01 993.27,1669.89 977.006,1661.59 967.439,1659.18 969.609,1665.68 964.448,1670.35 955.431,1669.57 937.238,1704.08 999.386,1751.24 1012.77,1773.59 1017.89,1763.82 1023.1,1763.85 1032.18,1774.11 1039.32,1762.17 1074.94,1791.22 1092.43,1782.74 1073.54,1748.12 1049.94,1722.8 1041.43,1732.49"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123520728"
- class="fil1 str3"
- points="953.652,1659.04 955.431,1669.57 937.238,1704.08 909.667,1684.22 918.965,1656.94 915.554,1647.45 933.954,1647.6"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123506952"
- class="fil1 str3"
- points="937.238,1704.08 982.066,1738.09 974.984,1744.16 966.871,1766.71 982.556,1772.35 976.32,1788.03 983.67,1802.74 983.816,1812.72 976.195,1818.34 976.105,1805.26 967.051,1793.78 938.385,1781.11 912.355,1757.17 894.016,1753.24 888.621,1746.34 886.536,1743.68 886.528,1728.33 886.601,1715.24 869.231,1685 858.027,1684.09 860.633,1670.62 873.052,1669.18 877.301,1661.48 884.505,1655.08 906.039,1654.86 915.554,1647.45 918.965,1656.94 909.667,1684.22"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123523464"
- class="fil1 str3"
- points="869.231,1685 858.027,1684.09 855.481,1697.25 836.256,1710.62 826.035,1753.87 813.334,1763.68 852.231,1780.02 877.52,1782.64 899.35,1809.52 904.492,1804.96 904.513,1792.91 895.733,1782.69 891.38,1763.88 894.016,1753.24 886.536,1743.68 886.528,1728.33 886.601,1715.24"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123526584"
- class="fil1 str3"
- points="1152.9,1843.74 1137.22,1833.3 1125.43,1834.94 1110.87,1822.18 1113.15,1807.93 1105.72,1791.46 1092.43,1782.74 1074.94,1791.22 1039.32,1762.17 1032.18,1774.11 1023.1,1763.85 1017.89,1763.82 1012.77,1773.59 999.386,1751.24 982.066,1738.09 974.984,1744.16 966.871,1766.71 982.556,1772.35 976.32,1788.03 983.67,1802.74 983.816,1812.72 976.195,1818.34 981.21,1828.82 1004.95,1874.74 1018.13,1898.21 1042.12,1918.68 1078.19,1933.82 1078.24,1912.07 1068.28,1894.79 1071.66,1883.9 1085.38,1887.84 1093.62,1872.04 1121.19,1863.77 1141.27,1873.17 1152.89,1870.45"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123534576"
- class="fil1 str3"
- points="967.051,1793.78 976.105,1805.26 976.195,1818.34 955.644,1835.42 941.487,1835.27 915.39,1829.25 899.35,1809.52 904.492,1804.96 904.513,1792.91 895.733,1782.69 891.38,1763.88 894.016,1753.24 912.355,1757.17 938.385,1781.11"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123533976"
- class="fil1 str3"
- points="1152.89,1914.16 1163.78,1927.86 1129.2,1939.51 1087.05,1978.45 1086.47,1957.32 1078.17,1942.05 1078.19,1933.82 1078.24,1912.07 1068.28,1894.79 1071.66,1883.9 1085.38,1887.84 1093.62,1872.04 1121.19,1863.77 1141.27,1873.17 1152.89,1870.45"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123513216"
- class="fil1 str3"
- points="988.916,2085.88 954.771,2062.46 984.632,2049.24 1004.27,1996.82 1086.47,1957.32 1087.05,1978.45 1079.19,1985.71 1086.69,2061.72 1078.37,2066.71 1062.15,2112.61 1031.13,2112.83 1022.17,2093.91 1012.63,2085.96"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123532968"
- class="fil1 str3"
- points="1004.27,1996.82 994.841,1960.18 987.348,1958.71 985.131,1947.28 987.934,1933.85 997.203,1932.51 1001.06,1906.9 1018.13,1898.21 1042.12,1918.68 1078.19,1933.82 1078.17,1942.05 1086.47,1957.32"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123525192"
- class="fil1 str3"
- points="994.841,1960.18 987.348,1958.71 964.779,1954.89 946.622,1953.72 941.182,1975.51 927.401,1998.06 902.086,1990.61 898.208,2014.19 919.154,2017.2 941.998,2053.69 954.771,2062.46 984.632,2049.24 1004.27,1996.82"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123525912"
- class="fil1 str3"
- points="853.35,2042.04 903.105,2102.63 920.687,2100.29 927.197,2059.84 941.998,2053.69 919.154,2017.2 898.208,2014.19 895.453,2030.73 872.274,2022.81"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123516384"
- class="fil1 str3"
- points="853.35,2042.04 872.274,2022.81 895.453,2030.73 898.208,2014.19 902.086,1990.61 890.208,1969.58 859.115,1949.81 834.523,1940.28 820.94,1917.54 813.538,1928.76 790.68,1932.63 793.686,1944.63 804.533,1950.27 809.544,1971.34 824.378,1977.18 840.913,2026.89"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123519888"
- class="fil1 str3"
- points="899.506,1937.89 871.385,1937.68 859.115,1949.81 890.208,1969.58 902.086,1990.61 927.401,1998.06 941.182,1975.51 946.622,1953.72 964.779,1954.89 918.623,1909"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123536520"
- class="fil1 str3"
- points="857.778,1869.72 834.503,1875.81 824.964,1891.77 826.916,1902.36 820.94,1917.54 834.523,1940.28 859.115,1949.81 871.385,1937.68 899.506,1937.89 918.623,1909 893.508,1893.31"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123514200"
- class="fil1 str3"
- points="899.164,1883.46 893.508,1893.31 857.778,1869.72 851.884,1842.21 869.051,1845.22 869.101,1834.38 883.841,1820.72 883.987,1809.55 899.35,1809.52 915.39,1829.25 941.487,1835.27 941.464,1849.9 932.232,1856.91 920.747,1879.77"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123529440"
- class="fil1 str3"
- points="850.132,1824.32 866.155,1811.31 883.987,1809.55 899.35,1809.52 877.52,1782.64 852.231,1780.02 813.334,1763.68 812.447,1770.7 794.931,1782.31 774.609,1804.09 771.579,1811.3 816.72,1831.45 840.604,1810.62"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123532032"
- class="fil1 str3"
- points="851.884,1842.21 869.051,1845.22 869.101,1834.38 883.841,1820.72 883.987,1809.55 866.155,1811.31 850.132,1824.32 840.604,1810.62 816.72,1831.45 857.778,1869.72"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123527832"
- class="fil1 str3"
- points="795.716,1869.35 807.846,1863.11 805.145,1847.66 816.72,1831.45 857.778,1869.72 834.503,1875.81 824.964,1891.77 826.916,1902.36 820.94,1917.54 805.498,1897.4"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- </g>
-
- <g
- id="_123524592">
- <polygon
- id="_123521616"
- class="fil1 str3"
- points="682.21,2928.73 675.663,2901.05 683.482,2888.24 696.659,2884.78 701.798,2879.74 701.09,2874.31 728.985,2889.25 724.994,2902.1 736.807,2918.6 728.161,2921.9 735.082,2932.22 725.235,2983.37 706.523,2980.15 674.917,2969.69 643.351,2945.45 653.789,2928.99 669.642,2936.15"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123509544"
- class="fil1 str3"
- points="856.142,2914.42 851.628,2913.31 847.074,2924.88 839.33,2925.25 836.602,2935.47 827.385,2949.77 824.339,2943.07 810.131,2943.02 808.216,2952.16 793.893,2949.49 786.618,2943.56 797.658,2930.49 789.814,2899.94 811.017,2887.92 825.088,2864.91 835.357,2861.1 846.062,2868.43 859.462,2864.55 877.622,2884.02 877.557,2907.41 870.777,2907.92 872.565,2917.21 862.987,2924.52 856.943,2919.92"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123533376"
- class="fil1 str3"
- points="901.478,2910.74 891.37,2919.27 903.078,2944.58 891.799,2947.46 888.946,2960.18 897.939,2952.53 907.1,2958.94 893.857,2968.57 895.324,2977.5 875.258,2971.8 865.162,2976.12 855.256,2977.28 850.996,2964.14 856.021,2952.27 852.966,2942.73 836.602,2935.47 839.33,2925.25 847.074,2924.88 851.628,2913.31 856.142,2914.42 856.943,2919.92 862.987,2924.52 872.565,2917.21 870.777,2907.92 877.557,2907.41 890.922,2897.91"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123512832"
- class="fil1 str3"
- points="901.898,2793.4 916.723,2804.85 918.923,2842.42 891.308,2858.88 883.856,2889.32 890.922,2897.91 877.557,2907.41 877.622,2884.02 859.462,2864.55 846.062,2868.43 835.357,2861.1 825.088,2864.91 811.017,2887.92 789.814,2899.94 797.658,2930.49 786.618,2943.56 776.985,2934.04 744.975,2926.25 735.082,2932.22 728.161,2921.9 736.807,2918.6 724.994,2902.1 728.985,2889.25 701.09,2874.31 697.552,2847.18 719.506,2838.85 766.709,2820.94 766.392,2846.94 731.276,2886.66 729.083,2891.62 731.563,2894.66 729.417,2902.46 736.22,2905.04 735.175,2907.55 739.188,2909.15 743.214,2904.27 746.275,2906.89 771.03,2876.28 819.947,2848.12 805.823,2838.11 780.133,2798.12 808.832,2775.62 833.758,2785.32 839.203,2773 851.034,2784.83 868.71,2776.92 893.515,2786.84 890.301,2798.88"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123536496"
- class="fil1 str3"
- points="739.188,2909.15 735.175,2907.55 736.22,2905.04 729.417,2902.46 731.563,2894.66 729.083,2891.62 731.276,2886.66 766.392,2846.94 766.709,2820.94 775.576,2810.39 772.241,2806.46 771.866,2799.95 775.339,2794.5 780.133,2798.12 805.823,2838.11 819.947,2848.12 771.03,2876.28 746.275,2906.89 743.214,2904.27"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123510456"
- class="fil1 str3"
- points="696.659,2884.78 683.482,2888.24 675.663,2901.05 682.21,2928.73 669.642,2936.15 653.789,2928.99 657.19,2892.39 647.285,2882.87 645.998,2873.75 676.072,2862.29"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123517104"
- class="fil1 str3"
- points="657.19,2892.39 653.789,2928.99 643.351,2945.45 639.263,2942.32 629.615,2947.14 629.769,2941.37 612.904,2904.19 636.512,2900.79 647.285,2882.87"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123517536"
- class="fil1 str3"
- points="647.285,2882.87 636.512,2900.79 612.904,2904.19 608.333,2894.11 616.528,2875.01 604.271,2867.68 604.484,2859.38 614.825,2853.04 629.168,2863.92 631.458,2873.97 645.998,2873.75"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123525480"
- class="fil1 str3"
- points="619.967,2951.96 594.283,2939.19 593.733,2926.89 600.574,2920.76 592.29,2911.08 593.691,2897.09 608.333,2894.11 629.769,2941.37 629.615,2947.14"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123514656"
- class="fil1 str3"
- points="782.852,3008.01 780.117,2997.59 768.943,2992.27 758.077,3000.59 752.417,2988.06 725.235,2983.37 735.082,2932.22 744.975,2926.25 776.985,2934.04 786.618,2943.56 793.893,2949.49 808.216,2952.16 810.131,2943.02 824.339,2943.07 827.385,2949.77 814.396,2968.88 817.6,2977.44 809.7,2988.07 810.923,3002.5"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123523560"
- class="fil1 str3"
- points="852.966,2942.73 856.021,2952.27 850.996,2964.14 855.256,2977.28 835.253,2980.06 817.6,2977.44 814.396,2968.88 827.385,2949.77 836.602,2935.47"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- </g>
-
- <g
- id="_123517872">
- <polygon
- id="_123529392"
- class="fil1 str3"
- points="33.5849,3035.75 41.1199,3074.77 34.4915,3074.87 29.1595,3073.65 26.3728,3083.28 18.8654,3083.7 13.3646,3071.39 16.3306,3058.37 11.012,3052.68 14.3162,3043.96"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123517752"
- class="fil1 str3"
- points="59.1953,3027.51 67.5138,3032.8 65.2332,3047.71 63.4896,3065.75 69.7114,3073.8 50.8534,3085.95 41.1199,3074.77 33.5849,3035.75 42.3408,3038.52 51.701,3037.09"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123530808"
- class="fil1 str3"
- points="79.2103,3067.68 88.7378,3077.46 98.813,3085.09 90.3449,3105.11 84.8333,3089.34 70.9434,3090.87 72.4157,3111.57 67.6728,3105.54 58.1744,3104.57 52.4884,3098.18 50.8534,3085.95 69.7114,3073.8"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123528240"
- class="fil1 str3"
- points="70.9434,3090.87 84.8333,3089.34 90.3449,3105.11 86.3825,3119.37 74.1171,3122.07 72.4157,3111.57"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123523920"
- class="fil1 str3"
- points="100.189,3128.84 86.3825,3119.37 90.3449,3105.11 92.4564,3108.56 100.794,3108.78 105.859,3105.46 122.12,3114.24 122.2,3120.94 118.794,3128.57 124.795,3134.78 123.752,3142.38 113.857,3149.22 111.359,3138.67 104.948,3139.89"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123510792"
- class="fil1 str3"
- points="127.334,3043.78 137.343,3055.96 129.954,3077.59 112.327,3080.44 101.229,3068.17 96.2591,3067.67 98.9053,3058.86 119.393,3050.51 126.972,3040.91"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123526512"
- class="fil1 str3"
- points="88.7378,3077.46 79.2103,3067.68 69.7114,3073.8 63.4896,3065.75 65.2332,3047.71 71.3886,3049.28 76.6471,3043.26 74.7148,3038.85 74.6712,3032.67 71.3641,3027.63 73.55,3027.63 95.3594,3015.08 96.5307,3016.21 89.9829,3036.5 98.9053,3058.86 96.2591,3067.67 94.4933,3067.5"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123509880"
- class="fil1 str3"
- points="70.0742,3024.81 55.7411,3022.76 68.3286,3006.26 80.6746,3000.85 95.3594,3015.08 73.55,3027.63 71.3641,3027.63"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123525672"
- class="fil1 str3"
- points="123.462,3114.73 121.721,3099.37 131.459,3087.72 135.232,3088.35 136.811,3096.63 131.054,3107.45 134.293,3114.81"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <g
- id="g435">
- <polygon
- id="_123522000"
- class="fil1 str3"
- points="163.395,3039.15 140.815,3037.53 141.249,3030.58 147.084,3026.04 163.374,3034.02"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123515568"
- class="fil1 str3"
- points="162.305,3068.36 154.259,3079.63 149.071,3079.54 149.935,3064.62 143.853,3058.38 150.798,3051.43 156.633,3046.89 160.407,3053.17 157.211,3060.58"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- </g>
- <g
- id="g439">
- <polygon
- id="_123529344"
- class="fil1 str3"
- points="151.655,3146.96 136.484,3146.44 133.441,3141.5 147.326,3130.05 154.897,3124.21 173.863,3126.57 178.914,3132.68 172.288,3140.89"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123509568"
- class="fil1 str3"
- points="166.183,3106.84 171.969,3107.92 178.799,3114.4 179,3119.16 166.867,3117.77 161.654,3111.96"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- </g>
- <polygon
- id="_123517392"
- class="fil1 str3"
- points="200.289,3115.16 188.56,3114.41 185.836,3102.31 180.314,3096.17 186.149,3087.72 195.875,3093.63 202.016,3107.03 200.703,3110.04"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123531240"
- class="fil1 str3"
- points="240.529,3169.96 238.749,3175.41 232.835,3175.24 227.614,3183.44 214.613,3173.8 217.212,3166.26 230.856,3159.83 234.906,3162.65 242.604,3166.52"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <g
- id="g445">
- <polygon
- id="_123506592"
- class="fil1 str3"
- points="240.646,3045.78 232.834,3047.96 227.625,3042.31 230.856,3032.13 240.582,3036.29"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123532080"
- class="fil1 str3"
- points="207.225,3045.35 207.225,3044.92 210.022,3036.03 215.841,3031.95 221.114,3037.1 217.208,3047.09 209.838,3048.7"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123513576"
- class="fil1 str3"
- points="211.131,3074.02 210.263,3069.67 210.022,3060.79 218.88,3056.71 224.153,3064.03 225.889,3068.37 215.915,3077.37"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123505728"
- class="fil1 str3"
- points="195.939,3087.92 192.901,3075.76 196.132,3070.35 202.386,3071.48 204.62,3077.06 204.609,3081.37 205.932,3087.8"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- </g>
- <g
- id="g451">
- <polygon
- id="_123522984"
- class="fil1 str3"
- points="272.766,3011.9 264.519,3010.17 262.843,2978.21 269.052,2977.83 279.711,2993.66"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123535848"
- class="fil1 str3"
- points="247.784,2994.34 255.34,3006.32 252.8,3017.99 244.987,3022.33 238.476,3007.56 239.838,2999.49"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123528912"
- class="fil1 str3"
- points="264.712,3016.49 271.4,3024.56 268.86,3039.27 263.651,3044.05 257.14,3040.14 254.162,3025.55"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- </g>
- <polygon
- id="_123529608"
- class="fil1 str3"
- points="126.972,3040.91 119.393,3050.51 98.9053,3058.86 89.9829,3036.5 96.5307,3016.21 111.167,3018.9 117.585,3029.69 126.015,3033.32"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- </g>
- <g
- id="_123519216">
- <polygon
- id="_123532104"
- class="fil1 str3"
- points="658.233,2087.36 682.31,2087.69 699.942,2096.18 714.245,2114.3 714.561,2139.08 704.215,2144.14 696.728,2135.21 682.861,2144.09 672.967,2134.35 663.731,2143.82 647.327,2132.41 649.109,2114.14"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123512568"
- class="fil1 str3"
- points="563.071,2165.56 555.031,2165.28 555.396,2140.77 586.682,2125.52 619.645,2119.72 637.041,2124.73 649.109,2114.14 647.327,2132.41 663.731,2143.82 672.967,2134.35 682.861,2144.09 663.037,2168.83 678.745,2188.31 679.841,2217.2 662.047,2226.57 621.288,2228.43 599.272,2209.66 580.212,2220.72 561.818,2207.59 543.924,2209.28 553.069,2193.43 569.468,2193.63 564.053,2169.86"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123517968"
- class="fil1 str3"
- points="679.841,2217.2 678.745,2188.31 663.037,2168.83 682.861,2144.09 696.728,2135.21 704.215,2144.14 714.561,2139.08 714.195,2113.64 741.564,2149.62 737.314,2173.94 717.836,2180.51 715.228,2190.71 707.745,2219.97 688.668,2243.43"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123531720"
- class="fil1 str3"
- points="619.767,2278.77 588.469,2268.18 590.276,2248.25 580.212,2220.72 599.272,2209.66 621.288,2228.43 662.047,2226.57 679.841,2217.2 688.668,2243.43 676.626,2248.09 685.092,2258.59 661.861,2273.17 647.411,2301.46 629.944,2293.6 611.653,2296.53"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123529008"
- class="fil1 str3"
- points="791.702,2189.18 778.643,2194.57 724.425,2210.56 715.228,2190.71 717.836,2180.51 737.314,2173.94 741.564,2149.62 766.274,2157.05"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123513792"
- class="fil1 str3"
- points="756.723,2325.43 769.624,2291.36 755.993,2284.06 759.594,2259.24 761.068,2250.48 773.118,2245.73 800.65,2246.07 802.543,2261.43 815.776,2279.18 806.687,2286.3 824.237,2332.36 829.202,2347.65 815.941,2341.77 792.966,2323.57 788.842,2336.68 768.337,2339.41"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123522120"
- class="fil1 str3"
- points="685.092,2258.59 704.766,2281.54 725.711,2307.76 731.195,2314.63 747.831,2322.83 756.723,2325.43 769.624,2291.36 755.993,2284.06 759.594,2259.24 761.068,2250.48 773.118,2245.73 800.65,2246.07 797.81,2223.04 808.231,2208.56 778.643,2194.57 724.425,2210.56 715.228,2190.71 707.745,2219.97 688.668,2243.43 676.626,2248.09"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123517944"
- class="fil1 str3"
- points="685.092,2258.59 704.766,2281.54 725.711,2307.76 715.227,2315.33 701.505,2317.41 687.362,2345.36 669.595,2341.4 646.764,2317.17 647.411,2301.46 661.861,2273.17"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123504024"
- class="fil1 str3"
- points="505.575,2286.54 566.323,2268.55 581.177,2281.04 562.813,2298.48 561.618,2306.5 586.675,2329.74 587.11,2347.83 550.406,2355.19 533.002,2336.02 484.101,2317.52 480.922,2311.67 491.621,2301.21"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123506304"
- class="fil1 str3"
- points="518.675,2253.04 521.205,2270.12 505.575,2286.54 566.323,2268.55 581.177,2281.04 562.813,2298.48 561.618,2306.5 586.675,2329.74 587.11,2347.83 596.481,2377.61 604.225,2374.11 621.78,2420.77 612.569,2426.24 631.338,2442.18 645.754,2416.75 650.412,2407.34 642.291,2373.14 648.671,2366.44 632.281,2332.12 636.13,2321.07 646.764,2317.17 647.411,2301.46 629.944,2293.6 611.653,2296.53 619.767,2278.77 588.469,2268.18 590.276,2248.25 580.212,2220.72 561.818,2207.59 543.924,2209.28"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123514128"
- class="fil1 str3"
- points="540.701,2399.04 536.786,2385.21 539.248,2369.81 550.406,2355.19 587.11,2347.83 596.481,2377.61 604.225,2374.11 621.78,2420.77 612.569,2426.24 631.338,2442.18 599.722,2459.44 570.925,2459.2 559.474,2459.25 541.062,2450.11 550.752,2434.56"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123515304"
- class="fil1 str3"
- points="480.922,2311.67 491.621,2301.21 454.775,2288.95 431.183,2264.34 424.509,2272.14 421.21,2308.62 428.463,2316.31 409.544,2336.83 428.602,2336.75 428.678,2350.24 449.003,2354.27 454.576,2341.47 472.572,2345.65 463.389,2368.06 475.99,2370.47 484.616,2362.48 509.875,2377.57 509.892,2386.71 540.701,2399.04 536.786,2385.21 539.248,2369.81 550.406,2355.19 533.002,2336.02 484.101,2317.52"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123527088"
- class="fil1 str3"
- points="428.602,2336.75 428.678,2350.24 449.003,2354.27 454.576,2341.47 472.706,2345.32 463.389,2368.06 453.552,2391.01 434.457,2421.37 386.163,2395.7 404.054,2342.78 409.544,2336.83"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123535800"
- class="fil1 str3"
- points="434.457,2421.37 435.392,2444.48 428.834,2449.52 425.652,2464.91 417.712,2464.96 410.475,2454.41 403.809,2451.54 403.237,2423.14 392.2,2419.5 384.527,2400.54 386.163,2395.7"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123524856"
- class="fil1 str3"
- points="478.835,2501.31 435.392,2444.48 434.457,2421.37 453.552,2391.01 463.389,2368.06 475.99,2370.47 484.616,2362.48 509.875,2377.57 509.892,2386.71 540.701,2399.04 550.752,2434.56 541.062,2450.11 527.667,2477.44 512.035,2477.97 491.272,2509.84 479.433,2509.9"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123532368"
- class="fil1 str3"
- points="402.523,2474.65 417.712,2464.96 425.652,2464.91 428.834,2449.52 435.392,2444.48 478.835,2501.31 479.433,2509.9 440.787,2542.76 407.269,2536.82 393.829,2524.51 397.085,2495.68 405.334,2489.15"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123532632"
- class="fil1 str3"
- points="645.754,2416.75 650.412,2407.34 642.291,2373.14 648.671,2366.44 632.281,2332.12 636.13,2321.07 646.764,2317.17 669.595,2341.4 687.362,2345.36 701.505,2317.41 715.227,2315.33 713.307,2353.46 708.432,2356.26 724.382,2399.46 698.495,2420.78 677.504,2417.78 673.61,2427.63"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123513984"
- class="fil1 str3"
- points="725.711,2307.76 731.195,2314.63 747.831,2322.83 751.728,2339.56 746.476,2350.29 754.242,2373.16 749.337,2373.27 724.382,2399.46 708.432,2356.26 713.307,2353.46 715.227,2315.33"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123515472"
- class="fil1 str3"
- points="770.715,2412.47 750.321,2435.93 738.921,2431.19 735.962,2406.83 724.382,2399.46 749.337,2373.27 754.242,2373.16 746.476,2350.29 751.728,2339.56 747.831,2322.83 756.723,2325.43 768.337,2339.41 788.842,2336.68 792.966,2323.57 815.941,2341.77 829.202,2347.65 823.655,2355.54 831.235,2365.9 825.52,2404.73 803.266,2405.07 797.152,2416.3"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- </g>
- <g
- id="_123510552">
- <polygon
- id="_123526656"
- class="fil1 str3"
- points="368.184,2588.27 368.696,2583.58 362.645,2578.87 358.927,2555.16 349.954,2549.66 347.887,2541.99 363.097,2528.12 393.829,2524.51 407.269,2536.82 404.405,2569.89 396.31,2569.52 389.882,2586.04 401.744,2613.79 371.06,2615.14 371.061,2612.51 357.59,2595.07 360.297,2589.1"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123508824"
- class="fil1 str3"
- points="407.269,2536.82 440.787,2542.76 444.255,2559.86 465.297,2565.05 444.003,2600.73 451.982,2605.6 442.583,2620.29 435.07,2612.17 401.744,2613.79 389.882,2586.04 396.31,2569.52 404.405,2569.89"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123519672"
- class="fil1 str3"
- points="540.101,2610.95 540.705,2620.89 537.311,2638.46 523.038,2639.63 498.95,2624.04 479.489,2611.45 469.188,2619.19 463.398,2611.34 451.982,2605.6 444.003,2600.73 465.297,2565.05 482.941,2564.95 497.483,2553.25 498.893,2542.26 511.497,2537.62 527.031,2540.67 540.911,2547.49 540.927,2561.29 525.036,2566.94 523.068,2575.95 529.296,2582.42 527.441,2606.45"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123536664"
- class="fil1 str3"
- points="556.397,2572.87 562.553,2594.72 553.841,2625.16 540.705,2620.89 540.101,2610.95 527.441,2606.45 529.296,2582.42 523.068,2575.95 525.036,2566.94 540.927,2561.29"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123534312"
- class="fil1 str3"
- points="413.219,2628.97 406.119,2622.66 401.744,2613.79 435.07,2612.17 442.583,2620.29 451.982,2605.6 463.398,2611.34 469.188,2619.19 479.489,2611.45 498.95,2624.04 490.608,2633.11 483.734,2630.52 460.95,2653.3 440.578,2653.3"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123515088"
- class="fil1 str3"
- points="490.608,2633.11 498.95,2624.04 523.038,2639.63 537.311,2638.46 536.228,2644.07 547.471,2654.9 533.606,2666.6 525.852,2690.51 500.054,2701.59 477.713,2672.47 490.399,2661.06 496.299,2646.92"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <g
- id="g484">
- <polygon
- id="_123510816"
- class="fil1 str3"
- points="361.873,2683.69 373.855,2687.23 373.514,2682.72 366.895,2677.37 359.79,2662.94 362.789,2657.25 368.402,2657.65 377.325,2667.83 384.023,2668.06 371.05,2638.93 371.06,2615.14 401.744,2613.79 406.119,2622.66 413.219,2628.97 440.578,2653.3 460.95,2653.3 483.734,2630.52 490.608,2633.11 496.299,2646.92 490.399,2661.06 477.713,2672.47 454.567,2670.93 430.709,2681.78 421.085,2703.37 410.446,2705.58 403.76,2725.7 391.354,2725.8 384.082,2714.43 370.516,2713.57 364.653,2707.23 370.088,2706.24 366.452,2697.82 355.147,2691.36 354.27,2683.4"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123529512"
- class="fil1 str3"
- points="344.384,2648.78 349.552,2643.54 351.287,2631.43 356.207,2632.83 366.087,2650.95 361.378,2656.18 351.329,2656.16"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- </g>
- <polygon
- id="_123535248"
- class="fil1 str3"
- points="430.709,2681.78 454.567,2670.93 477.713,2672.47 500.054,2701.59 479.768,2717.17 463.392,2720.77 453.239,2721.06 443.802,2717.86 415.341,2725.89 403.76,2725.7 410.446,2705.58 421.085,2703.37"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123508680"
- class="fil1 str3"
- points="500.054,2701.59 525.852,2690.51 524.204,2695.59 543.685,2709.22 541.029,2722.35 516.578,2725.93"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123508968"
- class="fil1 str3"
- points="456.605,2760.8 470.037,2762.72 479.498,2751.82 463.392,2720.77 479.768,2717.17 500.054,2701.59 516.578,2725.93 507.308,2732.96 508.209,2746.41 518.322,2771.13 500.918,2799.71 497.496,2795.76 472.037,2787.19 459.75,2775.04 453.14,2768.51"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123518136"
- class="fil1 str3"
- points="463.392,2720.77 479.498,2751.82 470.037,2762.72 456.605,2760.8 453.14,2768.51 439.976,2767.55 425.535,2753.11 439.388,2745.12 439.334,2731.61 453.239,2721.06"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123514272"
- class="fil1 str3"
- points="415.341,2725.89 443.802,2717.86 453.239,2721.06 439.334,2731.61 439.388,2745.12 425.535,2753.11 417.074,2752.47 410.923,2758.08 400.372,2740.67 391.354,2725.8 403.76,2725.7"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123529584"
- class="fil1 str3"
- points="350.93,2709.05 352.877,2706.01 357.594,2704.47 364.653,2707.23 370.516,2713.57 384.082,2714.43 391.354,2725.8 400.372,2740.67 397.616,2756.64 381.401,2758.11 358.364,2748.14 361.247,2733.23"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123526608"
- class="fil1 str3"
- points="345.896,2764.2 353.463,2769.24 357.298,2764.37 356.504,2757.75 358.364,2748.14 381.401,2758.11 397.616,2756.64 400.372,2740.67 410.923,2758.08 414.018,2788.5 422.472,2792.25 410.526,2801.86 407.243,2798.03 371.293,2801.39 368.093,2789.37 344.23,2773.71"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <g
- id="g495">
- <polygon
- id="_123510144"
- class="fil1 str3"
- points="342.792,2835.93 354.009,2835.06 367.103,2825.2 368.196,2851.22 389.267,2836 400.797,2846.4 432.916,2833.01 430.636,2816.03 418.79,2816.1 410.526,2801.86 407.243,2798.03 371.293,2801.39 368.093,2789.37 344.23,2773.71 338.516,2806.33 331.62,2820.18"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123509280"
- class="fil1 str3"
- points="325.97,2778.11 330.018,2773.03 335.896,2776.72 337.44,2783.86 333.533,2789.08 327.891,2789.51"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- </g>
- <polygon
- id="_123516648"
- class="fil1 str3"
- points="418.79,2816.1 410.526,2801.86 422.472,2792.25 414.018,2788.5 410.923,2758.08 417.074,2752.47 425.535,2753.11 439.976,2767.55 453.14,2768.51 459.75,2775.04 452.491,2790.33 459.031,2798.4 458.052,2818.88 456.273,2856.14 464.873,2873.43 459.805,2872.48 443.893,2886.79 438.309,2878.57 411.303,2875.96 400.797,2846.4 432.916,2833.01 430.636,2816.03"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123532560"
- class="fil1 str3"
- points="500.918,2799.71 509.706,2824.09 511.538,2846.49 458.128,2817.31 459.031,2798.4 452.491,2790.33 459.75,2775.04 472.037,2787.19 497.496,2795.76"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123523848"
- class="fil1 str3"
- points="523.876,2855.3 511.538,2846.49 509.706,2824.09 500.918,2799.71 518.322,2771.13 521.353,2778.54 547.8,2787.77 556.244,2777.91 571.268,2793.24 564.473,2817.08 576.782,2838.73 566.618,2840.33 550.978,2835.08 548.953,2862.17"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123511032"
- class="fil1 str3"
- points="505.417,2869 478.834,2876.05 464.873,2873.43 456.273,2856.14 458.128,2817.31 511.538,2846.49 523.876,2855.3 500.239,2862.47"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123516624"
- class="fil1 str3"
- points="479.433,2509.9 491.272,2509.84 502.787,2492.17 513.164,2500.34 511.497,2537.62 498.893,2542.26 497.483,2553.25 482.941,2564.95 465.297,2565.05 444.255,2559.86 440.787,2542.76"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123524928"
- class="fil1 str3"
- points="513.164,2500.34 502.787,2492.17 512.035,2477.97 527.667,2477.44 541.062,2450.11 559.474,2459.25 570.925,2459.2 570.936,2489.64 555.341,2497.17 554.459,2523.43 536.267,2525.2 527.031,2540.67 511.497,2537.62"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- </g>
- <g
- id="g3502"><g
- id="g398">
- <polygon
- id="_123534648"
- class="fil1 str3"
- points="740.129,3147.08 746.165,3142.23 758.438,3165.34 747.17,3171.57 716.781,3172.24 682.735,3186.74 679.56,3174.67 696.474,3167.28 689.669,3145.17 705.885,3139.88 721.496,3134.58"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123523368"
- class="fil1 str3"
- points="698.859,3199.44 690.487,3195.16 695.955,3185.29 702.946,3181.16 709.416,3181.17 712.578,3182.96 718.244,3182.88"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- </g><polygon
- id="_123534504"
- class="fil1 str3"
- points="884.915,3002.74 899.642,2983.76 895.324,2977.5 893.857,2968.57 907.1,2958.94 897.939,2952.53 888.946,2960.18 891.64,2947.39 903.078,2944.58 897.85,2933.28 901.271,2931.98 912.046,2929.51 932.585,2954.49 948.506,2937.81 953.263,2942.05 960.302,2967.6 940.789,2980.38 953.702,3005.8 948.982,3020.96 944.296,3021.34 939.611,3021.72 937.467,3012.8 912.643,3018.12 909.511,3034.7 896.616,3017.94"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" /><polygon
- id="_123507432"
- class="fil1 str3"
- points="881.153,3045.86 882.919,3021.73 896.616,3017.94 909.511,3034.7 902.779,3041.84"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" /><polygon
- id="_123526176"
- class="fil1 str3"
- points="879.859,3079.01 870.455,3079.01 854.518,3060.99 870.802,3027.7 861.091,3005.43 877.978,3004.55 884.915,3002.74 896.616,3017.94 882.919,3021.73 881.153,3045.86 902.779,3041.84 904.137,3048.14 902.393,3048.07 898.93,3049.38 886.262,3054.78 887.038,3072.34 879.921,3068.99"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" /><polygon
- id="_123517008"
- class="fil1 str3"
- points="904.137,3048.14 907.376,3064.45 899.895,3076.46 887.038,3072.34 886.262,3054.78 902.393,3048.07"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" /><polygon
- id="_123522240"
- class="fil1 str3"
- points="858.708,3100.04 848.491,3106.32 841.873,3101.98 837.603,3074.7 854.518,3060.99 870.455,3079.01 879.859,3079.01 879.921,3068.99 887.038,3072.34 899.895,3076.46 894.369,3085.33 908.247,3098.19 898.719,3104.53 900.62,3109.05 897.135,3114.01 883.071,3101.57"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" /><polygon
- id="_123533688"
- class="fil1 str3"
- points="877.758,3148.68 875.629,3136.95 870.838,3144.55 856.642,3144.36 846.544,3137.47 848.491,3106.32 858.708,3100.04 883.071,3101.57 897.214,3113.9 900.62,3109.05 898.719,3104.53 908.247,3098.19 915.611,3095.34 912.308,3103.34 913.525,3111.1 907.83,3112.67 905.564,3119.68 897.779,3130.24 886.92,3126.88 888.623,3139.49"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" /><polygon
- id="_123511968"
- class="fil1 str3"
- points="849.435,3019.93 855.754,3005.71 861.091,3005.43 870.802,3027.7 854.518,3060.99 837.603,3074.7 817.593,3068.81 805.34,3033.51 820.562,3019.72 832.665,3023.47 836.018,3002.14"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" /><polygon
- id="_123508776"
- class="fil1 str3"
- points="820.562,3019.72 810.923,3002.5 809.7,2988.07 817.6,2977.44 835.253,2980.06 854.536,2977.82 865.162,2976.12 875.258,2971.8 895.324,2977.5 899.642,2983.76 884.915,3002.74 877.978,3004.55 861.091,3005.43 855.754,3005.71 849.435,3019.93 836.018,3002.14 832.665,3023.47"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" /><polygon
- id="_123521688"
- class="fil1 str3"
- points="769.732,3108.66 763.162,3123.91 775.391,3145.56 769.358,3159.3 758.438,3165.34 746.165,3142.23 740.129,3147.08 721.496,3134.58 733.07,3109.35 749.847,3107.82 764.694,3095.01"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" /><polygon
- id="_123516120"
- class="fil1 str3"
- points="775.391,3145.56 763.162,3123.91 769.732,3108.66 784.878,3091.29 796.998,3091.32 799.204,3124.95 812.242,3146.82 812.282,3156.77 782.761,3193.85 773.2,3193.11 786.207,3176.04 780.156,3172.55 773.188,3178.62 768.431,3178.57 769.358,3159.3"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" /><g
- id="g412">
- <polygon
- id="_123517416"
- class="fil1 str3"
- points="623.04,3214.18 632.594,3211.71 629.263,3219.37 624.842,3220.55 619.862,3223.33 614.304,3221.84 610.188,3219.05 615.656,3212.66"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123532920"
- class="fil1 str3"
- points="565.296,3180.45 564.876,3196.36 560.113,3201 542.296,3197.89 532.525,3184.98 534.937,3173.17 546.22,3172.67 555.331,3177.38 559.508,3141.76 584.629,3141.3 603.544,3121.5 613.217,3129.19 641.986,3114.91 658.085,3122.45 660.241,3126.33 689.379,3118.68 698.98,3116.63 705.885,3139.88 689.669,3145.17 696.474,3167.28 679.56,3174.67 682.64,3186.87 679.897,3188.04 661.696,3189.71 664.258,3199.07 657.776,3204.03 645.171,3201.29 629.122,3204.72 621.295,3199.14 609.151,3197.57 600.829,3206.79 573.539,3199.61 575.723,3183.32 570.936,3175.91"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- </g><polygon
- id="_123523296"
- class="fil1 str3"
- points="660.241,3126.33 658.085,3122.45 656.979,3088.1 671.961,3082.95 680.911,3089.48 688.637,3084.75 698.423,3091.03 689.379,3118.68"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" /><polygon
- id="_123536448"
- class="fil1 str3"
- points="573.539,3199.61 600.829,3206.79 599.173,3208.63 599.17,3215.85 586.153,3226.97 560.976,3226.77 540.143,3235.42 533.188,3226.63 539.698,3219.29 567.487,3209.5 573.125,3202.7"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" /><polygon
- id="_123518016"
- class="fil1 str3"
- points="810.124,3085.66 817.593,3068.81 837.603,3074.7 841.873,3101.98 848.491,3106.32 846.544,3137.47 819.64,3146.92 814.402,3141.68 812.242,3146.82 799.204,3124.95 796.998,3091.32 800.464,3082.68"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" /><polygon
- id="_123512016"
- class="fil1 str3"
- points="824.938,3124.81 821.936,3114.13 831.717,3104.2 840.541,3112.3 836.791,3124.94"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" /><polygon
- id="_123524088"
- class="fil1 str3"
- points="768.943,2992.27 780.117,2997.59 782.852,3008.01 789.333,3006.74 791.961,3026.01 763.621,3035.14 757.993,3028.74 746.382,3027.62 725.235,2983.37 752.417,2988.06 758.077,3000.59"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" /><polygon
- id="_123531648"
- class="fil1 str3"
- points="764.406,3095.3 764.804,3083.62 756.144,3083.62 738.43,3052.22 746.382,3027.62 757.993,3028.74 763.621,3035.14 791.961,3026.01 789.333,3006.74 810.923,3002.5 820.562,3019.72 805.34,3033.51 817.593,3068.81 810.124,3085.66 800.464,3082.68 796.998,3091.32 784.878,3091.29 769.732,3108.66"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" /><polygon
- id="_123522096"
- class="fil1 str3"
- points="674.926,3063.09 671.961,3082.95 680.911,3089.48 688.637,3084.75 698.423,3091.03 689.379,3118.68 698.98,3116.63 705.885,3139.88 721.496,3134.58 733.07,3109.35 749.847,3107.82 764.694,3095.01 764.804,3083.62 756.144,3083.62 738.43,3052.22 733.378,3067.85 709.461,3075.66 684.832,3062.04"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" /><polygon
- id="_123516336"
- class="fil1 str3"
- points="706.523,2980.15 725.235,2983.37 746.382,3027.62 733.378,3067.85 709.461,3075.66 684.832,3062.04 681.624,3042.72 671.403,3038.58 672.733,3024.74 696.041,3021.54 707.161,2996.65 701.625,2987.16"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" /><polygon
- id="_123535080"
- class="fil1 str3"
- points="912.643,3018.12 937.467,3012.8 939.611,3021.72 946.113,3044.96 954.725,3053.64 934.185,3063.66 909.511,3034.7"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" /><g
- id="g506">
- <polygon
- id="_123531816"
- class="fil1 str3"
- points="902.779,3041.84 909.511,3034.7 934.185,3063.66 934.155,3082.53 954.687,3102.9 951.609,3106.69 927.23,3107.33 913.525,3111.1 912.308,3103.34 915.611,3095.34 908.247,3098.19 894.369,3085.33 907.376,3064.45"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123513144"
- class="fil1 str3"
- points="940.911,3113.82 938.458,3118.35 935.188,3121.94 924.874,3122.62 923.249,3119.87 922.573,3118.73 920.359,3116.23 925.18,3112.1 932.084,3112.1 935.15,3113.47"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- </g><g
- id="g510">
- <polygon
- id="_123509616"
- class="fil1 str3"
- points="990.8,3114.45 978.112,3098.68 974.135,3083.96 958.129,3085.77 957.765,3099.11 954.687,3102.9 934.155,3082.53 934.185,3063.66 954.725,3053.64 946.113,3044.96 973.294,3035.35 986.764,3039.1 996.127,3022.44 1003.05,3016.89 1000.81,3040.62 1019.02,3060.57 1021.59,3101.45 1015.33,3088.55 1011.12,3091.97 1015.81,3106.98 1011.54,3112.5 1003.29,3107.36 995.826,3115.4"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123535224"
- class="fil1 str3"
- points="950.352,3129.15 950.309,3119.71 956.431,3114.27 958.424,3131.82 952.116,3132.8"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123512208"
- class="fil1 str3"
- points="976.76,3122.09 976.655,3125.74 971.522,3131.08 966.873,3127.16 965.935,3096.25 970.755,3094.72 972.868,3106.03 978.467,3112.69 978.256,3120.46"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123525456"
- class="fil1 str3"
- points="1014.49,3131.51 1001.6,3129.76 1001.14,3125.24 1002.39,3118.84 1008.15,3117.26 1011.56,3114.27 1018.4,3119.64 1020.93,3124.87"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- </g><polygon
- id="_123510648"
- class="fil1 str3"
- points="1003.05,3016.89 996.127,3022.44 986.764,3039.1 973.294,3035.35 946.113,3044.96 939.611,3021.72 948.982,3020.96 953.702,3005.8 984.173,2994.61 997.376,3004.42 1003.51,3014.31"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" /><polygon
- id="_123536400"
- class="fil1 str3"
- points="997.134,2966.83 995.162,2980.61 984.173,2994.61 953.702,3005.8 940.91,2980.41 940.789,2980.38 960.302,2967.6 961.777,2966.76 968.842,2975.59"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" /><polygon
- id="_123520104"
- class="fil1 str3"
- points="1019.16,2958.78 1019.93,2972.61 1019.38,2988.4 1027.21,2989.3 1027.38,2997.33 1022.13,3008.78 1003.51,3014.31 997.376,3004.42 984.173,2994.61 995.162,2980.61 997.134,2966.83 1005.74,2968.25"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" /><g
- id="g519">
- <polygon
- id="_123530016"
- class="fil1 str3"
- points="1021.6,3101.47 1023.72,3105.84 1028.85,3103.79 1027.92,3091.22 1032.77,3088.93 1040.51,3093.28 1046.13,3090.82 1036.74,3074.18 1034.09,3063.59 1024.52,3050.67 1025.88,3042.53 1052.42,3068.69 1057.59,3080.2 1063.67,3079.72 1059.82,3066.67 1073.44,3067.02 1082.31,3078.1 1083.02,3067.23 1090.52,3067.5 1104.46,3054.96 1100.75,3043.55 1108.85,3028.24 1118.41,3009.43 1116.35,3006.32 1106.42,3004.64 1101.11,2986.67 1087.65,2984.09 1090.16,3032.79 1072.87,3037.18 1068.53,3020.71 1064.52,3005.48 1059.56,3004.96 1056.01,3009.5 1049.77,3009.87 1042.89,2990.54 1027.21,2989.3 1027.38,2997.33 1022.13,3008.78 1003.51,3014.31 1003.05,3016.89 1000.81,3040.62 1019.02,3060.57"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123530256"
- class="fil1 str3"
- points="1038.46,3103.96 1051.49,3097.33 1053.99,3108.34 1044.88,3110.23"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123504408"
- class="fil1 str3"
- points="1070.49,3094.88 1064.41,3098.07 1057.81,3094.22 1056.69,3091.36 1058.77,3084.39 1065.81,3084.3"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123510696"
- class="fil1 str3"
- points="1113.02,3078.37 1112.59,3085.47 1097.3,3082.93 1093.15,3076.16 1097.4,3070.49"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- </g><polygon
- id="_123520128"
- class="fil1 str3"
- points="1027.21,2989.3 1019.38,2988.4 1019.93,2972.61 1039.93,2968.24 1052.68,2979.68 1065.96,2972.56 1067.62,2958.58 1075.34,2962.21 1083.5,2966.13 1087.65,2984.09 1090.16,3032.79 1072.87,3037.18 1068.53,3020.71 1064.52,3005.48 1059.56,3004.96 1056.01,3009.5 1049.77,3009.87 1042.89,2990.54"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" /></g>
- <g
- id="_123534360">
- <polygon
- id="_123516696"
- class="fil1 str3"
- points="1087.23,2878.88 1088.75,2879.43 1092.02,2872.76 1109.54,2876.35 1116.53,2909.85 1105.6,2914.68 1108.26,2929.95 1095.53,2938.97 1097.12,2949.9 1075.34,2962.21 1067.62,2958.58 1063.31,2956.43 1061.07,2940.64 1047.42,2931.6 1046.81,2914.56 1054.6,2899.79 1038.47,2892.87 1043.9,2882.52 1056.41,2883.28 1052.01,2860.71 1046.16,2848.06 1049.87,2834.59 1071.79,2834.66 1084.66,2846.38 1072.93,2869.92 1081.16,2878.5 1083.28,2877.28 1086.11,2879.86"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123515856"
- class="fil1 str3"
- points="1259.03,2990.59 1253.16,2929.55 1272.39,2939.79 1294.15,2939.26 1301.48,2954.11 1317.8,2956.53 1325.69,2975.93 1343.75,2985.16 1331.28,2997.15 1311.86,2986.69 1297.95,2995.24 1284.31,2984.34 1272.72,2984.97 1273.02,2995.68"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123523440"
- class="fil1 str3"
- points="1296.24,3030.21 1290.9,3038.94 1282.82,3039.19 1273.05,3040.6 1266.64,3037.07 1260.75,3041.02 1257.21,3044.35 1243.05,3009.83 1259.03,2990.59 1273.02,2995.68 1272.72,2984.97 1284.31,2984.34 1297.95,2995.24 1311.86,2986.69 1331.28,2997.15 1327.85,3000.45 1327.36,3010.63 1316.96,3017.51 1304.85,3009.58 1300.01,3013.29"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123509904"
- class="fil1 str3"
- points="1121.08,2789.95 1110.2,2794.33 1100.89,2799.5 1092.94,2820.34 1071.79,2834.66 1084.66,2846.38 1072.93,2869.92 1081.16,2878.5 1083.28,2877.28 1086.11,2879.86 1087.23,2878.88 1088.75,2879.43 1092.02,2872.76 1109.54,2876.35 1116.53,2909.85 1105.6,2914.68 1108.26,2929.95 1095.53,2938.97 1097.12,2949.9 1075.34,2962.21 1083.5,2966.13 1087.65,2984.09 1101.11,2986.67 1106.42,3004.64 1116.35,3006.32 1126.37,2988.95 1133.84,2989.42 1136.96,2989.62 1149.08,3013.22 1153.89,3002.76 1153.84,2979.88 1173.72,2988.99 1200.32,2974.38 1208.36,2964.09 1208.17,2947.96 1224.52,2953.76 1236.81,2935.19 1253.16,2929.55 1246.24,2917.38 1220.55,2909.89 1212.85,2896.74 1220.88,2891.94 1206.37,2874.25 1211.5,2856.94 1227.47,2851 1217.28,2827.87 1201,2833.34 1172.94,2819.43 1172.87,2792.53 1152.65,2792.11 1152.39,2807.76 1137.23,2815.57"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123527976"
- class="fil1 str3"
- points="1197.95,3023.89 1195.62,3001.4 1173.72,2988.99 1200.32,2974.38 1208.36,2964.09 1208.17,2947.96 1224.52,2953.76 1236.81,2935.19 1253.16,2929.55 1259.03,2990.59 1243.05,3009.83 1257.21,3044.35 1253.67,3047.69 1244.57,3034.19 1220.98,3031.41"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <g
- id="g532">
- <polygon
- id="_123517608"
- class="fil1 str3"
- points="1118.41,3009.43 1116.35,3006.32 1126.37,2988.95 1136.96,2989.62 1149.08,3013.22 1169.32,3059.64 1165.21,3059.51 1151.75,3046.07 1143.89,3053.24 1133.83,3053.59 1127.53,3046.94 1120.87,3051.57 1104.46,3054.96 1100.75,3043.55"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123513720"
- class="fil1 str3"
- points="1153.82,3088.51 1147.22,3084.67 1141.77,3080.94 1151.22,3073.1 1157.3,3082.72"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123514320"
- class="fil1 str3"
- points="1132.99,3063.75 1119.87,3073.81 1112.25,3067.04 1123.01,3055.72 1130.82,3055.78"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- </g>
- <g
- id="g537">
- <polygon
- id="_123507000"
- class="fil1 str3"
- points="1153.84,2979.88 1173.72,2988.99 1195.62,3001.4 1197.95,3023.89 1192.37,3022.07 1180.78,3033.71 1181.12,3052.38 1176.95,3059.87 1169.32,3059.64 1149.08,3013.22 1153.89,3002.76"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123508464"
- class="fil1 str3"
- points="1185.85,3063.38 1189.95,3049.66 1197.23,3052.25 1197.23,3075.77 1191.15,3075.91"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123524472"
- class="fil1 str3"
- points="1205.38,3108.12 1205.57,3100.48 1210.19,3095.95 1212.42,3096.12 1218.33,3101.66 1221.53,3104 1214.16,3108.49"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- </g>
- </g>
- <g
- id="_123526296">
- <polygon
- id="_123509520"
- class="fil1 str3"
- points="1219.97,2777.33 1201.69,2779.99 1182.8,2768.68 1189.32,2758.7 1204.69,2759.97 1208.42,2752.94 1246.49,2753.13 1270.46,2767.5 1291.71,2758.78 1307.95,2762.12 1297.62,2774.74 1279.71,2774.33 1270.42,2793.3 1254.87,2794.64 1238.81,2822.65 1231.77,2808.35 1237.88,2796.5"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123533496"
- class="fil1 str3"
- points="1293.68,2828.91 1294.79,2845.43 1282.55,2849.31 1283.32,2862.94 1269.88,2875.84 1253.96,2871.46 1244.22,2843.51 1227.47,2851 1217.26,2827.83 1238.81,2822.65 1254.87,2794.64 1270.42,2793.3 1279.71,2774.33 1297.62,2774.74 1307.95,2762.12 1324.92,2765.61 1315.25,2780.49 1320.61,2795.04 1305.44,2795.13 1301.18,2801.77 1307.53,2813.31 1308.69,2823.23"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123535896"
- class="fil1 str3"
- points="1294.15,2939.26 1272.39,2939.79 1253.16,2929.55 1246.24,2917.38 1220.55,2909.89 1212.85,2896.74 1220.88,2891.94 1206.37,2874.25 1211.5,2856.94 1227.47,2851 1244.22,2843.51 1253.96,2871.46 1269.88,2875.84 1276.05,2877.54 1319.61,2878.03 1328.43,2878.13 1334.25,2912.23 1321.59,2931.15 1312.5,2930.96 1305.41,2922.72 1300.2,2923.07"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123529944"
- class="fil1 str3"
- points="1458.49,2839.29 1466.02,2842.83 1450.69,2869.07 1448.29,2890.48 1427.77,2895.06 1389.32,2928.71 1381.94,2948.43 1343.75,2985.16 1325.69,2975.93 1317.8,2956.53 1301.48,2954.11 1294.15,2939.26 1300.2,2923.07 1305.41,2922.72 1312.5,2930.96 1321.59,2931.15 1334.25,2912.23 1328.43,2878.13 1319.61,2878.03 1321.43,2869.57 1340.2,2852.83 1393.11,2835.31 1402.66,2820.19 1387.65,2808.8 1385.47,2800.02 1400.24,2786.25 1431.65,2811.94 1444.27,2805.19"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123520008"
- class="fil1 str3"
- points="1322.54,2826.93 1340.2,2852.83 1321.43,2869.57 1319.61,2878.03 1276.05,2877.54 1269.88,2875.84 1283.32,2862.94 1282.55,2849.31 1294.79,2845.43 1293.68,2828.91 1308.69,2823.23"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123509136"
- class="fil1 str3"
- points="1301.18,2801.77 1305.44,2795.13 1320.61,2795.04 1315.25,2780.49 1324.92,2765.61 1374.74,2761.27 1393.39,2775.9 1400.24,2786.25 1385.47,2800.02 1387.65,2808.8 1402.66,2820.19 1393.11,2835.31 1340.2,2852.83 1322.54,2826.93 1308.69,2823.23 1307.53,2813.31"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123526776"
- class="fil1 str3"
- points="1489.01,2827.6 1477.85,2809.89 1487.59,2798.01 1480.11,2783.99 1467.91,2782.79 1463.85,2796.39 1444.23,2796.23 1444.27,2805.19 1431.65,2811.94 1400.24,2786.25 1393.39,2775.9 1374.74,2761.27 1400.18,2729.79 1407.78,2710.97 1422.05,2721.86 1459.56,2721.64 1464.4,2704.6 1495.02,2705.98 1525.89,2696.09 1524.42,2706.79 1522.66,2719.65 1508.5,2719.29 1503.73,2731.24 1512.04,2737.16 1495.67,2800.73 1511.7,2811.87"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123535344"
- class="fil1 str3"
- points="1463.85,2796.39 1467.91,2782.79 1480.11,2783.99 1487.59,2798.01 1477.85,2809.89 1489.01,2827.6 1485.65,2829.93 1469.78,2836.4 1466.02,2842.83 1458.49,2839.29 1444.27,2805.19 1444.23,2796.23"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123529704"
- class="fil1 str3"
- points="1511.7,2811.87 1495.67,2800.73 1512.04,2737.16 1503.73,2731.24 1508.5,2719.29 1522.66,2719.65 1524.42,2706.79 1562.21,2744.91 1530.07,2799.12"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123534144"
- class="fil1 str3"
- points="1525.89,2696.09 1544.95,2664.44 1557.1,2660.33 1569.25,2656.22 1574.91,2640.11 1664.71,2591.89 1661.79,2594.86 1649.79,2628.83 1619.63,2656.59 1599.34,2699.18 1573.78,2717.29 1568.01,2735.14 1562.21,2744.91 1524.42,2706.79"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- </g>
- <g
- id="_123514032">
- <polygon
- id="_123504168"
- class="fil1 str3"
- points="863.575,2199.98 866.13,2130.15 841.823,2119.67 829.36,2119.6 820.603,2119.55 809.876,2137.83 785.329,2135.35 766.274,2157.05 791.702,2189.18 778.643,2194.57 808.231,2208.56 814.137,2204.71 840.551,2194.96"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123523944"
- class="fil1 str3"
- points="866.13,2130.15 841.823,2119.67 829.36,2119.6 826.575,2068.38 852.991,2041.67 902.573,2102.34 890.26,2104.44"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123516456"
- class="fil1 str3"
- points="799.741,1967.2 808.386,1966.47 809.544,1971.34 824.378,1977.18 840.913,2026.89 852.991,2041.67 826.575,2068.38 763.028,1992.38 787.295,1972.58"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123526464"
- class="fil1 str3"
- points="804.533,1950.27 808.386,1966.47 799.741,1967.2 787.295,1972.58 763.028,1992.38 743.073,1975.99 724.913,1951.4 738.721,1941 734.808,1934.22 747.243,1934.05 756.618,1942.5 764.428,1938.25 755.457,1926.07 763.583,1910.81 784.212,1906.8 793.686,1944.63"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123508800"
- class="fil1 str3"
- points="785.329,2135.35 772.567,2116.37 776.902,2090.23 766.881,2078.38 758.176,2083.62 748.127,2072.18 727.288,2079.8 718.147,2081.01 722.083,2088.15 714.245,2114.3 741.564,2149.62 766.274,2157.05"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123511488"
- class="fil1 str3"
- points="809.326,2085.33 826.575,2068.38 829.36,2119.6 820.603,2119.55 809.876,2137.83 785.329,2135.35 772.567,2116.37 776.902,2090.23 766.881,2078.38 784.67,2066.18"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123516024"
- class="fil1 str3"
- points="766.881,2078.38 784.67,2066.18 734.373,2027.64 725.955,2036.66 708.601,2037.06 697.788,2028.25 683.972,2037.18 693.091,2053.3 701.553,2050.89 718.147,2081.01 727.288,2079.8 748.127,2072.18 758.176,2083.62"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <path
- id="_123536280"
- class="fil1 str3"
- d="m 784.67,2066.18 -36.0911,-27.6541 -14.2054,-10.8843 -36.9741,-29.7283 -10.6797,8.2832 -6.08098,-9.045 -23.2158,11.3209 -32.8707,-24.5459 -6.25511,8.4744 -14.3502,-39.4746 c 0.33031,-0.4948 0.4047,-0.04 0.73586,-0.5349 l 13.1235,0.077 6.00146,7.2284 6.6276,-0.1485 5.88005,-8.5924 28.2198,-1.2765 19.8446,-0.898 0.28243,-12.2868 0.77491,-33.7006 8.03378,-5.7267 11.8875,11.3437 9.53827,-1.6604 19.9116,27.4683 3.91329,6.7877 -13.8081,10.3944 18.1603,24.5907 19.9543,16.3942 63.5477,75.9955 -17.2491,16.9488 -24.6568,-19.1504 z"
- inkscape:connector-curvature="0"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- </g>
- <g
- id="_123507816">
- <polygon
- id="_123534168"
- class="fil1 str3"
- points="324.87,2855.63 331.73,2861.06 333.992,2853.29 323.011,2841.9 318.655,2817.98 326.984,2813.34 331.62,2820.18 342.792,2835.93 354.009,2835.06 367.103,2825.2 368.196,2851.22 359.619,2859.62 346.146,2848.09 347.305,2880.9 337.459,2880.75"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123526272"
- class="fil1 str3"
- points="346.146,2848.09 359.619,2859.62 368.196,2851.22 389.267,2836 400.797,2846.4 411.303,2875.96 438.309,2878.57 422.602,2898.76 386.162,2924.3 378.67,2921.73 369.378,2899.03 354.164,2895.41 347.305,2880.9"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123530592"
- class="fil1 str3"
- points="312.318,2914.66 311.779,2901.47 309.348,2892.27 311.198,2886.84 314.431,2884.63 316.01,2879.55 300.748,2870.3 299.889,2864.62 313.266,2861.92 313.722,2854.08 307.199,2847.1 311.04,2843.08 318.389,2842.59 324.929,2855.67 337.459,2880.75 347.305,2880.9 354.164,2895.41 369.378,2899.03 378.67,2921.73 345.974,2930.51 345.957,2960.27 322.638,2955.32 317.118,2940.85 317.44,2922.78"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123505704"
- class="fil1 str3"
- points="389.007,2973.67 395.432,2973.99 397.616,2976.78 408.297,2967.11 415.13,2960.93 428.886,2948.15 462.271,2934.8 481.871,2934.36 460.365,2914.78 443.893,2886.79 438.309,2878.57 422.602,2898.76 386.162,2924.3 384.558,2947.57 383.336,2967.69 390.139,2970.75"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123526536"
- class="fil1 str3"
- points="383.336,2967.69 372.159,2973.68 365.579,2965.56 345.957,2960.27 345.974,2930.51 378.67,2921.73 386.162,2924.3 384.558,2947.57"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123529968"
- class="fil1 str3"
- points="423.852,3026.39 428.807,2998.42 436.485,2995.33 452.374,3008.49 444.388,3022.57"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123528624"
- class="fil1 str3"
- points="448.827,2960.15 421.529,2983.79 408.297,2967.11 415.13,2960.93 428.886,2948.15 462.271,2934.8 481.871,2934.36 454.881,2963.15"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123510528"
- class="fil1 str3"
- points="452.374,3008.49 436.485,2995.33 448.077,2975.05 454.881,2963.15 481.871,2934.36 477.682,2963.89 466.052,2984.39"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123513024"
- class="fil1 str3"
- points="375.283,2987.85 383.218,2988.61 389.007,2973.67 395.432,2973.99 397.616,2976.78 408.297,2967.11 421.529,2983.79 448.827,2960.15 454.881,2963.15 448.077,2975.05 436.485,2995.33 428.807,2998.42 410.045,3005.96 405.308,3001.37 398.968,3001.57 383.919,3002.04 367.22,3006.12 367.985,2998.1"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123503976"
- class="fil1 str3"
- points="425.606,3027.77 423.852,3026.39 444.388,3022.57 477.682,2963.89 481.871,2934.36 487.537,2968.46 467.627,3017.66 467.929,3021.23 453.356,3036.83 459.955,3055.35 441.956,3058.82 431.993,3049.37 423.925,3048.85"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123515400"
- class="fil1 str3"
- points="502.567,3012.31 500.55,3048.8 497.701,3048.44 494.459,3053.5 485.448,3046.64 482.636,3049.08 479.824,3051.51 459.955,3055.35 453.356,3036.83 467.929,3021.23 474.024,3029.43"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123535680"
- class="fil1 str3"
- points="498.364,2979.53 507.12,2974.62 514.309,2979.86 511.234,2985.66 511.389,2997.58 516.83,3003.39 502.567,3012.31 474.024,3029.43 467.929,3021.23 467.627,3017.66 487.537,2968.46"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123523896"
- class="fil1 str3"
- points="537.879,3054.52 500.55,3048.8 502.567,3012.31 516.83,3003.39 539.728,3006.93 540.445,3011.49 543.097,3028.35"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123505560"
- class="fil1 str3"
- points="539.728,3006.93 516.83,3003.39 511.389,2997.58 511.234,2985.66 514.309,2979.86 525.78,2970.98 545.95,2975.66 536.584,2994.16"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123530352"
- class="fil1 str3"
- points="581.261,2996.68 540.445,3011.49 539.728,3006.93 536.584,2994.16 545.95,2975.66 559.567,2951.02 568.818,2978.35 579.098,2991.28"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123531936"
- class="fil1 str3"
- points="598.175,2940.77 607.44,2975.16 601.749,2991.75 580.517,2994.82 579.098,2991.28 568.818,2978.35 559.567,2951.02 580.321,2950.9 594.498,2938.88"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123509232"
- class="fil1 str3"
- points="525.801,2959.64 525.78,2970.98 514.309,2979.86 507.12,2974.62 498.364,2979.53 487.537,2968.46 481.871,2934.36 495.842,2944.72 501.356,2959.62"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polyline
- id="_123534192"
- class="fil1 str3"
- points="481.871,2934.36 495.842,2944.72 501.356,2959.62 525.801,2959.64 525.78,2970.98 545.95,2975.66 559.567,2951.02 547.399,2929.21 539.728,2915.46 505.249,2905.36 503.288,2893.16 512.488,2879.23 505.417,2869 478.834,2876.05 464.873,2873.43 459.805,2872.48 443.893,2886.79 460.365,2914.78 481.871,2934.36"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123505536"
- class="fil1 str3"
- points="594.498,2938.88 580.321,2950.9 559.567,2951.02 547.399,2929.21 539.728,2915.46 539.354,2887.19 539.532,2871.55 523.952,2883.3 516.785,2885.45 512.488,2879.23 505.417,2869 500.239,2862.47 523.876,2855.3 548.953,2862.17 550.978,2835.08 566.84,2840.65 578.371,2854.16 597.864,2850.36 596.51,2860.89 604.381,2859.88 604.271,2867.68 616.528,2875.01 608.333,2894.11 593.691,2897.09 592.29,2911.08 600.574,2920.76 593.733,2926.89 594.133,2935.82"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123504960"
- class="fil1 str3"
- points="539.602,2887.22 539.728,2915.46 505.249,2905.36 503.288,2893.16 512.488,2879.23 516.785,2885.45 523.952,2883.3 539.532,2871.55"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <g
- id="g583">
- <polygon
- id="_123513408"
- class="fil1 str3"
- points="564.339,3076.87 569.635,3070.42 565.592,3063.68 564.025,3061.07 540.807,3079.01 537.879,3054.52 543.097,3028.35 540.445,3011.49 581.261,2996.68 580.517,2994.82 601.749,2991.75 626.324,3000.88 643.104,2996.27 644.548,3010.6 652.187,3015.24 656.501,3026.63 672.733,3024.74 671.403,3038.58 681.624,3042.72 684.832,3062.04 674.926,3063.09 671.961,3082.95 656.979,3088.1 658.085,3122.45 641.986,3114.91 613.217,3129.19 603.544,3121.5 584.629,3141.3 573.772,3141.5 559.508,3141.76 560.044,3137.2 544.117,3127.6 543.361,3123.6 540.111,3106.4"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123511896"
- class="fil1 str3"
- points="548.677,3145.58 552.295,3137.44 545.34,3134.91 537.701,3142.6 539.905,3147.1"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123514008"
- class="fil1 str3"
- points="545.35,3163.5 538.981,3167.25 531.315,3170.77 527.284,3159.11 537.093,3150.98"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- </g>
- <polygon
- id="_123508632"
- class="fil1 str3"
- points="652.187,3015.24 644.548,3010.6 643.104,2996.27 626.324,3000.88 601.749,2991.75 607.44,2975.16 598.175,2940.77 619.967,2951.96 629.615,2947.14 639.263,2942.32 644.229,2946.13 674.917,2969.69 706.523,2980.15 701.625,2987.16 707.161,2996.65 696.041,3021.54 672.733,3024.74 656.501,3026.63"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <g
- id="g589">
- <polygon
- id="_123526920"
- class="fil1 str3"
- points="299.677,3000.61 295.944,2995.66 294.427,2993.64 291.924,2974.3 295.529,2971.31 308.358,2990.62 308.358,2996.39 308.358,3000.61"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123526944"
- class="fil1 str3"
- points="329.031,2986.39 329.231,2987.11 336.138,2993.66 333.051,3002.93 331.797,3006.69 324.877,3005.19 313.092,2990.17 313.193,2977.77 317.666,2973.92 328.759,2985.41"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123513840"
- class="fil1 str3"
- points="304.018,2973.25 297.507,2966.44 294.861,2963.67 293.66,2953.01 303.342,2946.12 310.095,2951.09 310.596,2959.87 310.963,2966.3"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- </g>
- <polygon
- id="_123532992"
- class="fil1 str3"
- points="372.159,2973.68 363.077,2978.55 358.094,3000.15 346.88,3001.15 342.51,2982.42 328.157,2969.79 322.638,2955.32 345.957,2960.27 365.579,2965.56"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <g
- id="g595">
- <polygon
- id="_123525264"
- class="fil1 str3"
- points="422.098,3025.01 413.217,3030.73 402.264,3020.74 405.489,3016.74 412.964,3017.12 413.36,3009.16 410.045,3005.96 428.807,2998.42 423.852,3026.39"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123517440"
- class="fil1 str3"
- points="350.692,3028.72 348.107,3033.41 343.299,3033.56 341.346,3033.62 339.176,3031.45 339.236,3023.38 354.56,3013.88 356.538,3020.59 353.161,3025.29"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123525072"
- class="fil1 str3"
- points="374.131,3056.09 363.917,3058.38 357.435,3052.51 354.802,3050.13 355.915,3044.14 358.768,3039.89 372.356,3044.29 373.466,3050.56 373.85,3053.76"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123524640"
- class="fil1 str3"
- points="392.334,3063.18 394.302,3052.47 384.982,3044.8 376.938,3026.67 378.674,3014.08 383.075,3010.35 393.191,3016.49 394.3,3021.89 404.193,3036.03 411.428,3046.36 409.442,3055.33 408.908,3061.53 408.692,3064.04 401.4,3071.3 391.758,3069.68"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- </g>
- <polygon
- id="_123507528"
- class="fil1 str3"
- points="540.807,3079.01 528.397,3088.6 505.365,3095.39 495.474,3086.45 479.701,3086.82 479.662,3077.15 494.459,3053.5 497.701,3048.44 500.55,3048.8 537.879,3054.52"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <g
- id="g602">
- <polygon
- id="_123522600"
- class="fil1 str3"
- points="477.802,3177.79 481.074,3175.09 482.403,3174 493.264,3175.66 500.932,3186.84 497.368,3191.84 489.077,3190.17 483.015,3188.96"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123524280"
- class="fil1 str3"
- points="457.845,3188.2 453.066,3188.09 450.891,3177.35 453.876,3174.62 455.089,3173.51 455.969,3173.02 459.398,3170.09 466.353,3174.36 465.774,3182.06 464.38,3188.36"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123527688"
- class="fil1 str3"
- points="476.853,3201.49 480.242,3201.72 479.663,3210.73 467.389,3219.36 460.618,3216.42 455.666,3214.27 468.513,3200.93"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123535872"
- class="fil1 str3"
- points="524.275,3148.27 539.638,3131.74 536,3123.5 531.026,3112.24 546.41,3090.76 488.937,3104.5 479.816,3098.14 475.527,3102.43 475.468,3108.33 469.524,3113.58 475.468,3120.93 476.26,3125.65 476.587,3127.59 459.535,3140.79 456.601,3155.12 464.774,3167.46 480.217,3168.39 490.262,3162.06 505.873,3168.41 518.462,3166.46 523.893,3158.89 524.517,3158.02 524.447,3155.21"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- </g>
- <g
- id="g608">
- <polygon
- id="_123524736"
- class="fil1 str3"
- points="280.679,3019.82 281.073,3016.86 286.414,3013.45 291.366,3023.26 288.896,3028.74 287.09,3032.75 279.711,3027.11"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123529536"
- class="fil1 str3"
- points="297.507,3047.09 294.421,3043.07 293.167,3041.44 295.831,3034.24 302.474,3033.43 308.728,3042.37 307.512,3044.59 306.622,3046.22"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123508944"
- class="fil1 str3"
- points="315.303,3039.7 312.217,3035.38 310.963,3033.62 312.325,3020.77 319.402,3019.96 321.38,3034.06 319.518,3034.69 318.157,3035.15"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123530784"
- class="fil1 str3"
- points="304.387,3084.07 314.704,3083.78 322.248,3083.57 321.801,3090.79 321.06,3096.34 320.76,3098.6 315.034,3100.47 308.792,3103.12 288.826,3096.17 291.924,3078.11 298.568,3077.3"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123528264"
- class="fil1 str3"
- points="317.436,3078.47 314.869,3081.4 309.4,3080.19 306.19,3077.96 304.886,3077.06 308.172,3073.76 308.791,3071.41 314.495,3065.51 322.007,3064.27 320.946,3074.45"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123522024"
- class="fil1 str3"
- points="368.657,3186.46 365.666,3190.73 359.476,3190.18 356.961,3189.96 353.509,3179.88 358.325,3174.39 362.675,3167.4 368.594,3173.08 368.63,3180.81"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123521520"
- class="fil1 str3"
- points="390.822,3105.15 388.961,3107.86 377.541,3110.77 370.807,3120.65 368.071,3124.66 360.175,3121.75 362.605,3104.94 365.219,3094.43 383.208,3094.24 393.368,3101.45"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123515040"
- class="fil1 str3"
- points="381.989,3117.07 384.751,3114.41 404.653,3124.03 402.716,3129.45 388.673,3129.27 378.405,3129.14 375.192,3123.61"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123530424"
- class="fil1 str3"
- points="410.742,3098.14 415.135,3095.74 420.713,3099.27 415.303,3112.51 406.526,3113.58 400.107,3114.37 399.933,3104.07"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123528648"
- class="fil1 str3"
- points="451.221,3063.78 479.133,3056.88 484.149,3064.9 464.092,3087.83 449.426,3104.6 439.897,3105.42 435.108,3099.99 433.162,3097.79 434.794,3088.66 423.633,3085.46 421.211,3076.19 428.723,3061.89 440.744,3064.9"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123525576"
- class="fil1 str3"
- points="459.76,3118.71 459.171,3118.43 453.445,3125.11 447.928,3125.11 445.687,3125.1 440.908,3120.02 454.189,3104.07 463.314,3103.56 468.892,3107.09 460.565,3119.08"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123516984"
- class="fil1 str3"
- points="335.282,3215.49 330.944,3218.96 329.182,3220.36 321.389,3216.37 331.857,3205.19 341.683,3205.66 342.471,3208.36 343.048,3210.35"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123513432"
- class="fil1 str3"
- points="341.406,3096.35 351.956,3095.54 352.133,3102.75 351.092,3107.21 350.33,3110.47 349.762,3116.42 348.089,3119.2 347.41,3120.33 341.16,3124.66 328.055,3125.23 322.248,3117.89 330.061,3110.07 331.066,3108.12"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123519768"
- class="fil1 str3"
- points="333.45,3074.53 333.593,3068.55 339.369,3065.14 350.192,3087.44 343.578,3090.98 338.742,3093.56 333.099,3089.22"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- </g>
- <polygon
- id="_123530832"
- class="fil1 str3"
- points="501.356,2959.62 495.842,2944.72 481.871,2934.36 460.365,2914.78 443.893,2886.79 459.805,2872.48 478.834,2876.05 505.417,2869 512.488,2879.23 503.288,2893.16 505.249,2905.36 539.728,2915.46 559.567,2951.02 545.95,2975.66 525.78,2970.98 525.801,2959.64"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- </g>
- <g
- id="_123507288">
- <polygon
- id="_123513936"
- class="fil1 str3"
- points="591.872,2574.72 585.27,2557.09 568.262,2555.04 556.397,2572.87 540.927,2561.29 540.911,2547.49 527.031,2540.67 536.267,2525.2 554.459,2523.43 555.341,2497.17 570.936,2489.64 570.796,2459.34 599.722,2459.44 603.154,2494.78 614.514,2518.96 643.074,2517.05 649.307,2523.61 639.687,2565.36 637.105,2576.57 614.401,2578.71 606.468,2562.92"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123533784"
- class="fil1 str3"
- points="614.514,2518.96 603.154,2494.78 599.722,2459.44 631.338,2442.18 656.435,2491.38 653.002,2497.98 643.074,2517.05"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123514536"
- class="fil1 str3"
- points="723.014,2502.83 720.436,2518.72 695.882,2527.59 687.356,2530.67 653.002,2497.98 656.435,2491.38 631.338,2442.18 645.754,2416.75 673.61,2427.63 677.504,2417.78 698.495,2420.78 724.382,2399.46 735.962,2406.83 738.921,2431.19 750.321,2435.93 750.251,2464.15 771.722,2477 771.52,2488.1 747.347,2513.38"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123510840"
- class="fil1 str3"
- points="840.872,2514.12 847.065,2520.15 853.961,2546.7 839.501,2569.81 835.201,2562.17 821.734,2581.68 807.25,2584.4 794.291,2570.77 788.423,2534.92 747.347,2513.38 771.52,2488.1 771.722,2477 782.995,2474.88 790.749,2497.03 811.397,2501.12 824.279,2496.5"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123517848"
- class="fil1 str3"
- points="710.537,2565.34 695.882,2527.59 720.436,2518.72 723.014,2502.83 747.347,2513.38 788.423,2534.92 794.291,2570.77 807.25,2584.4 805.805,2595.64 769.166,2612.12 751.885,2619.9 738.141,2626.08 721.349,2606.48"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123530304"
- class="fil1 str3"
- points="566.931,2641.39 537.311,2638.46 540.705,2620.89 553.841,2625.16 562.553,2594.72 556.397,2572.87 568.262,2555.04 585.27,2557.09 591.872,2574.72 606.468,2562.92 614.401,2578.71 637.105,2576.57 639.687,2565.36 676.478,2598.66 676.077,2607.38 648.661,2610.81 617.198,2633.15"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123504912"
- class="fil1 str3"
- points="676.077,2607.38 648.661,2610.81 617.198,2633.15 617.503,2653.46 637.944,2657.21 664.57,2649.05 660.545,2678.27 654.843,2683.29 667.241,2697.91 698.41,2695.83 695.523,2650.84 701.463,2644.8 707.613,2610.23 721.349,2606.48 710.537,2565.34 695.882,2527.59 687.049,2530.38 653.114,2498.28 643.074,2517.05 649.307,2523.61 639.687,2565.36 676.478,2598.66"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123511992"
- class="fil1 str3"
- points="822.15,2642.71 805.822,2642.71 769.166,2612.12 805.805,2595.64 807.25,2584.4 821.734,2581.68 838.747,2602.47"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123522552"
- class="fil1 str3"
- points="518.322,2771.13 508.209,2746.41 507.308,2732.96 516.578,2725.93 541.029,2722.35 543.685,2709.22 524.204,2695.59 525.852,2690.51 533.606,2666.6 547.471,2654.9 536.228,2644.07 537.311,2638.46 566.931,2641.39 567.169,2661.7 572.387,2667.98 594.405,2669.8 594.255,2689.47 611.14,2695.29 611.147,2708.9 602.207,2715.02 619.854,2744.58 612.354,2753.85 617.233,2755.59 619.507,2759.32 621.89,2774.45 617.648,2795.32 581.119,2801.61 571.268,2793.24 556.244,2777.91 547.8,2787.77 521.353,2778.54"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123506472"
- class="fil1 str3"
- points="572.387,2667.98 567.169,2661.7 566.931,2641.39 617.198,2633.15 617.503,2653.46 637.944,2657.21 664.57,2649.05 660.545,2678.27 654.843,2683.29 636.621,2699.36 617.095,2697.35 611.14,2695.29 594.255,2689.47 594.405,2669.8"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123512088"
- class="fil1 str3"
- points="698.41,2695.83 695.523,2650.84 701.463,2644.8 707.613,2610.23 721.349,2606.48 738.141,2626.08 751.885,2619.9 749.901,2671.12 714.477,2731.91 696.209,2727.71 696.241,2726.21 695.979,2715.23 682.835,2712.22 677.122,2716.99 667.241,2697.91"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123526224"
- class="fil1 str3"
- points="797.908,2699.55 830.653,2712.62 835.508,2704.87 845.078,2706.71 847.842,2693.94 857.886,2690.29 876.373,2705.54 875.177,2729.06 866.502,2724.03 861.709,2721.37 824.038,2734.83 806.005,2740.93 780.523,2732.7 777.388,2746.91 752.049,2754.13 747.2,2758.99 734.763,2771.44 722.863,2767.55 714.477,2731.91 749.901,2671.12 768.508,2687.12 789.468,2688.16"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123532536"
- class="fil1 str3"
- points="808.832,2775.62 833.758,2785.32 839.203,2773 851.034,2784.83 868.71,2776.92 866.502,2724.03 861.709,2721.37 824.038,2734.83 806.005,2740.93 780.523,2732.7 777.388,2746.91 752.049,2754.13 747.2,2758.99 752.398,2767.95 746.03,2779.43 754.751,2786.74 775.339,2794.5 780.133,2798.12 804.467,2779.24"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123534624"
- class="fil1 str3"
- points="612.354,2753.85 619.854,2744.58 602.207,2715.02 611.147,2708.9 611.14,2695.29 617.095,2697.35 636.621,2699.36 654.843,2683.29 667.241,2697.91 677.122,2716.99 657.535,2729.59 656.03,2743.7 646.395,2746.79 651.765,2761.06 619.507,2759.32 617.233,2755.59"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123535632"
- class="fil1 str3"
- points="667.06,2750.32 656.03,2743.7 657.535,2729.59 677.122,2716.99 682.835,2712.22 695.979,2715.23 696.209,2727.71"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123507864"
- class="fil1 str3"
- points="689.343,2789.46 689.314,2775.55 667.284,2749.75 696.209,2727.71 714.477,2731.91 722.863,2767.55 704.31,2792.96"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123526032"
- class="fil1 str3"
- points="715.359,2828.43 726.459,2809.83 704.31,2792.96 722.863,2767.55 734.763,2771.44 747.2,2758.99 752.398,2767.95 746.03,2779.43 754.751,2786.74 775.339,2794.5 771.866,2799.95 772.241,2806.46 775.576,2810.39 766.709,2820.94 719.506,2838.85"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123535824"
- class="fil1 str3"
- points="566.84,2840.65 576.782,2838.73 564.473,2817.08 571.268,2793.24 580.427,2801.12 617.648,2795.32 616.183,2802.37 631.34,2820.92 620.014,2824.51 617.597,2855.14 614.825,2853.04 604.381,2859.88 596.51,2860.89 597.864,2850.36 578.371,2854.16"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123513288"
- class="fil1 str3"
- points="621.89,2774.45 619.507,2759.32 651.765,2761.06 646.395,2746.79 656.03,2743.7 667.284,2749.75 689.314,2775.55 689.343,2789.46 667.501,2793.55 660.884,2804.17 637.476,2805.14 636.106,2796.78 617.648,2795.32"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123524976"
- class="fil1 str3"
- points="726.459,2809.83 704.31,2792.96 689.343,2789.46 667.501,2793.55 660.884,2804.17 654.864,2812.91 662.648,2828.41 675.01,2825.19 697.552,2847.18 719.506,2838.85 715.359,2828.43"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123532848"
- class="fil1 str3"
- points="631.458,2873.97 629.168,2863.92 617.597,2855.14 620.014,2824.51 631.34,2820.92 616.183,2802.37 617.648,2795.32 636.106,2796.78 637.476,2805.14 660.884,2804.17 654.864,2812.91 662.648,2828.41 675.01,2825.19 697.552,2847.18 701.798,2879.74 696.659,2884.78 676.072,2862.29 645.998,2873.75"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- <polygon
- id="_123520896"
- class="fil1 str3"
- points="849.764,2652.02 857.353,2656.57 859.788,2655.2 869.772,2661.13 860.037,2667.95 855.727,2677.44 857.886,2690.29 847.842,2693.94 845.078,2706.71 835.508,2704.87 830.653,2712.62 797.908,2699.55 789.468,2688.16 768.508,2687.12 749.901,2671.12 751.885,2619.9 769.166,2612.12 805.822,2642.71 822.15,2642.71 838.864,2603.08 855.993,2624.48 863.048,2625.71 862.962,2632.14 855.746,2632.58 853.548,2626.45 848.018,2630.15 850.892,2639.92"
- style="fill: none; stroke: rgb(199, 199, 162); stroke-width: 0.797991;" />
- </g>
- <g
- transform="matrix(1.0054068,0,0,1.0054068,-0.02738123,-0.03888718)"
- id="_74312864"><polygon
- style="fill:none;stroke:#cfcfa9;stroke-width:0.70866197"
- id="_53586096"
- points="1059.63,2737.39 1053.24,2749.32 1006.35,2749.25 1000.42,2769.94 992.882,2750.74 961.773,2752.66 956.125,2733.71 959.5,2724.72 947.476,2707.15 963.05,2651.08 986.438,2640.35 998.847,2646.25 1022.17,2695.83 1008.68,2709.29 1024.51,2726.86 1043.94,2714.13 " /><polygon
- style="fill:none;stroke:#cfcfa9;stroke-width:0.70866197"
- id="_55040216"
- points="931.519,2785.71 911.795,2789.77 897.049,2778.38 885.515,2783.83 888.711,2771.86 864.04,2761.99 861.843,2709.39 870.471,2714.38 947.476,2707.15 959.5,2724.72 956.125,2733.71 961.773,2752.66 941.39,2764.32 " /><polygon
- style="fill:none;stroke:#cfcfa9;stroke-width:0.70866197"
- id="_54401600"
- points="1043.94,2714.13 1024.51,2726.86 1008.68,2709.29 1022.17,2695.83 998.847,2646.25 1015.13,2618.1 1033.29,2627.23 1054.06,2659.23 1083.26,2670.95 1073.28,2697.67 1069.81,2729.63 1059.63,2737.39 " /><polygon
- style="fill:none;stroke:#cfcfa9;stroke-width:0.70866197"
- id="_55213984"
- points="1020.5,2817.69 1012.39,2827.94 995.848,2827.45 961.283,2826.41 954.268,2816.05 923.26,2831.7 913.982,2827.14 911.795,2789.77 931.519,2785.71 941.39,2764.32 961.773,2752.66 992.882,2750.74 1000.42,2769.94 1013.37,2776.81 1022.09,2789.84 1013.87,2800.75 " /><polygon
- style="fill:none;stroke:#cfcfa9;stroke-width:0.70866197"
- id="_55250640"
- points="886.516,2843.51 913.982,2827.14 923.26,2831.7 913.932,2853.9 917.503,2861.54 896.631,2895.09 879.104,2873.78 " /><polygon
- style="fill:none;stroke:#cfcfa9;stroke-width:0.70866197"
- id="_55261112"
- points="969.837,2846.07 956.706,2865.06 961.423,2883.98 975.625,2890.25 973.584,2902.46 941.39,2906.56 926.458,2892 926.696,2880.84 917.503,2861.54 913.932,2853.9 923.26,2831.7 954.268,2816.05 961.283,2826.41 995.848,2827.45 986.881,2836.89 999.636,2841.15 995.497,2850.72 " /><polygon
- style="fill:none;stroke:#cfcfa9;stroke-width:0.70866197"
- id="_54158464"
- points="969.837,2846.07 995.497,2850.72 1005.21,2854.47 991.145,2891.34 975.625,2890.25 961.423,2883.98 956.706,2865.06 " /><polygon
- style="fill:none;stroke:#cfcfa9;stroke-width:0.70866197"
- id="_55233608"
- points="907.143,2913.76 893.023,2917.51 886.578,2903.58 896.631,2895.09 917.503,2861.54 926.696,2880.84 926.458,2892 941.39,2906.56 943.406,2922.02 927.571,2938.6 " /><path
- style="fill:none;stroke:#cfcfa9;stroke-width:0.70866197"
- d="M 1012.0625 2889.75 L 1004.4062 2901.9375 L 982.125 2891.2812 L 966.59375 2890.2188 L 964.5625 2902.4062 L 932.375 2906.5312 L 934.375 2921.9688 L 939.125 2926.1875 L 946.125 2951.5938 L 947.59375 2950.7812 L 954.625 2959.5625 L 982.75 2950.8438 L 991.3125 2952.25 L 1004.6562 2942.8125 L 1005.4375 2956.5625 L 1025.3125 2952.25 L 1038 2963.625 L 1051.2188 2956.5312 L 1052.8438 2942.625 L 1048.5625 2940.5 L 1046.3438 2924.7812 L 1032.7812 2915.7812 L 1032.1562 2898.8438 L 1012.0625 2889.75 z "
- transform="translate(9.0226775,0.04366498)"
- id="_55216032" /><polygon
- style="fill:none;stroke:#cfcfa9;stroke-width:0.70866197"
- id="_74091008"
- points="1032.89,2877.32 1048.93,2884.2 1041.19,2898.89 1021.09,2889.78 1013.43,2901.99 991.145,2891.34 1005.21,2854.47 995.497,2850.72 999.636,2841.15 986.881,2836.89 995.848,2827.45 1012.77,2827.96 1020.39,2839.26 1040.53,2832.74 1046.35,2845.33 1050.73,2867.78 1038.29,2867.02 " /><polygon
- style="fill:none;stroke:#cfcfa9;stroke-width:0.70866197"
- id="_74456064"
- points="1094.31,2762.12 1103.07,2763.74 1104.1,2778.92 1094.97,2784.45 1087.07,2805.18 1066.03,2819.42 1044.23,2819.35 1040.53,2832.74 1020.39,2839.26 1012.77,2827.96 1020.5,2817.69 1013.87,2800.75 1022.09,2789.84 1013.76,2776.83 1000.42,2769.94 1006.35,2749.25 1053.24,2749.32 1059.63,2737.39 1069.68,2729.29 1079.31,2736.39 1079.89,2748.62 " /></g></g>
-</svg> \ No newline at end of file
diff --git a/examples/mapdata/doc/images/mapdata-example.png b/examples/mapdata/doc/images/mapdata-example.png
deleted file mode 100644
index 8bd8fc18..00000000
--- a/examples/mapdata/doc/images/mapdata-example.png
+++ /dev/null
Binary files differ
diff --git a/examples/mapdata/doc/src/mapdata.qdoc b/examples/mapdata/doc/src/mapdata.qdoc
deleted file mode 100644
index 3014cadb..00000000
--- a/examples/mapdata/doc/src/mapdata.qdoc
+++ /dev/null
@@ -1,29 +0,0 @@
-/****************************************************************************
-**
-** 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 mapdata
- \title Mapdata Example
-
- The mapdata example shows how to make a simple 3D maps visualization using Q3DMaps and
- combining the use of widgets for adjusting several adjustable qualities.
-
- \image mapdata-example.png
-
- TODO
-*/
diff --git a/examples/mapdata/main.cpp b/examples/mapdata/main.cpp
deleted file mode 100644
index d176bd55..00000000
--- a/examples/mapdata/main.cpp
+++ /dev/null
@@ -1,201 +0,0 @@
-/****************************************************************************
-**
-** 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 "mapdata.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();
-
- Q3DMaps *chart = new Q3DMaps();
- 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("Population of a few cities in Finland"));
-
- hLayout->addWidget(container, 1);
- hLayout->addLayout(vLayout);
-
-// QPushButton *dataButton = new QPushButton(widget);
-// dataButton->setText(QStringLiteral("Add a row of random data"));
-// dataButton->setEnabled(false);
-
- 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 bar style"));
-
- QPushButton *cameraButton = new QPushButton(widget);
- cameraButton->setText(QStringLiteral("Change camera preset"));
-
-// QPushButton *selectionButton = new QPushButton(widget);
-// selectionButton->setText(QStringLiteral("Change selection mode"));
-
-// QCheckBox *gridCheckBox = new QCheckBox(widget);
-// gridCheckBox->setText(QStringLiteral("Show grid"));
-// gridCheckBox->setChecked(true);
-
-// QCheckBox *rotationCheckBox = new QCheckBox(widget);
-// rotationCheckBox->setText("Rotate with slider");
-
-// QSlider *rotationSliderX = new QSlider(Qt::Horizontal, widget);
-// rotationSliderX->setTickInterval(1);
-// rotationSliderX->setMinimum(-180);
-// rotationSliderX->setValue(0);
-// rotationSliderX->setMaximum(180);
-// rotationSliderX->setEnabled(false);
-// QSlider *rotationSliderY = new QSlider(Qt::Horizontal, widget);
-// rotationSliderY->setTickInterval(1);
-// rotationSliderY->setMinimum(0);
-// rotationSliderY->setValue(0);
-// rotationSliderY->setMaximum(90);
-// rotationSliderY->setEnabled(false);
-
-// QSlider *sizeSliderX = new QSlider(Qt::Horizontal, widget);
-// sizeSliderX->setTickInterval(1);
-// sizeSliderX->setMinimum(1);
-// sizeSliderX->setValue(100);
-// sizeSliderX->setMaximum(100);
-// QSlider *sizeSliderZ = new QSlider(Qt::Horizontal, widget);
-// sizeSliderZ->setTickInterval(1);
-// sizeSliderZ->setMinimum(1);
-// sizeSliderZ->setValue(100);
-// sizeSliderZ->setMaximum(100);
-
- QComboBox *valueDimension = new QComboBox(widget);
- valueDimension->addItem(QStringLiteral("Height"));
- valueDimension->addItem(QStringLiteral("Width"));
- valueDimension->addItem(QStringLiteral("Depth"));
- valueDimension->addItem(QStringLiteral("Radius"));
- valueDimension->addItem(QStringLiteral("All"));
- valueDimension->setCurrentIndex(4);
-
- 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(80);
- fontSizeSlider->setMaximum(200);
-
-// vLayout->addWidget(rotationCheckBox, 0, Qt::AlignTop);
-// vLayout->addWidget(rotationSliderX, 0, Qt::AlignTop);
-// vLayout->addWidget(rotationSliderY, 0, Qt::AlignTop);
-// vLayout->addWidget(new QLabel(QStringLiteral("Adjust relative bar size")));
-// vLayout->addWidget(sizeSliderX, 0, Qt::AlignTop);
-// vLayout->addWidget(sizeSliderZ, 0, Qt::AlignTop);
-// vLayout->addWidget(dataButton, 0, Qt::AlignTop);
- 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(new QLabel(QStringLiteral("Apply value to:")));
- vLayout->addWidget(valueDimension, 0, Qt::AlignTop);
-// vLayout->addWidget(selectionButton, 0, Qt::AlignTop);
-// 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);
-// // TODO: Add example for setMeshFileName
-
- widget->show();
-
- MapsModifier *modifier = new MapsModifier(chart);
-
-// QObject::connect(rotationSliderX, &QSlider::valueChanged, modifier, &MapsModifier::rotateX);
-// QObject::connect(rotationSliderY, &QSlider::valueChanged, modifier, &MapsModifier::rotateY);
-
-// QObject::connect(sizeSliderX, &QSlider::valueChanged, modifier, &MapsModifier::setSpecsX);
-// QObject::connect(sizeSliderZ, &QSlider::valueChanged, modifier, &MapsModifier::setSpecsZ);
-
- QObject::connect(fontSizeSlider, &QSlider::valueChanged, modifier,
- &MapsModifier::changeFontSize);
-
- QObject::connect(styleButton, &QPushButton::clicked, modifier, &MapsModifier::changeStyle);
- QObject::connect(cameraButton, &QPushButton::clicked, modifier,
- &MapsModifier::changePresetCamera);
- QObject::connect(themeButton, &QPushButton::clicked, modifier, &MapsModifier::changeTheme);
- QObject::connect(labelButton, &QPushButton::clicked, modifier,
- &MapsModifier::changeTransparency);
-// QObject::connect(dataButton, &QPushButton::clicked, modifier, &MapsModifier::addBars);
-// QObject::connect(selectionButton, &QPushButton::clicked, modifier,
-// &MapsModifier::changeSelectionMode);
-
- QObject::connect(valueDimension, SIGNAL(currentIndexChanged(int)), modifier,
- SLOT(changeValueDimension(int)));
-
- 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);
-
-// QObject::connect(gridCheckBox, &QCheckBox::stateChanged, modifier,
-// &MapsModifier::setGridEnabled);
-
-// QObject::connect(rotationCheckBox, &QCheckBox::stateChanged, rotationSliderX,
-// &QSlider::setEnabled);
-// QObject::connect(rotationCheckBox, &QCheckBox::stateChanged, rotationSliderX,
-// &QSlider::setValue);
-// QObject::connect(rotationCheckBox, &QCheckBox::stateChanged, rotationSliderY,
-// &QSlider::setEnabled);
-// QObject::connect(rotationCheckBox, &QCheckBox::stateChanged, rotationSliderY,
-// &QSlider::setValue);
-
- modifier->start();
-
- return app.exec();
-}
diff --git a/examples/mapdata/mapdata.cpp b/examples/mapdata/mapdata.cpp
deleted file mode 100644
index 6f0157da..00000000
--- a/examples/mapdata/mapdata.cpp
+++ /dev/null
@@ -1,368 +0,0 @@
-/****************************************************************************
-**
-** 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 "mapdata.h"
-#include <QtDataVis3D/qmapdataproxy.h>
-#include <QImage>
-#include <QFile>
-
-using namespace QtDataVis3D;
-
-MapsModifier::MapsModifier(Q3DMaps *maps)
- : m_chart(maps),
- m_imageRect(QRect()),
- m_fontSize(80.0f),
- m_barSpecs(QVector3D(30.0f, 30.0f, 30.0f))
-{
- QImage image = QImage(QStringLiteral(":/images/finland"));
- m_imageRect = image.rect();
- m_chart->setAreaSpecs(m_imageRect, image);
- m_chart->setFontSize(m_fontSize);
-
-#if 0
- m_chart->setBarSpecs(m_barSpecs, Q3DMaps::AdjustHeight);
- m_chart->setBarType(BevelBars, true);
- m_chart->setTheme(ThemeBlueIcy);
- m_chart->setShadowQuality(ShadowMedium);
-#else
- m_chart->setBarSpecs(m_barSpecs, Q3DMaps::AdjustAll);
- m_chart->setMeshFileName(QStringLiteral(":/meshes/weirdthing"));
-#endif
- QMapDataProxy *proxy = new QMapDataProxy;
- m_chart->setDataProxy(proxy);
-}
-
-MapsModifier::~MapsModifier()
-{
- delete m_chart;
-}
-
-void MapsModifier::start()
-{
- addData();
-}
-
-void MapsModifier::addData()
-{
- QMapDataArray *dataArray = new QMapDataArray;
- QMapDataItem *item;
- item = new QMapDataItem();
- item->setValue(191050);
- item->setLabel("Oulu");
- item->setMapPosition(QPointF(963, 1604));
- dataArray->append(*item);
- delete item;
-
- item = new QMapDataItem();
- item->setValue(22274);
- item->setLabel("Kemi");
- item->setMapPosition(QPointF(857, 1383));
- dataArray->append(*item);
- delete item;
-
- item = new QMapDataItem();
- item->setValue(60887);
- item->setLabel("Rovaniemi");
- item->setMapPosition(QPointF(1061, 1119));
- dataArray->append(*item);
- delete item;
-
- item = new QMapDataItem();
- item->setValue(16176);
- item->setLabel("Kuusamo");
- item->setMapPosition(QPointF(1459, 1284));
- dataArray->append(*item);
- delete item;
-
- item = new QMapDataItem();
- item->setValue(3998);
- item->setLabel("Ivalo");
- item->setMapPosition(QPointF(1239, 474));
- dataArray->append(*item);
- delete item;
-
- item = new QMapDataItem();
- item->setValue(37978);
- item->setLabel("Kajaani");
- item->setMapPosition(QPointF(1285, 1859));
- dataArray->append(*item);
- delete item;
-
- item = new QMapDataItem();
- item->setValue(46809);
- item->setLabel("Kokkola");
- item->setMapPosition(QPointF(580, 1973));
- dataArray->append(*item);
- delete item;
-
- item = new QMapDataItem();
- item->setValue(105236);
- item->setLabel("Kuopio");
- item->setMapPosition(QPointF(1292, 2283));
- dataArray->append(*item);
- delete item;
-
- item = new QMapDataItem();
- item->setValue(133557);
- item->setLabel("Jyväskylä");
- item->setMapPosition(QPointF(991, 2496));
- dataArray->append(*item);
- delete item;
-
- item = new QMapDataItem();
- item->setValue(65771);
- item->setLabel("Vaasa");
- item->setMapPosition(QPointF(441, 2184));
- dataArray->append(*item);
- delete item;
-
- item = new QMapDataItem();
- item->setValue(217603);
- item->setLabel("Tampere");
- item->setMapPosition(QPointF(686, 2656));
- dataArray->append(*item);
- delete item;
-
- item = new QMapDataItem();
- item->setValue(180350);
- item->setLabel("Turku");
- item->setMapPosition(QPointF(430, 3046));
- dataArray->append(*item);
- delete item;
-
- item = new QMapDataItem();
- item->setValue(72400);
- item->setLabel("Lappeenranta");
- item->setMapPosition(QPoint(1365, 2852));
- dataArray->append(*item);
- delete item;
-
- item = new QMapDataItem();
- item->setValue(14754);
- item->setLabel("Tammisaari");
- item->setMapPosition(QPointF(605, 3215));
- dataArray->append(*item);
- delete item;
-
- item = new QMapDataItem();
- item->setValue(1879);
- item->setLabel("Enontekiö");
- item->setMapPosition(QPointF(752, 556));
- dataArray->append(*item);
- delete item;
-
- item = new QMapDataItem();
- item->setValue(36624);
- item->setLabel("Savonlinna");
- item->setMapPosition(QPointF(1445, 2586));
- dataArray->append(*item);
- delete item;
-
- item = new QMapDataItem();
- item->setValue(605022);
- item->setLabel("Helsinki");
- item->setMapPosition(QPointF(822, 3130));
- dataArray->append(*item);
- delete item;
-
- item = new QMapDataItem();
- item->setValue(54887);
- item->setLabel("Kotka");
- item->setMapPosition(QPointF(1162, 3051));
- dataArray->append(*item);
- delete item;
-
- item = new QMapDataItem();
- item->setValue(11372);
- item->setLabel("Maarianhamina");
- item->setMapPosition(QPointF(56, 3101));
- dataArray->append(*item);
- delete item;
-
- item = new QMapDataItem();
- item->setValue(9266);
- item->setLabel("Hanko");
- item->setMapPosition(QPointF(527, 3228));
- dataArray->append(*item);
- delete item;
-
- item = new QMapDataItem();
- item->setValue(1287);
- item->setLabel("Utsjoki");
- item->setMapPosition(QPointF(1180, 72));
- dataArray->append(*item);
- delete item;
-
- static_cast<QMapDataProxy *>(m_chart->dataProxy())->resetArray(dataArray);
-}
-
-void MapsModifier::changeStyle()
-{
- static int model = 0;
- switch (model) {
- case 0:
- m_chart->setBarType(QDataVis::Cylinders, false);
- break;
- case 1:
- m_chart->setBarType(QDataVis::Cylinders, true);
- break;
- case 2:
- m_chart->setBarType(QDataVis::Cones, false);
- break;
- case 3:
- m_chart->setBarType(QDataVis::Cones, true);
- break;
- case 4:
- m_chart->setBarType(QDataVis::Bars, false);
- break;
- case 5:
- m_chart->setBarType(QDataVis::Bars, true);
- break;
- case 6:
- m_chart->setBarType(QDataVis::Pyramids, false);
- break;
- case 7:
- m_chart->setBarType(QDataVis::Pyramids, true);
- break;
- case 8:
- m_chart->setBarType(QDataVis::BevelBars, false);
- break;
- case 9:
- m_chart->setBarType(QDataVis::BevelBars, true);
- break;
- case 10:
- m_chart->setBarType(QDataVis::Spheres, false);
- break;
- case 11:
- m_chart->setBarType(QDataVis::Spheres, true);
- break;
- }
- model++;
- if (model > 11)
- model = 0;
-}
-
-void MapsModifier::changePresetCamera()
-{
- static int preset = QDataVis::PresetFrontLow;
-
- m_chart->setCameraPreset((QDataVis::CameraPreset)preset);
-
- if (++preset > QDataVis::PresetDirectlyAboveCCW45)
- preset = QDataVis::PresetFrontLow;
-}
-
-void MapsModifier::changeTheme()
-{
- static int theme = QDataVis::ThemeSystem;
-
- m_chart->setTheme((QDataVis::ColorTheme)theme);
-
- if (++theme > QDataVis::ThemeLight)
- theme = QDataVis::ThemeSystem;
-}
-
-void MapsModifier::changeTransparency()
-{
- static int transparency = QDataVis::TransparencyNone;
-
- m_chart->setLabelTransparency((QDataVis::LabelTransparency)transparency);
-
- if (++transparency > QDataVis::TransparencyNoBackground)
- transparency = QDataVis::TransparencyFromTheme;
-}
-
-void MapsModifier::changeValueDimension(int dimension)
-{
- m_chart->setBarSpecs(m_barSpecs, (Q3DMaps::AdjustmentDirection)dimension);
-}
-
-void MapsModifier::changeFont(const QFont &font)
-{
- QFont newFont = font;
- newFont.setPointSizeF(m_fontSize);
- //qDebug() << newFont << newFont.style();
- m_chart->setFont(newFont);
-}
-
-void MapsModifier::changeFontSize(int fontsize)
-{
- m_fontSize = fontsize;
- m_chart->setFontSize((GLfloat)m_fontSize);
-}
-
-void MapsModifier::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;
- }
- 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)
-//{
-// m_chart->setGridEnabled((bool)enabled);
-//}
-
-//void MapsModifier::rotateX(int rotation)
-//{
-// m_xRotation = rotation;
-// m_chart->setCameraPosition(m_xRotation, m_yRotation);
-//}
-
-//void MapsModifier::rotateY(int rotation)
-//{
-// m_yRotation = rotation;
-// m_chart->setCameraPosition(m_xRotation, m_yRotation);
-//}
-
-//void MapsModifier::setSpecsX(int barwidth)
-//{
-// m_barWidth = (float)barwidth / 100.0f;
-// m_chart->setBarSpecs(QSizeF(m_barWidth, m_barDepth), QSizeF(m_barSpacingX, m_barSpacingZ));
-//}
-
-//void MapsModifier::setSpecsZ(int bardepth)
-//{
-// m_barDepth = (float)bardepth / 100.0f;
-// m_chart->setBarSpecs(QSizeF(m_barWidth, m_barDepth), QSizeF(m_barSpacingX, m_barSpacingZ));
-//}
diff --git a/examples/mapdata/mapdata.qrc b/examples/mapdata/mapdata.qrc
deleted file mode 100644
index 76ea5f05..00000000
--- a/examples/mapdata/mapdata.qrc
+++ /dev/null
@@ -1,8 +0,0 @@
-<RCC>
- <qresource prefix="/images">
- <file alias="finland">Suomi.karttapohja.svg</file>
- </qresource>
- <qresource prefix="/meshes">
- <file alias="weirdthing">weirdthing.obj</file>
- </qresource>
-</RCC>
diff --git a/examples/mapdata/weirdthing.obj b/examples/mapdata/weirdthing.obj
deleted file mode 100644
index 46c9e789..00000000
--- a/examples/mapdata/weirdthing.obj
+++ /dev/null
@@ -1,1232 +0,0 @@
-# Blender v2.66 (sub 0) OBJ File: 'kummajuttu.blend'
-# www.blender.org
-o Sphere
-v 0.003570 0.980785 -0.198744
-v 0.003570 0.923880 -0.386337
-v 0.003570 0.831470 -0.559224
-v 0.003570 0.707107 -0.710760
-v 0.003570 0.555570 -0.835123
-v 0.003570 0.382683 -0.927533
-v 0.003570 0.195090 -0.984439
-v 0.003570 0.000000 -1.003654
-v 0.003570 -0.195090 -0.984439
-v 0.003570 -0.382683 -0.927533
-v 0.003570 -0.555570 -0.835123
-v 0.003570 -0.707107 -0.710760
-v 0.003570 -0.831470 -0.559224
-v 0.003570 -0.923880 -0.386337
-v 0.003570 -0.980785 -0.198744
-v 0.078228 0.980785 -0.183894
-v 0.150016 0.923880 -0.357207
-v 0.216177 0.831470 -0.516933
-v 0.274168 0.707107 -0.656935
-v 0.321760 0.555570 -0.771831
-v 0.357123 0.382683 -0.857207
-v 0.378900 0.195090 -0.909781
-v 0.386254 0.000000 -0.927533
-v 0.378900 -0.195090 -0.909781
-v 0.357124 -0.382683 -0.857207
-v 0.321760 -0.555570 -0.771831
-v 0.274168 -0.707107 -0.656935
-v 0.216177 -0.831470 -0.516933
-v 0.150016 -0.923880 -0.357207
-v 0.078227 -0.980785 -0.183893
-v 0.003569 -1.000000 -0.003653
-v 0.141519 0.980785 -0.141603
-v 0.274168 0.923880 -0.274251
-v 0.396417 0.831470 -0.396501
-v 0.503570 0.707107 -0.503653
-v 0.591508 0.555570 -0.591591
-v 0.656851 0.382683 -0.656934
-v 0.697090 0.195090 -0.697173
-v 0.710677 0.000000 -0.710760
-v 0.697090 -0.195090 -0.697173
-v 0.656852 -0.382683 -0.656935
-v 0.591508 -0.555570 -0.591591
-v 0.503570 -0.707107 -0.503653
-v 0.396417 -0.831470 -0.396501
-v 0.274168 -0.923880 -0.274251
-v 0.141519 -0.980785 -0.141603
-v 0.183810 0.980785 -0.078311
-v 0.357123 0.923880 -0.150100
-v 0.516850 0.831470 -0.216261
-v 0.656851 0.707107 -0.274251
-v 0.771748 0.555570 -0.321843
-v 0.857123 0.382683 -0.357206
-v 0.909697 0.195090 -0.378983
-v 0.927450 0.000000 -0.386336
-v 0.909697 -0.195090 -0.378983
-v 0.857123 -0.382683 -0.357206
-v 0.771748 -0.555570 -0.321843
-v 0.656851 -0.707107 -0.274251
-v 0.516850 -0.831470 -0.216261
-v 0.357123 -0.923880 -0.150100
-v 0.183810 -0.980785 -0.078311
-v 0.198660 0.980785 -0.003653
-v 0.677357 1.471222 -0.125912
-v 0.559140 0.831470 -0.003653
-v 0.710676 0.707107 -0.003653
-v 0.835039 0.555570 -0.003653
-v 0.927449 0.382683 -0.003653
-v 0.984355 0.195090 -0.003653
-v 1.003570 0.000000 -0.003653
-v 0.984355 -0.195090 -0.003653
-v 0.927449 -0.382683 -0.003653
-v 0.835039 -0.555570 -0.003653
-v 0.710676 -0.707107 -0.003653
-v 0.559140 -0.831470 -0.003653
-v 0.386253 -0.923880 -0.003653
-v 0.198660 -0.980785 -0.003653
-v 0.183810 0.980785 0.071005
-v 0.357123 0.923880 0.142794
-v 0.516850 0.831470 0.208955
-v 0.656851 0.707107 0.266945
-v 0.771747 0.555570 0.314537
-v 0.857123 0.382683 0.349901
-v 0.909697 0.195090 0.371678
-v 0.927449 0.000000 0.379031
-v 0.909697 -0.195090 0.371678
-v 0.857123 -0.382683 0.349901
-v 0.771747 -0.555570 0.314537
-v 0.656851 -0.707107 0.266945
-v 0.516850 -0.831470 0.208955
-v 0.357123 -0.923880 0.142794
-v 0.183809 -0.980785 0.071005
-v 0.141519 0.980785 0.134297
-v 0.274168 0.923880 0.266945
-v 0.396417 0.831470 0.389194
-v 0.503569 0.707107 0.496347
-v 0.510364 0.555081 0.463719
-v 0.656851 0.382683 0.649629
-v 0.697089 0.195090 0.689867
-v 0.710676 0.000000 0.703454
-v 0.748412 -0.191114 0.569205
-v 0.656851 -0.382683 0.649629
-v 0.591507 -0.555570 0.584285
-v 0.503569 -0.707107 0.496347
-v 0.396417 -0.831470 0.389195
-v 0.274167 -0.923880 0.266945
-v 0.141519 -0.980785 0.134296
-v 0.078227 0.980785 0.176587
-v 0.150016 0.923880 0.349900
-v 0.216177 0.831470 0.509627
-v 0.274167 0.707107 0.649628
-v 0.291322 0.560724 0.763409
-v 0.277774 0.364301 0.818832
-v 0.378899 0.195090 0.902475
-v 0.386252 0.000000 0.920227
-v 0.379597 -0.105845 0.875443
-v 0.357122 -0.382683 0.849900
-v 0.321759 -0.555570 0.764525
-v 0.274167 -0.707107 0.649628
-v 0.216177 -0.831470 0.509627
-v 0.150016 -0.923880 0.349900
-v 0.078227 -0.980785 0.176587
-v 0.003569 0.980785 0.191437
-v 0.003569 0.923880 0.379030
-v 0.003569 0.831470 0.551917
-v 0.003569 0.707107 0.703454
-v 0.003569 0.555570 0.827816
-v 0.002822 0.396037 1.575037
-v -0.004287 0.229143 1.537837
-v 0.003569 0.000000 0.996347
-v 0.002270 0.152905 1.513075
-v 0.003569 -0.382683 0.920226
-v 0.003569 -0.555570 0.827816
-v 0.003569 -0.707107 0.703454
-v 0.003569 -0.831470 0.551917
-v 0.003569 -0.923880 0.379030
-v 0.003569 -0.980785 0.191437
-v -0.071089 0.980785 0.176587
-v -0.142877 0.923880 0.349900
-v -0.209038 0.831470 0.509627
-v -0.267029 0.707107 0.649628
-v -0.278921 0.569917 0.759967
-v -0.256269 0.375922 0.808299
-v -0.371761 0.195090 0.902474
-v -0.379115 0.000000 0.920226
-v -0.376325 -0.115657 0.878437
-v -0.349985 -0.382683 0.849900
-v -0.314621 -0.555570 0.764524
-v -0.267029 -0.707107 0.649628
-v -0.209038 -0.831470 0.509627
-v -0.142877 -0.923880 0.349900
-v -0.071088 -0.980785 0.176587
-v -0.134381 0.980785 0.134296
-v -0.267029 0.923880 0.266945
-v -0.389278 0.831470 0.389194
-v -0.496431 0.707107 0.496346
-v -0.514055 0.534945 0.480404
-v -0.649713 0.382683 0.649628
-v -0.689951 0.195090 0.689866
-v -0.703538 0.000000 0.703453
-v -0.717210 -0.189018 0.574779
-v -0.649712 -0.382683 0.649628
-v -0.584369 -0.555570 0.584284
-v -0.496431 -0.707107 0.496346
-v -0.389278 -0.831470 0.389194
-v -0.267029 -0.923880 0.266945
-v -0.134380 -0.980785 0.134296
-v -0.176671 0.980785 0.071004
-v -0.349984 0.923880 0.142793
-v -0.509711 0.831470 0.208954
-v -0.649712 0.707107 0.266944
-v -0.764608 0.555570 0.314536
-v -0.849984 0.382683 0.349899
-v -0.902558 0.195090 0.371676
-v -0.920310 0.000000 0.379030
-v -0.902558 -0.195090 0.371676
-v -0.849984 -0.382683 0.349899
-v -0.764608 -0.555570 0.314536
-v -0.649712 -0.707107 0.266944
-v -0.509711 -0.831470 0.208954
-v -0.349984 -0.923880 0.142793
-v -0.176671 -0.980785 0.071004
-v -0.191521 0.980785 -0.003654
-v -0.670833 1.424588 -0.130514
-v -0.552001 0.831470 -0.003654
-v -0.703537 0.707107 -0.003654
-v -0.827900 0.555570 -0.003654
-v -0.920310 0.382683 -0.003654
-v -0.977216 0.195090 -0.003654
-v -0.996431 0.000000 -0.003654
-v -0.977216 -0.195090 -0.003654
-v -0.920310 -0.382683 -0.003654
-v -0.827900 -0.555570 -0.003654
-v -0.703537 -0.707107 -0.003654
-v -0.552001 -0.831470 -0.003654
-v -0.379114 -0.923880 -0.003654
-v -0.191521 -0.980785 -0.003653
-v -0.176671 0.980785 -0.078311
-v -0.349984 0.923880 -0.150100
-v -0.509711 0.831470 -0.216261
-v -0.649712 0.707107 -0.274252
-v -0.764608 0.555570 -0.321844
-v -0.849984 0.382683 -0.357207
-v -0.902558 0.195090 -0.378984
-v -0.920310 0.000000 -0.386338
-v -0.902558 -0.195090 -0.378984
-v -0.849984 -0.382683 -0.357207
-v -0.764608 -0.555570 -0.321844
-v -0.649712 -0.707107 -0.274252
-v -0.509711 -0.831470 -0.216261
-v -0.349984 -0.923880 -0.150100
-v -0.176670 -0.980785 -0.078311
-v -0.004740 0.946694 -0.042452
-v -0.134380 0.980785 -0.141603
-v -0.267029 0.923880 -0.274252
-v -0.389278 0.831470 -0.396501
-v -0.496430 0.707107 -0.503654
-v -0.584368 0.555570 -0.591592
-v -0.649712 0.382683 -0.656935
-v -0.689950 0.195090 -0.697174
-v -0.703537 0.000000 -0.710761
-v -0.689950 -0.195090 -0.697174
-v -0.649711 -0.382683 -0.656935
-v -0.584368 -0.555570 -0.591592
-v -0.496430 -0.707107 -0.503654
-v -0.389278 -0.831470 -0.396501
-v -0.267029 -0.923880 -0.274252
-v -0.134380 -0.980785 -0.141603
-v -0.071088 0.980785 -0.183894
-v -0.142877 0.923880 -0.357207
-v -0.209038 0.831470 -0.516934
-v -0.267028 0.707107 -0.656935
-v -0.314620 0.555570 -0.771831
-v -0.349983 0.382683 -0.857207
-v -0.371760 0.195090 -0.909781
-v -0.379113 0.000000 -0.927533
-v -0.371760 -0.195090 -0.909781
-v -0.349983 -0.382683 -0.857207
-v -0.314620 -0.555570 -0.771831
-v -0.267028 -0.707107 -0.656935
-v -0.209038 -0.831470 -0.516934
-v -0.142877 -0.923880 -0.357207
-v -0.071088 -0.980785 -0.183893
-vt 0.999851 0.254364
-vt 1.000216 0.316861
-vt 0.947490 0.313317
-vt 1.001430 0.629353
-vt 1.001720 0.691851
-vt 0.931922 0.687175
-vt 0.999311 0.191868
-vt 0.951339 0.251099
-vt 1.001186 0.566854
-vt 0.934881 0.624892
-vt 1.007035 0.941813
-vt 0.425056 0.995097
-vt 0.688036 0.976661
-vt 0.998332 0.129375
-vt 0.957069 0.189020
-vt 1.000962 0.504356
-vt 0.937391 0.562576
-vt 1.003771 0.879336
-vt 0.883350 0.933568
-vt 1.000738 0.441858
-vt 0.939710 0.500246
-vt 1.002681 0.816844
-vt 0.911801 0.873194
-vt 1.000498 0.379359
-vt 0.942029 0.437916
-vt 1.002102 0.754348
-vt 0.922311 0.811468
-vt 0.944536 0.375600
-vt 0.928063 0.749391
-vt 0.967518 0.127291
-vt 0.914370 0.179467
-vt 0.874297 0.548708
-vt 0.793367 0.911832
-vt 0.878776 0.486849
-vt 0.830431 0.854878
-vt 0.883328 0.425001
-vt 0.847177 0.794812
-vt 0.888332 0.363217
-vt 0.857097 0.733741
-vt 0.894325 0.301577
-vt 0.864050 0.672239
-vt 0.902279 0.240220
-vt 0.869538 0.610526
-vt 0.673229 0.952622
-vt 0.840021 0.282844
-vt 0.799196 0.650007
-vt 0.851832 0.222629
-vt 0.806082 0.588829
-vt 0.647674 0.930190
-vt 0.936876 0.120264
-vt 0.870487 0.163782
-vt 0.812241 0.527510
-vt 0.728438 0.886032
-vt 0.818195 0.466151
-vt 0.761780 0.830244
-vt 0.824401 0.404841
-vt 0.779430 0.771193
-vt 0.831401 0.343685
-vt 0.790798 0.710891
-vt 0.764618 0.380134
-vt 0.718010 0.745282
-vt 0.772877 0.319381
-vt 0.728814 0.685077
-vt 0.783442 0.259124
-vt 0.737196 0.624350
-vt 0.798621 0.199874
-vt 0.744340 0.563358
-vt 0.707182 0.860354
-vt 0.906609 0.108594
-vt 0.824112 0.142946
-vt 0.750946 0.502250
-vt 0.757534 0.441139
-vt 0.702334 0.804422
-vt 0.876972 0.092772
-vt 0.772639 0.118425
-vt 0.689719 0.476662
-vt 0.628630 0.839481
-vt 0.696023 0.415406
-vt 0.648446 0.780984
-vt 0.703032 0.354290
-vt 0.660884 0.720963
-vt 0.711521 0.293471
-vt 0.669897 0.660249
-vt 0.722910 0.233237
-vt 0.677174 0.599187
-vt 0.740364 0.174247
-vt 0.683593 0.537954
-vt 0.619392 0.910335
-vt 0.589901 0.893857
-vt 0.656384 0.208905
-vt 0.618155 0.578027
-vt 0.673599 0.149088
-vt 0.623041 0.516276
-vt 0.559721 0.881431
-vt 0.848420 0.073445
-vt 0.710510 0.092518
-vt 0.654100 0.398336
-vt 0.584434 0.822825
-vt 0.597641 0.762372
-vt 0.638711 0.331180
-vt 0.615729 0.669357
-vt 0.646031 0.269806
-vt 0.571320 0.314734
-vt 0.606283 0.701204
-vt 0.552981 0.688148
-vt 0.575821 0.252624
-vt 0.551486 0.628681
-vt 0.582490 0.190702
-vt 0.562178 0.501443
-vt 0.594534 0.129251
-vt 0.627829 0.454510
-vt 0.529129 0.873575
-vt 0.822173 0.051396
-vt 0.626046 0.069542
-vt 0.568416 0.404557
-vt 0.541593 0.812161
-vt 0.548412 0.750252
-vt 0.498332 0.870625
-vt 0.803855 0.027548
-vt 0.507034 0.058187
-vt 0.564908 0.439180
-vt 0.501186 0.433146
-vt 0.499311 0.808132
-vt 0.501720 0.308149
-vt 0.499851 0.745636
-vt 0.500216 0.683139
-vt 0.502102 0.245652
-vt 0.548785 0.563632
-vt 0.500498 0.620641
-vt 0.502681 0.183156
-vt 0.500213 0.480106
-vt 0.503771 0.120664
-vt 0.500833 0.511381
-vt 0.450277 0.630514
-vt 0.411801 0.126807
-vt 0.439710 0.499754
-vt 0.383351 0.066432
-vt 0.437391 0.437424
-vt 0.457069 0.810979
-vt 0.925055 0.004903
-vt 1.188037 0.023339
-vt 0.500933 0.465124
-vt 0.433581 0.399732
-vt 0.451339 0.748901
-vt 0.431922 0.312826
-vt 0.447490 0.686683
-vt 0.428063 0.250609
-vt 0.422311 0.188532
-vt 0.351556 0.393216
-vt 0.394325 0.698423
-vt 0.357098 0.266259
-vt 0.347177 0.205188
-vt 0.454645 0.567651
-vt 0.385200 0.656262
-vt 0.330431 0.145123
-vt 0.378776 0.513151
-vt 0.293367 0.088168
-vt 0.374297 0.451292
-vt 0.467518 0.872709
-vt 0.414370 0.820533
-vt 0.188037 0.023339
-vt 0.173229 0.047378
-vt 0.402279 0.759780
-vt 0.228438 0.113968
-vt 0.312241 0.472490
-vt 0.436876 0.879736
-vt 0.370488 0.836218
-vt 0.147674 0.069810
-vt 0.306082 0.411171
-vt 0.351833 0.777370
-vt 0.364050 0.327761
-vt 0.340021 0.717156
-vt 0.290798 0.289109
-vt 0.331401 0.656315
-vt 0.279430 0.228807
-vt 0.383329 0.574999
-vt 0.261780 0.169756
-vt 0.318195 0.533849
-vt 0.218010 0.254718
-vt 0.324402 0.595159
-vt 0.264618 0.619866
-vt 0.202334 0.195578
-vt 0.257534 0.558861
-vt 0.175646 0.138926
-vt 0.250946 0.497750
-vt 0.406609 0.891406
-vt 0.376972 0.907228
-vt 0.119392 0.089665
-vt 0.244340 0.436642
-vt 0.298621 0.800125
-vt 0.299196 0.349993
-vt 0.237196 0.375650
-vt 0.283443 0.740876
-vt 0.228814 0.314923
-vt 0.272877 0.680619
-vt 0.177174 0.400813
-vt 0.222910 0.766763
-vt 0.169898 0.339751
-vt 0.211521 0.706529
-vt 0.160884 0.279037
-vt 0.203032 0.645710
-vt 0.148446 0.219016
-vt 0.128630 0.160519
-vt 0.189719 0.523338
-vt 0.290338 0.852691
-vt 0.272639 0.881575
-vt 0.089901 0.106143
-vt 0.183593 0.462046
-vt 0.084435 0.177175
-vt 0.196023 0.584594
-vt 0.127829 0.545490
-vt 0.348421 0.926554
-vt 0.210511 0.907482
-vt 0.059721 0.118569
-vt 0.123041 0.483724
-vt 0.240365 0.825753
-vt 0.173599 0.850912
-vt 0.118155 0.421973
-vt 0.156384 0.791095
-vt 0.112765 0.360300
-vt 0.146031 0.730194
-vt 0.106283 0.298796
-vt 0.138711 0.668820
-vt 0.097641 0.237628
-vt 0.132896 0.607213
-vt 0.052981 0.311852
-vt 0.071320 0.685266
-vt 0.048412 0.249748
-vt 0.067856 0.623066
-vt 0.041593 0.187839
-vt 0.064908 0.560821
-vt 0.322173 0.948604
-vt 0.126046 0.930458
-vt 0.029129 0.126425
-vt 0.062178 0.498557
-vt 0.094534 0.870749
-vt 0.059443 0.436293
-vt 0.082490 0.809298
-vt 0.056480 0.374049
-vt 0.075821 0.747376
-vt 0.486102 0.945947
-vt 0.995670 0.066893
-vt 1.173229 0.047378
-vt 1.147674 0.069810
-vt 1.119392 0.089665
-vt 1.089901 0.106143
-vt 1.059721 0.118569
-vt 0.303856 0.972452
-vt 1.029129 0.126425
-vt 0.000738 0.441858
-vt 0.002681 0.816844
-vt 0.002103 0.754348
-vt 0.000498 0.379359
-vt 0.001720 0.691851
-vt 1.048412 0.249748
-vt 1.052981 0.311852
-vt 0.001430 0.629353
-vt 1.041593 0.187839
-vt 0.001186 0.566854
-vt 0.007035 0.941813
-vt 0.000962 0.504356
-vt 0.003771 0.879336
-vt 1.383351 0.066432
-vt 0.000216 0.316861
-vn 0.000000 -0.825831 -0.563891
-vn 0.000000 -0.701041 -0.713095
-vn 0.272866 -0.701041 -0.658803
-vn 0.000000 0.192785 -0.981231
-vn 0.000000 0.378430 -0.925596
-vn 0.354198 0.378430 -0.855159
-vn 0.000000 -0.919523 -0.393017
-vn 0.215796 -0.825831 -0.520981
-vn 0.000000 0.000000 -1.000000
-vn 0.375500 0.192785 -0.906522
-vn 0.000000 0.919523 -0.393017
-vn -0.000519 0.997436 -0.071200
-vn 0.027406 0.997192 -0.069613
-vn 0.000000 -0.978362 -0.206793
-vn 0.150395 -0.919523 -0.363109
-vn 0.000000 -0.192785 -0.981231
-vn 0.382672 0.000000 -0.923856
-vn 0.000000 0.825831 -0.563891
-vn 0.150395 0.919523 -0.363109
-vn 0.000000 -0.378430 -0.925596
-vn 0.375500 -0.192785 -0.906522
-vn 0.000000 0.701041 -0.713095
-vn 0.215796 0.825831 -0.520981
-vn 0.000000 -0.550005 -0.835139
-vn 0.354198 -0.378430 -0.855159
-vn 0.000000 0.550005 -0.835139
-vn 0.272866 0.701041 -0.658803
-vn 0.319590 -0.550005 -0.771569
-vn 0.319590 0.550005 -0.771569
-vn 0.079134 -0.978362 -0.191046
-vn 0.277902 -0.919523 -0.277902
-vn 0.707083 0.000000 -0.707083
-vn 0.277902 0.919523 -0.277902
-vn 0.693838 -0.192785 -0.693838
-vn 0.398724 0.825831 -0.398724
-vn 0.654500 -0.378430 -0.654500
-vn 0.504227 0.701041 -0.504227
-vn 0.590533 -0.550005 -0.590533
-vn 0.590533 0.550005 -0.590533
-vn 0.504227 -0.701041 -0.504227
-vn 0.654500 0.378430 -0.654500
-vn 0.398724 -0.825831 -0.398724
-vn 0.693838 0.192785 -0.693838
-vn 0.055757 0.996734 -0.058199
-vn 0.658803 -0.701041 -0.272866
-vn 0.855159 0.378430 -0.354198
-vn 0.520981 -0.825831 -0.215796
-vn 0.906522 0.192785 -0.375500
-vn -0.236305 0.959014 -0.156285
-vn 0.146214 -0.978362 -0.146214
-vn 0.363109 -0.919523 -0.150395
-vn 0.923856 0.000000 -0.382672
-vn 0.011261 0.683889 -0.729453
-vn 0.906522 -0.192785 -0.375500
-vn 0.605701 0.653768 -0.453536
-vn 0.855159 -0.378430 -0.354198
-vn 0.658803 0.701041 -0.272866
-vn 0.771569 -0.550005 -0.319590
-vn 0.771569 0.550005 -0.319590
-vn 0.925596 -0.378430 0.000000
-vn 0.713095 0.701041 0.000000
-vn 0.835139 -0.550005 0.000000
-vn 0.835139 0.550005 0.000000
-vn 0.713095 -0.701041 0.000000
-vn 0.925596 0.378430 0.000000
-vn 0.563891 -0.825831 0.000000
-vn 0.981231 0.192785 0.000000
-vn 0.457015 0.878414 -0.139592
-vn 0.191046 -0.978362 -0.079134
-vn 0.393017 -0.919523 0.000000
-vn 1.000000 0.000000 0.000000
-vn 0.981231 -0.192785 0.000000
-vn 0.826655 0.536607 0.169225
-vn 0.206793 -0.978362 0.000000
-vn 0.363109 -0.919523 0.150395
-vn 0.918363 -0.013153 0.395428
-vn 0.332072 0.776086 0.536058
-vn 0.887234 -0.192480 0.419202
-vn 0.520981 0.825831 0.215796
-vn 0.853755 -0.365734 0.370556
-vn 0.661458 0.653645 0.367626
-vn 0.771569 -0.550005 0.319590
-vn 0.697836 0.595203 0.398389
-vn 0.658803 -0.701041 0.272866
-vn 0.855159 0.378430 0.354198
-vn 0.520981 -0.825831 0.215796
-vn 0.906522 0.192785 0.375500
-vn -0.493942 0.869381 -0.011963
-vn -0.170476 0.970946 0.167882
-vn 0.504227 -0.701041 0.504227
-vn 0.585894 0.507614 0.631642
-vn 0.398724 -0.825831 0.398724
-vn 0.693838 0.192785 0.693838
-vn 0.071383 0.994934 0.070467
-vn 0.191046 -0.978362 0.079134
-vn 0.277902 -0.919523 0.277902
-vn 0.742882 -0.188543 0.642293
-vn 0.277902 0.919523 0.277902
-vn 0.398724 0.825831 0.398724
-vn 0.673086 -0.270486 0.688314
-vn 0.604236 0.484725 0.632374
-vn 0.590533 -0.550005 0.590533
-vn 0.363536 -0.292184 0.884548
-vn 0.652760 0.351756 0.670919
-vn 0.377728 0.636097 0.672811
-vn 0.319590 -0.550005 0.771569
-vn 0.382183 0.480911 0.789056
-vn 0.272866 -0.701041 0.658803
-vn 0.561907 0.233131 0.793634
-vn 0.215796 -0.825831 0.520981
-vn 0.683676 -0.129032 0.718253
-vn 0.039155 0.994781 0.093997
-vn 0.146214 -0.978362 0.146214
-vn 0.150395 -0.919523 0.363109
-vn 0.489853 -0.255684 0.833430
-vn 0.150395 0.919523 0.363109
-vn 0.215796 0.825831 0.520981
-vn -0.000214 0.994781 0.101779
-vn 0.079134 -0.978362 0.191046
-vn 0.000000 -0.919523 0.393017
-vn 0.373913 -0.143284 0.916318
-vn 0.483200 0.406323 0.775475
-vn 0.000000 0.919523 0.393017
-vn 0.090335 -0.566515 0.819056
-vn 0.000000 0.825831 0.563891
-vn 0.001495 0.700217 0.713889
-vn 0.000000 -0.550005 0.835139
-vn 0.503006 0.524033 0.687246
-vn 0.164159 0.810419 0.562334
-vn 0.000000 -0.701041 0.713095
-vn 0.058321 -0.465743 0.882962
-vn 0.000000 -0.825831 0.563891
-vn 0.073977 0.415296 0.906644
-vn -0.589007 0.456130 0.667043
-vn -0.215796 -0.825831 0.520981
-vn -0.704520 0.368694 0.606342
-vn -0.150395 -0.919523 0.363109
-vn -0.530290 -0.262947 0.805994
-vn -0.150395 0.919523 0.363109
-vn 0.000000 -0.978362 0.206793
-vn -0.079134 -0.978362 0.191046
-vn 0.049959 0.476424 0.877773
-vn -0.661336 -0.128391 0.738975
-vn -0.215796 0.825831 0.520981
-vn -0.469863 -0.393567 0.790124
-vn -0.287149 0.689108 0.665304
-vn -0.319590 -0.550005 0.771569
-vn -0.272866 -0.701041 0.658803
-vn -0.673421 -0.193152 0.713553
-vn -0.604236 0.498520 0.621540
-vn -0.590533 -0.550005 0.590533
-vn -0.504227 -0.701041 0.504227
-vn -0.768883 0.370861 0.520829
-vn -0.544877 0.410474 0.731132
-vn -0.398724 -0.825831 0.398724
-vn -0.666066 0.221381 0.712241
-vn -0.277902 -0.919523 0.277902
-vn -0.671102 -0.151128 0.725761
-vn -0.038942 0.994964 0.092257
-vn -0.277902 0.919523 0.277902
-vn -0.146214 -0.978362 0.146214
-vn -0.398724 0.825831 0.398724
-vn -0.363109 -0.919523 0.150395
-vn -0.923856 0.000000 0.382672
-vn -0.069369 0.995270 0.067782
-vn -0.291696 0.836390 0.464003
-vn -0.191046 -0.978362 0.079134
-vn -0.897244 -0.193762 0.396680
-vn -0.520981 0.825831 0.215796
-vn -0.655873 -0.216712 0.723075
-vn -0.658803 0.701041 0.272866
-vn -0.771569 -0.550005 0.319590
-vn -0.740257 0.558123 0.374828
-vn -0.658803 -0.701041 0.272866
-vn -0.502091 0.528520 0.684500
-vn -0.520981 -0.825831 0.215796
-vn -0.906522 0.192785 0.375500
-vn -0.713095 -0.701041 0.000000
-vn -0.855159 0.378430 0.354198
-vn -0.925596 0.378430 0.000000
-vn -0.563891 -0.825831 0.000000
-vn -0.981231 0.192785 0.000000
-vn -0.393017 -0.919523 0.000000
-vn -1.000000 0.000000 0.000000
-vn -0.085879 0.995697 0.033967
-vn 0.169530 0.985382 0.015473
-vn -0.206793 -0.978362 0.000000
-vn -0.981231 -0.192785 0.000000
-vn -0.759606 0.649922 0.023621
-vn -0.855159 -0.378430 0.354198
-vn -0.925596 -0.378430 0.000000
-vn -0.713095 0.701041 0.000000
-vn -0.835139 -0.550005 0.000000
-vn -0.835139 0.550005 0.000000
-vn -0.855159 -0.378430 -0.354198
-vn -0.658803 0.701041 -0.272866
-vn -0.771569 -0.550005 -0.319590
-vn -0.771569 0.550005 -0.319590
-vn -0.658803 -0.701041 -0.272866
-vn -0.855159 0.378430 -0.354198
-vn -0.520981 -0.825831 -0.215796
-vn -0.363109 -0.919523 -0.150395
-vn -0.923856 0.000000 -0.382672
-vn -0.495224 0.845058 -0.201483
-vn -0.237465 0.770379 -0.591693
-vn -0.191046 -0.978362 -0.079134
-vn -0.906522 -0.192785 -0.375500
-vn -0.277902 -0.919523 -0.277902
-vn -0.906522 0.192785 -0.375500
-vn -0.707083 0.000000 -0.707083
-vn -0.073366 0.996765 -0.032228
-vn -0.277902 0.919523 -0.277902
-vn -0.146214 -0.978362 -0.146214
-vn -0.693838 -0.192785 -0.693838
-vn -0.520981 0.825831 -0.215796
-vn -0.398724 0.825831 -0.398724
-vn -0.654500 -0.378430 -0.654500
-vn -0.504227 0.701041 -0.504227
-vn -0.590533 -0.550005 -0.590533
-vn -0.590533 0.550005 -0.590533
-vn -0.504227 -0.701041 -0.504227
-vn -0.654500 0.378430 -0.654500
-vn -0.398724 -0.825831 -0.398724
-vn -0.693838 0.192785 -0.693838
-vn -0.272866 -0.701041 -0.658803
-vn -0.354198 0.378430 -0.855159
-vn -0.215796 -0.825831 -0.520981
-vn -0.375500 0.192785 -0.906522
-vn -0.150395 -0.919523 -0.363109
-vn -0.382672 0.000000 -0.923856
-vn -0.051729 0.997223 -0.053529
-vn -0.150395 0.919523 -0.363109
-vn -0.079134 -0.978362 -0.191046
-vn -0.375500 -0.192785 -0.906522
-vn -0.215796 0.825831 -0.520981
-vn -0.354198 -0.378430 -0.855159
-vn -0.272866 0.701041 -0.658803
-vn -0.319590 -0.550005 -0.771569
-vn -0.319590 0.550005 -0.771569
-vn 0.007691 0.999298 0.035981
-vn 0.000000 -0.999969 0.000000
-vn -0.026765 0.997467 -0.065828
-s 1
-f 13/1/1 12/2/2 27/3/3
-f 7/4/4 6/5/5 21/6/6
-f 14/7/7 13/1/1 28/8/8
-f 8/9/9 7/4/4 22/10/10
-f 2/11/11 1/12/12 16/13/13
-f 15/14/14 14/7/7 29/15/15
-f 9/16/16 8/9/9 23/17/17
-f 3/18/18 2/11/11 17/19/19
-f 10/20/20 9/16/16 24/21/21
-f 4/22/22 3/18/18 18/23/23
-f 11/24/24 10/20/20 25/25/25
-f 5/26/26 4/22/22 19/27/27
-f 12/2/2 11/24/24 26/28/28
-f 6/5/5 5/26/26 20/29/29
-f 30/30/30 29/15/15 45/31/31
-f 24/21/21 23/17/17 39/32/32
-f 18/23/23 17/19/19 33/33/33
-f 25/25/25 24/21/21 40/34/34
-f 19/27/27 18/23/23 34/35/35
-f 26/28/28 25/25/25 41/36/36
-f 20/29/29 19/27/27 35/37/37
-f 27/3/3 26/28/28 42/38/38
-f 21/6/6 20/29/29 36/39/39
-f 28/8/8 27/3/3 43/40/40
-f 22/10/10 21/6/6 37/41/41
-f 29/15/15 28/8/8 44/42/42
-f 23/17/17 22/10/10 38/43/43
-f 17/19/19 16/13/13 32/44/44
-f 44/42/42 43/40/40 58/45/45
-f 38/43/43 37/41/41 52/46/46
-f 45/31/31 44/42/42 59/47/47
-f 39/32/32 38/43/43 53/48/48
-f 33/33/33 32/44/44 47/49/49
-f 46/50/50 45/31/31 60/51/51
-f 40/34/34 39/32/32 54/52/52
-f 34/35/35 33/33/33 48/53/53
-f 41/36/36 40/34/34 55/54/54
-f 35/37/37 34/35/35 49/55/55
-f 42/38/38 41/36/36 56/56/56
-f 36/39/39 35/37/37 50/57/57
-f 43/40/40 42/38/38 57/58/58
-f 37/41/41 36/39/39 51/59/59
-f 57/58/58 56/56/56 71/60/60
-f 51/59/59 50/57/57 65/61/61
-f 58/45/45 57/58/58 72/62/62
-f 52/46/46 51/59/59 66/63/63
-f 59/47/47 58/45/45 73/64/64
-f 53/48/48 52/46/46 67/65/65
-f 60/51/51 59/47/47 74/66/66
-f 54/52/52 53/48/48 68/67/67
-f 48/53/53 47/49/49 63/68/68
-f 61/69/69 60/51/51 75/70/70
-f 55/54/54 54/52/52 69/71/71
-f 49/55/55 48/53/53 63/68/68
-f 56/56/56 55/54/54 70/72/72
-f 50/57/57 49/55/55 64/73/73
-f 76/74/74 75/70/70 90/75/75
-f 70/72/72 69/71/71 84/76/76
-f 64/73/73 63/68/68 78/77/77
-f 71/60/60 70/72/72 85/78/78
-f 65/61/61 64/73/73 79/79/79
-f 72/62/62 71/60/60 86/80/80
-f 66/63/63 65/61/61 80/81/81
-f 73/64/64 72/62/62 87/82/82
-f 67/65/65 66/63/63 81/83/83
-f 74/66/66 73/64/64 88/84/84
-f 68/67/67 67/65/65 82/85/85
-f 75/70/70 74/66/66 89/86/86
-f 69/71/71 68/67/67 83/87/87
-f 63/68/68 62/88/88 77/89/89
-f 89/86/86 88/84/84 103/90/90
-f 83/87/87 82/85/85 97/91/91
-f 90/75/75 89/86/86 104/92/92
-f 84/76/76 83/87/87 98/93/93
-f 78/77/77 77/89/89 92/94/94
-f 91/95/95 90/75/75 105/96/96
-f 85/78/78 84/76/76 100/97/97
-f 79/79/79 78/77/77 93/98/98
-f 86/80/80 85/78/78 100/97/97
-f 80/81/81 79/79/79 94/99/99
-f 87/82/82 86/80/80 101/100/100
-f 81/83/83 80/81/81 96/101/101
-f 88/84/84 87/82/82 102/102/102
-f 82/85/85 81/83/83 97/91/91
-f 102/102/102 101/100/100 116/103/103
-f 96/101/101 95/104/104 110/105/105
-f 103/90/90 102/102/102 117/106/106
-f 97/91/91 96/101/101 111/107/107
-f 104/92/92 103/90/90 118/108/108
-f 98/93/93 97/91/91 113/109/109
-f 105/96/96 104/92/92 119/110/110
-f 99/111/111 98/93/93 113/109/109
-f 93/98/98 92/94/94 107/112/112
-f 106/113/113 105/96/96 120/114/114
-f 100/97/97 99/111/111 115/115/115
-f 94/99/99 93/98/98 108/116/116
-f 101/100/100 100/97/97 115/115/115
-f 95/104/104 94/99/99 109/117/117
-f 108/116/116 107/112/112 122/118/118
-f 121/119/119 120/114/114 135/120/120
-f 115/115/115 114/121/121 129/122/122
-f 109/117/117 108/116/116 123/123/123
-f 116/103/103 115/115/115 131/124/124
-f 110/105/105 109/117/117 124/125/125
-f 117/106/106 116/103/103 131/124/124
-f 111/107/107 110/105/105 125/126/126
-f 118/108/108 117/106/106 132/127/127
-f 112/128/128 111/107/107 126/129/129
-f 119/110/110 118/108/108 133/130/130
-f 113/109/109 112/128/128 128/131/131
-f 120/114/114 119/110/110 134/132/132
-f 114/121/121 113/109/109 129/122/122
-f 127/133/133 126/129/129 141/134/134
-f 134/132/132 133/130/130 149/135/135
-f 128/131/131 127/133/133 143/136/136
-f 135/120/120 134/132/132 150/137/137
-f 129/122/122 128/131/131 144/138/138
-f 123/123/123 122/118/118 138/139/139
-f 136/140/140 135/120/120 151/141/141
-f 130/142/142 129/122/122 145/143/143
-f 124/125/125 123/123/123 139/144/144
-f 131/124/124 130/142/142 146/145/145
-f 125/126/126 124/125/125 140/146/146
-f 132/127/127 131/124/124 147/147/147
-f 126/129/129 125/126/126 140/146/146
-f 133/130/130 132/127/127 148/148/148
-f 146/145/145 145/143/143 160/149/149
-f 140/146/146 139/144/144 155/150/150
-f 147/147/147 146/145/145 162/151/151
-f 141/134/134 140/146/146 155/150/150
-f 148/148/148 147/147/147 163/152/152
-f 142/153/153 141/134/134 156/154/154
-f 149/135/135 148/148/148 164/155/155
-f 143/136/136 142/153/153 158/156/156
-f 150/137/137 149/135/135 165/157/157
-f 144/138/138 143/136/136 159/158/158
-f 138/139/139 137/159/159 153/160/160
-f 151/161/141 150/137/137 166/162/161
-f 145/143/143 144/138/138 160/149/149
-f 139/144/144 138/139/139 154/163/162
-f 165/157/157 164/155/155 180/164/163
-f 159/158/158 158/156/156 174/165/164
-f 153/160/160 152/166/165 168/167/166
-f 166/162/161 165/157/157 181/168/167
-f 160/149/149 159/158/158 175/169/168
-f 154/163/162 153/160/160 169/170/169
-f 161/171/170 160/149/149 175/169/168
-f 155/150/150 154/163/162 170/172/171
-f 162/151/151 161/171/170 177/173/172
-f 156/154/154 155/150/150 171/174/173
-f 163/152/152 162/151/151 178/175/174
-f 157/176/175 156/154/154 171/174/173
-f 164/155/155 163/152/152 179/177/176
-f 158/156/156 157/176/175 173/178/177
-f 178/175/174 177/173/172 193/179/178
-f 172/180/179 171/174/173 187/181/180
-f 179/177/176 178/175/174 194/182/181
-f 173/178/177 172/180/179 188/183/182
-f 180/164/163 179/177/176 195/184/183
-f 174/165/164 173/178/177 189/185/184
-f 168/167/166 167/186/185 182/187/186
-f 181/168/167 180/164/163 196/188/187
-f 175/169/168 174/165/164 190/189/188
-f 169/170/169 168/167/166 184/190/189
-f 176/191/190 175/169/168 191/192/191
-f 170/172/171 169/170/169 185/193/192
-f 177/173/172 176/191/190 192/194/193
-f 171/174/173 170/172/171 186/195/194
-f 191/192/191 190/189/188 206/196/195
-f 185/193/192 184/190/189 200/197/196
-f 192/194/193 191/192/191 207/198/197
-f 186/195/194 185/193/192 201/199/198
-f 193/179/178 192/194/193 208/200/199
-f 187/181/180 186/195/194 202/201/200
-f 194/182/181 193/179/178 209/202/201
-f 188/183/182 187/181/180 202/201/200
-f 195/184/183 194/182/181 210/203/202
-f 189/185/184 188/183/182 204/204/203
-f 183/205/204 182/187/186 198/206/205
-f 196/188/187 195/184/183 211/207/206
-f 190/189/188 189/185/184 205/208/207
-f 184/190/189 183/205/204 198/206/205
-f 210/203/202 209/202/201 226/209/208
-f 204/204/203 203/210/209 220/211/210
-f 198/206/205 197/212/211 214/213/212
-f 211/207/206 210/203/202 227/214/213
-f 205/208/207 204/204/203 221/215/214
-f 199/216/215 198/206/205 215/217/216
-f 206/196/195 205/208/207 222/218/217
-f 200/197/196 199/216/215 216/219/218
-f 207/198/197 206/196/195 223/220/219
-f 201/199/198 200/197/196 217/221/220
-f 208/200/199 207/198/197 224/222/221
-f 202/201/200 201/199/198 218/223/222
-f 209/202/201 208/200/199 225/224/223
-f 203/210/209 202/201/200 219/225/224
-f 224/222/221 223/220/219 239/226/225
-f 218/223/222 217/221/220 233/227/226
-f 225/224/223 224/222/221 240/228/227
-f 219/225/224 218/223/222 234/229/228
-f 226/209/208 225/224/223 241/230/229
-f 220/211/210 219/225/224 235/231/230
-f 214/213/212 213/232/231 229/233/232
-f 227/214/213 226/209/208 242/234/233
-f 221/215/214 220/211/210 236/235/234
-f 215/217/216 214/213/212 230/236/235
-f 222/218/217 221/215/214 237/237/236
-f 216/219/218 215/217/216 231/238/237
-f 223/220/219 222/218/217 238/239/238
-f 217/221/220 216/219/218 232/240/239
-f 1/12/12 212/241/240 16/13/13
-f 31/242/241 15/14/14 30/30/30
-f 31/242/241 30/30/30 46/50/50
-f 16/13/13 212/241/240 32/44/44
-f 32/44/44 212/241/240 47/49/49
-f 31/242/241 46/50/50 61/69/69
-f 47/49/49 212/241/240 62/88/88
-f 31/242/241 61/69/69 76/74/74
-f 31/242/241 76/74/74 91/95/95
-f 62/88/88 212/241/240 77/89/89
-f 77/89/89 212/241/240 92/94/94
-f 31/242/241 91/95/95 106/113/113
-f 92/94/94 212/241/240 107/112/112
-f 31/242/241 106/113/113 121/119/119
-f 31/242/241 121/119/119 136/140/140
-f 107/112/112 212/241/240 122/118/118
-f 122/118/118 212/241/240 137/159/159
-f 31/242/241 136/140/140 151/141/141
-f 137/159/159 212/241/240 152/166/165
-f 31/242/241 151/141/141 166/243/161
-f 31/242/241 166/243/161 181/244/167
-f 152/166/165 212/241/240 167/186/185
-f 167/186/185 212/241/240 182/187/186
-f 31/242/241 181/244/167 196/245/187
-f 31/242/241 196/245/187 211/246/206
-f 182/187/186 212/241/240 197/212/211
-f 31/242/241 211/246/206 227/247/213
-f 197/212/211 212/241/240 213/232/231
-f 213/232/231 212/241/240 228/248/242
-f 31/242/241 227/247/213 242/249/233
-f 31/242/241 242/249/233 15/14/14
-f 237/237/236 236/235/234 10/250/20
-f 231/238/237 230/236/235 4/251/22
-f 238/239/238 237/237/236 10/250/20
-f 232/240/239 231/238/237 5/252/26
-f 239/226/225 238/239/238 11/253/24
-f 233/227/226 232/240/239 6/254/5
-f 240/255/227 239/256/225 13/1/1
-f 234/229/228 233/227/226 7/257/4
-f 228/248/242 212/241/240 1/12/12
-f 241/258/229 240/255/227 14/7/7
-f 235/231/230 234/229/228 8/259/9
-f 229/233/232 228/248/242 2/260/11
-f 242/249/233 241/258/229 15/14/14
-f 236/235/234 235/231/230 9/261/16
-f 230/236/235 229/233/232 3/262/18
-f 28/8/8 13/1/1 27/3/3
-f 22/10/10 7/4/4 21/6/6
-f 29/15/15 14/7/7 28/8/8
-f 23/17/17 8/9/9 22/10/10
-f 17/19/19 2/11/11 16/13/13
-f 30/30/30 15/14/14 29/15/15
-f 24/21/21 9/16/16 23/17/17
-f 18/23/23 3/18/18 17/19/19
-f 25/25/25 10/20/20 24/21/21
-f 19/27/27 4/22/22 18/23/23
-f 26/28/28 11/24/24 25/25/25
-f 20/29/29 5/26/26 19/27/27
-f 27/3/3 12/2/2 26/28/28
-f 21/6/6 6/5/5 20/29/29
-f 46/50/50 30/30/30 45/31/31
-f 40/34/34 24/21/21 39/32/32
-f 34/35/35 18/23/23 33/33/33
-f 41/36/36 25/25/25 40/34/34
-f 35/37/37 19/27/27 34/35/35
-f 42/38/38 26/28/28 41/36/36
-f 36/39/39 20/29/29 35/37/37
-f 43/40/40 27/3/3 42/38/38
-f 37/41/41 21/6/6 36/39/39
-f 44/42/42 28/8/8 43/40/40
-f 38/43/43 22/10/10 37/41/41
-f 45/31/31 29/15/15 44/42/42
-f 39/32/32 23/17/17 38/43/43
-f 33/33/33 17/19/19 32/44/44
-f 59/47/47 44/42/42 58/45/45
-f 53/48/48 38/43/43 52/46/46
-f 60/51/51 45/31/31 59/47/47
-f 54/52/52 39/32/32 53/48/48
-f 48/53/53 33/33/33 47/49/49
-f 61/69/69 46/50/50 60/51/51
-f 55/54/54 40/34/34 54/52/52
-f 49/55/55 34/35/35 48/53/53
-f 56/56/56 41/36/36 55/54/54
-f 50/57/57 35/37/37 49/55/55
-f 57/58/58 42/38/38 56/56/56
-f 51/59/59 36/39/39 50/57/57
-f 58/45/45 43/40/40 57/58/58
-f 52/46/46 37/41/41 51/59/59
-f 72/62/62 57/58/58 71/60/60
-f 66/63/63 51/59/59 65/61/61
-f 73/64/64 58/45/45 72/62/62
-f 67/65/65 52/46/46 66/63/63
-f 74/66/66 59/47/47 73/64/64
-f 68/67/67 53/48/48 67/65/65
-f 75/70/70 60/51/51 74/66/66
-f 69/71/71 54/52/52 68/67/67
-f 47/49/49 62/88/88 63/68/68
-f 76/74/74 61/69/69 75/70/70
-f 70/72/72 55/54/54 69/71/71
-f 64/73/73 49/55/55 63/68/68
-f 71/60/60 56/56/56 70/72/72
-f 65/61/61 50/57/57 64/73/73
-f 91/95/95 76/74/74 90/75/75
-f 85/78/78 70/72/72 84/76/76
-f 79/79/79 64/73/73 78/77/77
-f 86/80/80 71/60/60 85/78/78
-f 80/81/81 65/61/61 79/79/79
-f 87/82/82 72/62/62 86/80/80
-f 81/83/83 66/63/63 80/81/81
-f 88/84/84 73/64/64 87/82/82
-f 82/85/85 67/65/65 81/83/83
-f 89/86/86 74/66/66 88/84/84
-f 83/87/87 68/67/67 82/85/85
-f 90/75/75 75/70/70 89/86/86
-f 84/76/76 69/71/71 83/87/87
-f 78/77/77 63/68/68 77/89/89
-f 104/92/92 89/86/86 103/90/90
-f 98/93/93 83/87/87 97/91/91
-f 105/96/96 90/75/75 104/92/92
-f 99/111/111 84/76/76 98/93/93
-f 93/98/98 78/77/77 92/94/94
-f 106/113/113 91/95/95 105/96/96
-f 84/76/76 99/111/111 100/97/97
-f 94/99/99 79/79/79 93/98/98
-f 101/100/100 86/80/80 100/97/97
-f 95/104/104 80/81/81 94/99/99
-f 102/102/102 87/82/82 101/100/100
-f 80/81/81 95/104/104 96/101/101
-f 103/90/90 88/84/84 102/102/102
-f 81/83/83 96/101/101 97/91/91
-f 117/106/106 102/102/102 116/103/103
-f 111/107/107 96/101/101 110/105/105
-f 118/108/108 103/90/90 117/106/106
-f 112/128/128 97/91/91 111/107/107
-f 119/110/110 104/92/92 118/108/108
-f 97/91/91 112/128/128 113/109/109
-f 120/114/114 105/96/96 119/110/110
-f 114/121/121 99/111/111 113/109/109
-f 108/116/116 93/98/98 107/112/112
-f 121/119/119 106/113/113 120/114/114
-f 99/111/111 114/121/121 115/115/115
-f 109/117/117 94/99/99 108/116/116
-f 116/103/103 101/100/100 115/115/115
-f 110/105/105 95/104/104 109/117/117
-f 123/123/123 108/116/116 122/118/118
-f 136/140/140 121/119/119 135/120/120
-f 130/142/142 115/115/115 129/122/122
-f 124/125/125 109/117/117 123/123/123
-f 115/115/115 130/142/142 131/124/124
-f 125/126/126 110/105/105 124/125/125
-f 132/127/127 117/106/106 131/124/124
-f 126/129/129 111/107/107 125/126/126
-f 133/130/130 118/108/108 132/127/127
-f 127/133/133 112/128/128 126/129/129
-f 134/132/132 119/110/110 133/130/130
-f 112/128/128 127/133/133 128/131/131
-f 135/120/120 120/114/114 134/132/132
-f 113/109/109 128/131/131 129/122/122
-f 142/153/153 127/133/133 141/134/134
-f 133/130/130 148/148/148 149/135/135
-f 127/133/133 142/153/153 143/136/136
-f 134/132/132 149/135/135 150/137/137
-f 128/131/131 143/136/136 144/138/138
-f 122/118/118 137/159/159 138/139/139
-f 135/120/120 150/263/137 151/141/141
-f 129/122/122 144/138/138 145/143/143
-f 123/123/123 138/139/139 139/144/144
-f 130/142/142 145/143/143 146/145/145
-f 124/125/125 139/144/144 140/146/146
-f 131/124/124 146/145/145 147/147/147
-f 141/134/134 126/129/129 140/146/146
-f 132/127/127 147/147/147 148/148/148
-f 161/171/170 146/145/145 160/149/149
-f 139/144/144 154/163/162 155/150/150
-f 146/145/145 161/171/170 162/151/151
-f 156/154/154 141/134/134 155/150/150
-f 147/147/147 162/151/151 163/152/152
-f 157/176/175 142/153/153 156/154/154
-f 148/148/148 163/152/152 164/155/155
-f 142/153/153 157/176/175 158/156/156
-f 149/135/135 164/155/155 165/157/157
-f 143/136/136 158/156/156 159/158/158
-f 137/159/159 152/166/165 153/160/160
-f 150/137/137 165/157/157 166/162/161
-f 144/138/138 159/158/158 160/149/149
-f 138/139/139 153/160/160 154/163/162
-f 164/155/155 179/177/176 180/164/163
-f 158/156/156 173/178/177 174/165/164
-f 152/166/165 167/186/185 168/167/166
-f 165/157/157 180/164/163 181/168/167
-f 159/158/158 174/165/164 175/169/168
-f 153/160/160 168/167/166 169/170/169
-f 176/191/190 161/171/170 175/169/168
-f 154/163/162 169/170/169 170/172/171
-f 161/171/170 176/191/190 177/173/172
-f 155/150/150 170/172/171 171/174/173
-f 162/151/151 177/173/172 178/175/174
-f 172/180/179 157/176/175 171/174/173
-f 163/152/152 178/175/174 179/177/176
-f 157/176/175 172/180/179 173/178/177
-f 177/173/172 192/194/193 193/179/178
-f 171/174/173 186/195/194 187/181/180
-f 178/175/174 193/179/178 194/182/181
-f 172/180/179 187/181/180 188/183/182
-f 179/177/176 194/182/181 195/184/183
-f 173/178/177 188/183/182 189/185/184
-f 183/205/204 168/167/166 182/187/186
-f 180/164/163 195/184/183 196/188/187
-f 174/165/164 189/185/184 190/189/188
-f 168/167/166 183/205/204 184/190/189
-f 175/169/168 190/189/188 191/192/191
-f 169/170/169 184/190/189 185/193/192
-f 176/191/190 191/192/191 192/194/193
-f 170/172/171 185/193/192 186/195/194
-f 190/189/188 205/208/207 206/196/195
-f 184/190/189 199/216/215 200/197/196
-f 191/192/191 206/196/195 207/198/197
-f 185/193/192 200/197/196 201/199/198
-f 192/194/193 207/198/197 208/200/199
-f 186/195/194 201/199/198 202/201/200
-f 193/179/178 208/200/199 209/202/201
-f 203/210/209 188/183/182 202/201/200
-f 194/182/181 209/202/201 210/203/202
-f 188/183/182 203/210/209 204/204/203
-f 182/187/186 197/212/211 198/206/205
-f 195/184/183 210/203/202 211/207/206
-f 189/185/184 204/204/203 205/208/207
-f 199/216/215 184/190/189 198/206/205
-f 209/202/201 225/224/223 226/209/208
-f 203/210/209 219/225/224 220/211/210
-f 197/212/211 213/232/231 214/213/212
-f 210/203/202 226/209/208 227/214/213
-f 204/204/203 220/211/210 221/215/214
-f 198/206/205 214/213/212 215/217/216
-f 205/208/207 221/215/214 222/218/217
-f 199/216/215 215/217/216 216/219/218
-f 206/196/195 222/218/217 223/220/219
-f 200/197/196 216/219/218 217/221/220
-f 207/198/197 223/220/219 224/222/221
-f 201/199/198 217/221/220 218/223/222
-f 208/200/199 224/222/221 225/224/223
-f 202/201/200 218/223/222 219/225/224
-f 223/220/219 238/239/238 239/226/225
-f 217/221/220 232/240/239 233/227/226
-f 224/222/221 239/226/225 240/228/227
-f 218/223/222 233/227/226 234/229/228
-f 225/224/223 240/228/227 241/230/229
-f 219/225/224 234/229/228 235/231/230
-f 213/232/231 228/248/242 229/233/232
-f 226/209/208 241/230/229 242/234/233
-f 220/211/210 235/231/230 236/235/234
-f 214/213/212 229/233/232 230/236/235
-f 221/215/214 236/235/234 237/237/236
-f 215/217/216 230/236/235 231/238/237
-f 222/218/217 237/237/236 238/239/238
-f 216/219/218 231/238/237 232/240/239
-f 236/235/234 9/261/16 10/250/20
-f 230/236/235 3/262/18 4/251/22
-f 11/253/24 238/239/238 10/250/20
-f 231/238/237 4/251/22 5/252/26
-f 12/264/2 239/226/225 11/253/24
-f 232/240/239 5/252/26 6/254/5
-f 239/256/225 12/2/2 13/1/1
-f 233/227/226 6/254/5 7/257/4
-f 240/255/227 13/1/1 14/7/7
-f 234/229/228 7/257/4 8/259/9
-f 228/248/242 1/12/12 2/260/11
-f 241/258/229 14/7/7 15/14/14
-f 235/231/230 8/259/9 9/261/16
-f 229/233/232 2/260/11 3/262/18
diff --git a/examples/qmlbarchart/qml/qmlbarchart/main.qml b/examples/qmlbarchart/qml/qmlbarchart/main.qml
deleted file mode 100644
index f10f98b9..00000000
--- a/examples/qmlbarchart/qml/qmlbarchart/main.qml
+++ /dev/null
@@ -1,205 +0,0 @@
-/****************************************************************************
-**
-** 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.Window 2.1
-import QtQuick.Controls 1.0
-import com.digia.QtDataVis3D 1.0
-
-Item {
- id: mainview
- width: 800
- height: 600
- visible: true
-
- Item {
- id: dataView
- width: parent.width - tableView.width
- height: parent.height
- anchors.right: parent.right;
-
- 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"]
- }
-
- 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
- }
-
- CategoryAxis {
- id: rowAxis
- categoryLabels: ["2000", "2001", "2002", "2003", "2004"]
- }
- CategoryAxis {
- id: columnAxis
- categoryLabels: ["January", "February", "March", "April", "May", "June",
- "July", "August", "September", "October", "November", "December"]
- }
- 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
- }
- }
-
- 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"
- }
-
- 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
-
- TextArea {
- id: mappingButtonText
- text: "Show Income"
- anchors.fill: parent
- textColor: "#000000"
- }
-
- 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.qrc b/examples/qmlbarchart/qmlbarchart.qrc
deleted file mode 100644
index b96401d5..00000000
--- a/examples/qmlbarchart/qmlbarchart.qrc
+++ /dev/null
@@ -1,5 +0,0 @@
-<RCC>
- <qresource prefix="/qml">
- <file alias="main.qml">qml/qmlbarchart/main.qml</file>
- </qresource>
-</RCC>
diff --git a/examples/qmlbars/doc/images/qmlbars-example.png b/examples/qmlbars/doc/images/qmlbars-example.png
new file mode 100644
index 00000000..b23491e9
--- /dev/null
+++ b/examples/qmlbars/doc/images/qmlbars-example.png
Binary files differ
diff --git a/examples/qmlbars/doc/src/qmlbars.qdoc b/examples/qmlbars/doc/src/qmlbars.qdoc
new file mode 100644
index 00000000..185956ea
--- /dev/null
+++ b/examples/qmlbars/doc/src/qmlbars.qdoc
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 qmlbars
+ \title Qt Quick 2 Bars Example
+ \ingroup qtdatavisualization_examples
+ \brief Using Bars3D in a QML application.
+
+ The Qt Quick 2 bars example shows how to make a simple 3D bar graph using Bars3D and Qt
+ Quick 2.
+
+ \image qmlbars-example.png
+
+ The interesting thing about this example is remapping the data, so we concentrate on that
+ and skip explaining the basic Bars3D functionality - for more detailed QML example documentation,
+ see \l{Qt Quick 2 Scatter Example}.
+
+ \section1 Data
+
+ The example data is monthly income and expenses of a fictional company over several years.
+ The data is defined in a list model in \c data.qml like this:
+
+ \snippet ../examples/qmlbars/qml/qmlbars/data.qml 0
+ \dots 4
+
+ Each data item has four roles: year, month, income, and expenses. Years and months are natural to
+ map to rows and columns of a bar chart, but we can only show either income or expenses as the value.
+ We choose to default to showing expenses when we initialize the mapping item:
+
+ \snippet ../examples/qmlbars/qml/qmlbars/data.qml 1
+
+ Final piece we need for handling data is the proxy to bring the model and mapping together:
+
+ \snippet ../examples/qmlbars/qml/qmlbars/data.qml 2
+
+ \section1 Custom axis labels
+
+ One interesting tidbit about axes is that we redefine the category labels for column axis in
+ \c axes.qml. This is done because the data contains abbreviated month names, which we don't want
+ to use for our column labels:
+
+ \snippet ../examples/qmlbars/qml/qmlbars/axes.qml 0
+
+ \section1 Using mapping
+
+ In the \c main.qml, we set up the graph and various UI elements. There are three interesting
+ mapping related code blocks we want to highlight here. The first one shows how to change the
+ visualized data from expenses to income, and vice versa, by simply changing the value role on the
+ BarDataMapping item:
+
+ \snippet ../examples/qmlbars/qml/qmlbars/main.qml 0
+
+ The axis change is done because income and expenses have different label format. The same could have
+ been achieved using a single axis and just changing the label format.
+
+ The second interesting block is where we filter some of the rows away from the visualized data:
+
+ \snippet ../examples/qmlbars/qml/qmlbars/main.qml 1
+
+ The filtering is done by setting \c autoRowCategories to false on the BarDataMapping item and defining
+ the row categories explicitly. This way, only the items in specified rows are visualized.
+
+ The third interesting block shows how to get the row and column index of an item if you know the
+ row and column values by using BarDataMapping methods \c rowCategoryIndex() and \c columnCategoryIndex():
+
+ \snippet ../examples/qmlbars/qml/qmlbars/main.qml 2
+*/
diff --git a/examples/qmlbarchart/main.cpp b/examples/qmlbars/main.cpp
index b58e66f8..58cd5e32 100644
--- a/examples/qmlbarchart/main.cpp
+++ b/examples/qmlbars/main.cpp
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -33,10 +33,9 @@ int main(int argc, char *argv[])
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.setTitle(QStringLiteral("Monthly income/expenses"));
+
viewer.setSource(QUrl("qrc:/qml/main.qml"));
viewer.setResizeMode(QQuickView::SizeRootObjectToView);
viewer.show();
diff --git a/examples/qmlbars/qml/qmlbars/axes.qml b/examples/qmlbars/qml/qmlbars/axes.qml
new file mode 100644
index 00000000..66be99a0
--- /dev/null
+++ b/examples/qmlbars/qml/qmlbars/axes.qml
@@ -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 QtDataVisualization 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 com.digia.QtDataVisualization 1.0
+
+Item {
+ property alias column: columnAxis
+ property alias expenses: expensesAxis
+ property alias income: incomeAxis
+
+ // For row labels we can use row labels from data proxy, so default axis
+ // suffices for rows.
+
+ // Custom labels for columns, since the data contains abbreviated month names.
+ //! [0]
+ CategoryAxis3D {
+ id: columnAxis
+ categoryLabels: ["January", "February", "March", "April", "May", "June",
+ "July", "August", "September", "October", "November", "December"]
+ }
+ //! [0]
+ ValueAxis3D {
+ id: incomeAxis
+ min: 0
+ max: 35
+ labelFormat: "%.2f M\u20AC"
+ title: "Monthly income"
+ }
+ ValueAxis3D {
+ id: expensesAxis
+ min: 0
+ max: 35
+ labelFormat: "-%.2f M\u20AC"
+ title: "Monthly expenses"
+ }
+}
diff --git a/examples/qmlbars/qml/qmlbars/data.qml b/examples/qmlbars/qml/qmlbars/data.qml
new file mode 100644
index 00000000..ecb05030
--- /dev/null
+++ b/examples/qmlbars/qml/qmlbars/data.qml
@@ -0,0 +1,137 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 com.digia.QtDataVisualization 1.0
+
+Item {
+ property alias mapping: valueMapping
+ property alias model: dataModel
+ property alias proxy: modelProxy
+
+ //! [1]
+ BarDataMapping {
+ id: valueMapping
+ rowRole: "year"
+ columnRole: "month"
+ valueRole: "expenses"
+ }
+ //! [1]
+ //! [2]
+ ItemModelBarDataProxy {
+ id: modelProxy
+ activeMapping: valueMapping
+ itemModel: dataModel
+ }
+ //! [2]
+ //! [0]
+ ListModel {
+ id: dataModel
+ ListElement{ year: "2006"; month: "Jan"; expenses: "4"; income: "5" }
+ ListElement{ year: "2006"; month: "Feb"; expenses: "5"; income: "6" }
+ ListElement{ year: "2006"; month: "Mar"; expenses: "7"; income: "4" }
+ //! [0]
+ ListElement{ year: "2006"; month: "Apr"; expenses: "3"; income: "2" }
+ ListElement{ year: "2006"; month: "May"; expenses: "4"; income: "1" }
+ ListElement{ year: "2006"; month: "Jun"; expenses: "2"; income: "2" }
+ ListElement{ year: "2006"; month: "Jul"; expenses: "1"; income: "3" }
+ ListElement{ year: "2006"; month: "Aug"; expenses: "5"; income: "1" }
+ ListElement{ year: "2006"; month: "Sep"; expenses: "2"; income: "3" }
+ ListElement{ year: "2006"; month: "Oct"; expenses: "5"; income: "2" }
+ ListElement{ year: "2006"; month: "Nov"; expenses: "8"; income: "5" }
+ ListElement{ year: "2006"; month: "Dec"; expenses: "3"; income: "3" }
+
+ ListElement{ year: "2007"; month: "Jan"; expenses: "3"; income: "1" }
+ ListElement{ year: "2007"; month: "Feb"; expenses: "4"; income: "2" }
+ ListElement{ year: "2007"; month: "Mar"; expenses: "12"; income: "4" }
+ ListElement{ year: "2007"; month: "Apr"; expenses: "13"; income: "6" }
+ ListElement{ year: "2007"; month: "May"; expenses: "14"; income: "11" }
+ ListElement{ year: "2007"; month: "Jun"; expenses: "7"; income: "7" }
+ ListElement{ year: "2007"; month: "Jul"; expenses: "6"; income: "4" }
+ ListElement{ year: "2007"; month: "Aug"; expenses: "4"; income: "15" }
+ ListElement{ year: "2007"; month: "Sep"; expenses: "2"; income: "18" }
+ ListElement{ year: "2007"; month: "Oct"; expenses: "29"; income: "25" }
+ ListElement{ year: "2007"; month: "Nov"; expenses: "23"; income: "29" }
+ ListElement{ year: "2007"; month: "Dec"; expenses: "5"; income: "9" }
+
+ ListElement{ year: "2008"; month: "Jan"; expenses: "3"; income: "8" }
+ ListElement{ year: "2008"; month: "Feb"; expenses: "8"; income: "14" }
+ ListElement{ year: "2008"; month: "Mar"; expenses: "10"; income: "20" }
+ ListElement{ year: "2008"; month: "Apr"; expenses: "12"; income: "24" }
+ ListElement{ year: "2008"; month: "May"; expenses: "10"; income: "19" }
+ ListElement{ year: "2008"; month: "Jun"; expenses: "5"; income: "8" }
+ ListElement{ year: "2008"; month: "Jul"; expenses: "1"; income: "4" }
+ ListElement{ year: "2008"; month: "Aug"; expenses: "7"; income: "12" }
+ ListElement{ year: "2008"; month: "Sep"; expenses: "4"; income: "16" }
+ ListElement{ year: "2008"; month: "Oct"; expenses: "22"; income: "33" }
+ ListElement{ year: "2008"; month: "Nov"; expenses: "16"; income: "25" }
+ ListElement{ year: "2008"; month: "Dec"; expenses: "2"; income: "7" }
+
+ ListElement{ year: "2009"; month: "Jan"; expenses: "4"; income: "5" }
+ ListElement{ year: "2009"; month: "Feb"; expenses: "4"; income: "7" }
+ ListElement{ year: "2009"; month: "Mar"; expenses: "11"; income: "14" }
+ ListElement{ year: "2009"; month: "Apr"; expenses: "16"; income: "22" }
+ ListElement{ year: "2009"; month: "May"; expenses: "3"; income: "5" }
+ ListElement{ year: "2009"; month: "Jun"; expenses: "4"; income: "8" }
+ ListElement{ year: "2009"; month: "Jul"; expenses: "7"; income: "9" }
+ ListElement{ year: "2009"; month: "Aug"; expenses: "9"; income: "13" }
+ ListElement{ year: "2009"; month: "Sep"; expenses: "1"; income: "6" }
+ ListElement{ year: "2009"; month: "Oct"; expenses: "14"; income: "25" }
+ ListElement{ year: "2009"; month: "Nov"; expenses: "19"; income: "29" }
+ ListElement{ year: "2009"; month: "Dec"; expenses: "5"; income: "7" }
+
+ ListElement{ year: "2010"; month: "Jan"; expenses: "14"; income: "22" }
+ ListElement{ year: "2010"; month: "Feb"; expenses: "5"; income: "7" }
+ ListElement{ year: "2010"; month: "Mar"; expenses: "1"; income: "9" }
+ ListElement{ year: "2010"; month: "Apr"; expenses: "1"; income: "12" }
+ ListElement{ year: "2010"; month: "May"; expenses: "5"; income: "9" }
+ ListElement{ year: "2010"; month: "Jun"; expenses: "5"; income: "8" }
+ ListElement{ year: "2010"; month: "Jul"; expenses: "3"; income: "7" }
+ ListElement{ year: "2010"; month: "Aug"; expenses: "1"; income: "5" }
+ ListElement{ year: "2010"; month: "Sep"; expenses: "2"; income: "4" }
+ ListElement{ year: "2010"; month: "Oct"; expenses: "10"; income: "13" }
+ ListElement{ year: "2010"; month: "Nov"; expenses: "12"; income: "17" }
+ ListElement{ year: "2010"; month: "Dec"; expenses: "6"; income: "9" }
+
+ ListElement{ year: "2011"; month: "Jan"; expenses: "2"; income: "6" }
+ ListElement{ year: "2011"; month: "Feb"; expenses: "4"; income: "8" }
+ ListElement{ year: "2011"; month: "Mar"; expenses: "7"; income: "12" }
+ ListElement{ year: "2011"; month: "Apr"; expenses: "9"; income: "15" }
+ ListElement{ year: "2011"; month: "May"; expenses: "7"; income: "19" }
+ ListElement{ year: "2011"; month: "Jun"; expenses: "9"; income: "18" }
+ ListElement{ year: "2011"; month: "Jul"; expenses: "13"; income: "17" }
+ ListElement{ year: "2011"; month: "Aug"; expenses: "5"; income: "9" }
+ ListElement{ year: "2011"; month: "Sep"; expenses: "3"; income: "8" }
+ ListElement{ year: "2011"; month: "Oct"; expenses: "13"; income: "15" }
+ ListElement{ year: "2011"; month: "Nov"; expenses: "8"; income: "17" }
+ ListElement{ year: "2011"; month: "Dec"; expenses: "7"; income: "10" }
+
+ ListElement{ year: "2012"; month: "Jan"; expenses: "12"; income: "16" }
+ ListElement{ year: "2012"; month: "Feb"; expenses: "24"; income: "28" }
+ ListElement{ year: "2012"; month: "Mar"; expenses: "27"; income: "22" }
+ ListElement{ year: "2012"; month: "Apr"; expenses: "29"; income: "25" }
+ ListElement{ year: "2012"; month: "May"; expenses: "27"; income: "29" }
+ ListElement{ year: "2012"; month: "Jun"; expenses: "19"; income: "18" }
+ ListElement{ year: "2012"; month: "Jul"; expenses: "13"; income: "17" }
+ ListElement{ year: "2012"; month: "Aug"; expenses: "15"; income: "19" }
+ ListElement{ year: "2012"; month: "Sep"; expenses: "3"; income: "8" }
+ ListElement{ year: "2012"; month: "Oct"; expenses: "3"; income: "6" }
+ ListElement{ year: "2012"; month: "Nov"; expenses: "4"; income: "8" }
+ ListElement{ year: "2012"; month: "Dec"; expenses: "5"; income: "9" }
+ }
+}
diff --git a/examples/qmlbars/qml/qmlbars/main.qml b/examples/qmlbars/qml/qmlbars/main.qml
new file mode 100644
index 00000000..6f44fe63
--- /dev/null
+++ b/examples/qmlbars/qml/qmlbars/main.qml
@@ -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 QtDataVisualization 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.QtDataVisualization 1.0
+import "."
+
+Item {
+ id: mainview
+ width: 1280
+ height: 1024
+ visible: true
+
+ Data {
+ id: graphData
+ }
+
+ Axes {
+ id: graphAxes
+ }
+
+ Item {
+ id: dataView
+ width: parent.width - tableView.width
+ height: parent.height
+ anchors.right: parent.right;
+
+ Bars3D {
+ id: testGraph
+ width: dataView.width
+ height: dataView.height
+ shadowQuality: AbstractGraph3D.ShadowQualityMedium
+ selectionMode: AbstractGraph3D.SelectionModeItem
+ font.pointSize: 35
+ theme: AbstractGraph3D.ThemeRetro
+ labelStyle: AbstractGraph3D.LabelStyleFromTheme
+ dataProxy: graphData.proxy
+ barThickness: 0.5
+ barSpacing: Qt.size(0.5, 0.5)
+ barSpacingRelative: false
+ scene.activeCamera.cameraPreset: AbstractGraph3D.CameraPresetRight
+ columnAxis: graphAxes.column
+ valueAxis: graphAxes.expenses
+ itemLabelFormat: "@valueTitle for @colLabel, @rowLabel: @valueLabel"
+
+ onSelectedBarPosChanged: {
+ // Set tableView current row to selected bar
+ var rowRole = graphData.proxy.rowLabels[position.x];
+ var colRole = graphData.proxy.columnLabels[position.y];
+ var currentRow = tableView.currentRow
+ if (currentRow === -1 || rowRole !== graphData.model.get(currentRow).year
+ || colRole !== graphData.model.get(currentRow).month) {
+ var totalRows = tableView.rowCount;
+ for (var i = 0; i < totalRows; i++) {
+ var currentRowRole = graphData.model.get(i).year
+ var currentColRole = graphData.model.get(i).month
+ if (currentRowRole === rowRole && currentColRole === colRole) {
+ tableView.currentRow = i
+ break
+ }
+ }
+ }
+ }
+ }
+ }
+
+ Button {
+ id: mappingToggle
+ anchors.bottom: parent.bottom
+ width: tableView.width
+ height: 60
+ text: "Show Income"
+ //! [0]
+ onClicked: {
+ if (graphData.mapping.valueRole === "expenses") {
+ graphData.mapping.valueRole = "income"
+ text = "Show Expenses"
+ testGraph.valueAxis = graphAxes.income
+ } else {
+ graphData.mapping.valueRole = "expenses"
+ text = "Show Income"
+ testGraph.valueAxis = graphAxes.expenses
+ }
+ }
+ //! [0]
+ }
+
+ Button {
+ id: shadowToggle
+ anchors.bottom: mappingToggle.top
+ width: tableView.width
+ height: 60
+ text: "Hide Shadows"
+ onClicked: {
+ if (testGraph.shadowQuality == AbstractGraph3D.ShadowQualityNone) {
+ testGraph.shadowQuality = AbstractGraph3D.ShadowQualityMedium;
+ text = "Hide Shadows"
+ } else {
+ testGraph.shadowQuality = AbstractGraph3D.ShadowQualityNone;
+ text = "Show Shadows"
+ }
+ }
+ }
+
+ Button {
+ id: dataToggle
+ anchors.bottom: shadowToggle.top
+ width: tableView.width
+ height: 60
+ text: "Show 2010 - 2012"
+ //! [1]
+ onClicked: {
+ if (testGraph.rowAxis.max !== 6) {
+ text = "Show 2010 - 2012"
+ graphData.mapping.autoRowCategories = true
+ } else {
+ text = "Show all years"
+ // Explicitly defining row categories, since we do not want to show data for
+ // all years in the model, just for the selected ones.
+ graphData.mapping.autoRowCategories = false
+ graphData.mapping.rowCategories = ["2010", "2011", "2012"]
+ }
+ }
+ //! [1]
+ }
+
+ TableView {
+ id: tableView
+ x: 0
+ y: 0
+ width: 298
+ height: parent.height - mappingToggle.height - shadowToggle.height - dataToggle.height
+ TableViewColumn{ role: "year" ; title: "Year" ; width: 80 }
+ TableViewColumn{ role: "month" ; title: "Month" ; width: 80 }
+ TableViewColumn{ role: "expenses" ; title: "Expenses" ; width: 60 }
+ TableViewColumn{ role: "income" ; title: "Income" ; width: 60 }
+ model: graphData.model
+
+ //! [2]
+ onCurrentRowChanged: {
+ var rowIndex = graphData.proxy.activeMapping.rowCategoryIndex(graphData.model.get(currentRow).year)
+ var colIndex = graphData.proxy.activeMapping.columnCategoryIndex(graphData.model.get(currentRow).month)
+ testGraph.selectedBarPos = Qt.point(rowIndex, colIndex)
+ }
+ //! [2]
+ }
+}
diff --git a/examples/qmlmaps/qmlmaps.desktop b/examples/qmlbars/qmlbars.desktop
index 25959510..cf59c6b8 100644
--- a/examples/qmlmaps/qmlmaps.desktop
+++ b/examples/qmlbars/qmlbars.desktop
@@ -3,9 +3,9 @@ Encoding=UTF-8
Version=1.0
Type=Application
Terminal=false
-Name=qmlmaps
-Exec=/opt/qmlmaps/bin/qmlmaps
-Icon=qmlmaps64
+Name=qmlbars
+Exec=/opt/qmlbars/bin/qmlbars
+Icon=qmlbars64
X-Window-Icon=
X-HildonDesk-ShowInToolbar=true
X-Osso-Type=application/x-executable
diff --git a/examples/qmlmaps/qmlmaps.pro b/examples/qmlbars/qmlbars.pro
index 44963d48..758e7b76 100644
--- a/examples/qmlmaps/qmlmaps.pro
+++ b/examples/qmlbars/qmlbars.pro
@@ -2,28 +2,24 @@
error( "Couldn't find the examples.pri file!" )
}
+QT += widgets
+
# Add more folders to ship with the application, here
-folder_01.source = qml/qmlmaps
+folder_01.source = qml/qmlbars
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
+RESOURCES += qmlbars.qrc
+
+OTHER_FILES += doc/src/* \
+ doc/images/*
diff --git a/examples/qmlbars/qmlbars.qrc b/examples/qmlbars/qmlbars.qrc
new file mode 100644
index 00000000..7c291fd3
--- /dev/null
+++ b/examples/qmlbars/qmlbars.qrc
@@ -0,0 +1,7 @@
+<RCC>
+ <qresource prefix="/qml">
+ <file alias="Axes.qml">qml/qmlbars/axes.qml</file>
+ <file alias="Data.qml">qml/qmlbars/data.qml</file>
+ <file alias="main.qml">qml/qmlbars/main.qml</file>
+ </qresource>
+</RCC>
diff --git a/examples/qmlbarchart/qmlbarchart64.png b/examples/qmlbars/qmlbars64.png
index 707d5c4e..707d5c4e 100644
--- a/examples/qmlbarchart/qmlbarchart64.png
+++ b/examples/qmlbars/qmlbars64.png
Binary files differ
diff --git a/examples/qmlbarchart/qtquick2applicationviewer/qtquick2applicationviewer.cpp b/examples/qmlbars/qtquick2applicationviewer/qtquick2applicationviewer.cpp
index 10709d7a..10709d7a 100644
--- a/examples/qmlbarchart/qtquick2applicationviewer/qtquick2applicationviewer.cpp
+++ b/examples/qmlbars/qtquick2applicationviewer/qtquick2applicationviewer.cpp
diff --git a/examples/qmlbarchart/qtquick2applicationviewer/qtquick2applicationviewer.h b/examples/qmlbars/qtquick2applicationviewer/qtquick2applicationviewer.h
index cf66f140..cf66f140 100644
--- a/examples/qmlbarchart/qtquick2applicationviewer/qtquick2applicationviewer.h
+++ b/examples/qmlbars/qtquick2applicationviewer/qtquick2applicationviewer.h
diff --git a/examples/qmlmaps/qtquick2applicationviewer/qtquick2applicationviewer.pri b/examples/qmlbars/qtquick2applicationviewer/qtquick2applicationviewer.pri
index e5f7990f..a071e63d 100644
--- a/examples/qmlmaps/qtquick2applicationviewer/qtquick2applicationviewer.pri
+++ b/examples/qmlbars/qtquick2applicationviewer/qtquick2applicationviewer.pri
@@ -61,16 +61,6 @@ android-no-sdk {
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 =
diff --git a/examples/qmlmaps/doc/src/qmlmaps.qdoc b/examples/qmlmaps/doc/src/qmlmaps.qdoc
deleted file mode 100644
index f27dc126..00000000
--- a/examples/qmlmaps/doc/src/qmlmaps.qdoc
+++ /dev/null
@@ -1,29 +0,0 @@
-/****************************************************************************
-**
-** 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
deleted file mode 100644
index 578d8252..00000000
--- a/examples/qmlmaps/floorplan.jpg
+++ /dev/null
Binary files differ
diff --git a/examples/qmlmaps/qml/qmlmaps/main.qml b/examples/qmlmaps/qml/qmlmaps/main.qml
deleted file mode 100644
index 9a8fa93b..00000000
--- a/examples/qmlmaps/qml/qmlmaps/main.qml
+++ /dev/null
@@ -1,114 +0,0 @@
-/****************************************************************************
-**
-** 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.qrc b/examples/qmlmaps/qmlmaps.qrc
deleted file mode 100644
index 81f1f83c..00000000
--- a/examples/qmlmaps/qmlmaps.qrc
+++ /dev/null
@@ -1,8 +0,0 @@
-<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/qmlscatter/doc/images/qmlscatter-example.png b/examples/qmlscatter/doc/images/qmlscatter-example.png
new file mode 100644
index 00000000..039c1efc
--- /dev/null
+++ b/examples/qmlscatter/doc/images/qmlscatter-example.png
Binary files differ
diff --git a/examples/qmlscatter/doc/images/qmlscatter-newproject.png b/examples/qmlscatter/doc/images/qmlscatter-newproject.png
new file mode 100644
index 00000000..b64e6fc6
--- /dev/null
+++ b/examples/qmlscatter/doc/images/qmlscatter-newproject.png
Binary files differ
diff --git a/examples/qmlscatter/doc/src/qmlscatter.qdoc b/examples/qmlscatter/doc/src/qmlscatter.qdoc
index d52798c2..c0d207d8 100644
--- a/examples/qmlscatter/doc/src/qmlscatter.qdoc
+++ b/examples/qmlscatter/doc/src/qmlscatter.qdoc
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -19,11 +19,150 @@
/*!
\example qmlscatter
\title Qt Quick 2 Scatter Example
+ \ingroup qtdatavisualization_examples
+ \brief Using Scatter3D in a QML application.
- The Qt Quick 2 scatter example shows how to make a simple scatter chart visualization using
- Q3DScatter using Qt Quick 2.
+ The Qt Quick 2 scatter example shows how to make a simple scatter graph visualization using
+ Scatter3D and Qt Quick 2.
\image qmlscatter-example.png
- TODO
+ \section1 Creating the application
+
+ The application main is created by creating a new Qt Quick 2 Application project in QtCreator:
+
+ \image qmlscatter-newproject.png
+
+ We'll modify the generated \c main.cpp a bit, as we want to add our \c main.qml file as a
+ resource. We do it by replacing
+
+ \code viewer.setMainQmlFile(QStringLiteral("qml/qmlscatter/main.qml")); \endcode
+
+ with
+
+ \snippet ../examples/qmlscatter/main.cpp 0
+
+ This will help us when deploying the application to Android. We'll also change the application
+ to be shown maximized by replacing
+
+ \code viewer.showExpanded(); \endcode
+
+ with
+
+ \snippet ../examples/qmlscatter/main.cpp 1
+
+ We won't look into that any closer, as we'll change nothing in the generated
+ \c qtquick2applicationviewer files.
+
+ Next we'll create new qml files for data (\c data.qml) and a QtQuick.Controls button
+ we want to modify a bit (\c newbutton.qml), and add them to the resource file, in addition to
+ main.qml:
+
+ \code
+ <RCC>
+ <qresource prefix="/qml">
+ <file alias="main.qml">qml/qmlscatter/main.qml</file>
+ <file alias="Data.qml">qml/qmlscatter/data.qml</file>
+ <file alias="NewButton.qml">qml/qmlscatter/newbutton.qml</file>
+ </qresource>
+ </RCC>
+ \endcode
+
+ Now the base for our application is done, and we can start setting up the graph.
+
+ \section1 Setting up the graph
+
+ Let's start modifying the generated \c {main.qml}. We can remove all previous content from it,
+ as it has nothing we need.
+
+ First we'll import all the QML modules we need:
+
+ \snippet ../examples/qmlscatter/qml/qmlscatter/main.qml 0
+
+ The last \c import just imports all the qml files in the same directory as our \c {main.qml},
+ because that's where \c newbutton.qml and \c data.qml are.
+
+ Then we create our main \c Item, call it \c mainView and set it visible:
+
+ \snippet ../examples/qmlscatter/qml/qmlscatter/main.qml 1
+
+ Then we'll add another \c Item inside it, and call it \c dataView. This will be the item to hold
+ the \c Scatter3D graph. We'll anchor it to the parent bottom:
+
+ \snippet ../examples/qmlscatter/qml/qmlscatter/main.qml 9
+
+ Next we're ready to add the \c Scatter3D graph itself. We'll add it inside the \c dataView and
+ name it \c {scatterGraph}. Let's make it fill the \c {dataView}:
+
+ \snippet ../examples/qmlscatter/qml/qmlscatter/main.qml 2
+
+ Now the graph is ready to use, but has no data. It also has the default proxy, axes and visual
+ properties.
+
+ Let's modify some visual properties first by adding the following inside \c {scatterGraph}:
+
+ \snippet ../examples/qmlscatter/qml/qmlscatter/main.qml 3
+
+ We changed the font, theme and shadow quality. We're happy with the other visual properties,
+ so we won't change them.
+
+ Then it's time to start feeding the graph some data.
+
+ \section1 Adding data to the graph
+
+ Let's create a \c Data item inside the \c mainView and name it \c {graphData}:
+
+ \snippet ../examples/qmlscatter/qml/qmlscatter/main.qml 4
+
+ This is the component that holds our data in \c {data.qml}. It has an \c Item as the main
+ component.
+
+ In the main component we'll add the data itself in a \c ListModel and name it
+ \c {dataModel}:
+
+ \snippet ../examples/qmlscatter/qml/qmlscatter/data.qml 0
+ \dots
+
+ That itself doesn't do us much good, so we'll create a \c ScatterDataMapping and name it
+ \c {scatterMapping}:
+
+ \snippet ../examples/qmlscatter/qml/qmlscatter/data.qml 1
+
+ In \c scatterMapping we need to define axis roles to match the roles in the \c ListElement
+ items of the \c {dataModel}.
+
+ We'll still need a data proxy, so we'll create a \c ItemModelScatterDataProxy and call it
+ \c {modelProxy}:
+
+ \snippet ../examples/qmlscatter/qml/qmlscatter/data.qml 2
+
+ We set \c scatterMapping as the active mapping and \c dataModel as the item model.
+
+ We still need to expose the proxy to be usable from \c {main.qml}. We do this by defining it as
+ an alias in the main data component:
+
+ \snippet ../examples/qmlscatter/qml/qmlscatter/data.qml 3
+
+ Now we can use the data from \c data.qml with \c scatterGraph in \c {main.qml}. We'll just set
+ \c proxy as the \c dataProxy for the graph:
+
+ \snippet ../examples/qmlscatter/qml/qmlscatter/main.qml 5
+
+ We'll set up selection label format and the axes in \c scatterGraph as well:
+
+ \snippet ../examples/qmlscatter/qml/qmlscatter/main.qml 6
+
+ After that we'll add a few buttons to the \c mainView to control the graph. We'll only show one
+ as an example:
+
+ \snippet ../examples/qmlscatter/qml/qmlscatter/main.qml 7
+
+ Then we'll modify \c dataView to make room for the buttons at the top:
+
+ \snippet ../examples/qmlscatter/qml/qmlscatter/main.qml 8
+ \dots
+
+ And we're done!
+
+ \section1 Example contents
*/
diff --git a/examples/qmlscatter/main.cpp b/examples/qmlscatter/main.cpp
index d48bea3d..cc3fa4c3 100644
--- a/examples/qmlscatter/main.cpp
+++ b/examples/qmlscatter/main.cpp
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -33,14 +33,15 @@ int main(int argc, char *argv[])
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.setTitle(QStringLiteral("QML scatter example"));
+ //! [0]
viewer.setSource(QUrl("qrc:/qml/main.qml"));
+ //! [0]
viewer.setResizeMode(QQuickView::SizeRootObjectToView);
- viewer.setMinimumSize(QSize(640, 480));
- viewer.show();
+ //! [1]
+ viewer.showMaximized();
+ //! [1]
return app.exec();
}
diff --git a/examples/qmlscatter/qml/qmlscatter/data.qml b/examples/qmlscatter/qml/qmlscatter/data.qml
new file mode 100644
index 00000000..37b0dc61
--- /dev/null
+++ b/examples/qmlscatter/qml/qmlscatter/data.qml
@@ -0,0 +1,1109 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 com.digia.QtDataVisualization 1.0
+
+Item {
+ //! [3]
+ property alias proxy: modelProxy
+ //! [3]
+
+ //! [1]
+ ScatterDataMapping {
+ id: scatterMapping
+ xPosRole: "xPos"
+ yPosRole: "yPos"
+ zPosRole: "zPos"
+ }
+ //! [1]
+
+ //! [2]
+ ItemModelScatterDataProxy {
+ id: modelProxy
+ activeMapping: scatterMapping
+ itemModel: dataModel
+ }
+ //! [2]
+
+ //! [0]
+ ListModel {
+ id: dataModel
+ ListElement{ xPos: -10.0; yPos: 5.0; zPos: -5.0 }
+ //! [0]
+ ListElement{ xPos: -9.0; yPos: 3.0; zPos: -4.5 }
+ ListElement{ xPos: -8.5; yPos: 4.1; zPos: -4.0 }
+ ListElement{ xPos: -8.0; yPos: 4.75; zPos: -3.9 }
+ ListElement{ xPos: -9.5; yPos: 4.9; zPos: -4.2 }
+ ListElement{ xPos: -9.9; yPos: 3.42; zPos: -3.5 }
+ ListElement{ xPos: -7.8; yPos: 3.1; zPos: -4.9 }
+ ListElement{ xPos: -7.3; yPos: 2.91; zPos: -4.1 }
+ ListElement{ xPos: -7.1 ; yPos: 3.68 ; zPos: -4.52 }
+ ListElement{ xPos: -8.8 ; yPos: 2.96 ; zPos: -3.6 }
+ ListElement{ xPos: -6.94 ; yPos: 2.4 ; zPos: -2.92 }
+ ListElement{ xPos: -9.02 ; yPos: 4.74 ; zPos: -4.18 }
+ ListElement{ xPos: -9.54 ; yPos: 3.1 ; zPos: -3.8 }
+ ListElement{ xPos: -6.86 ; yPos: 3.66 ; zPos: -3.58 }
+ ListElement{ xPos: -8.16 ; yPos: 1.82 ; zPos: -4.64 }
+ ListElement{ xPos: -7.4 ; yPos: 3.18 ; zPos: -4.22 }
+ ListElement{ xPos: -7.9 ; yPos: 3.06 ; zPos: -4.3 }
+ ListElement{ xPos: -8.98 ; yPos: 2.64 ; zPos: -4.44 }
+ ListElement{ xPos: -6.36 ; yPos: 3.96 ; zPos: -4.38 }
+ ListElement{ xPos: -7.18 ; yPos: 3.32 ; zPos: -4.04 }
+ ListElement{ xPos: -7.9 ; yPos: 3.4 ; zPos: -2.78 }
+ ListElement{ xPos: -7.4 ; yPos: 3.12 ; zPos: -3.1 }
+ ListElement{ xPos: -7.54 ; yPos: 2.8 ; zPos: -3.68 }
+
+ ListElement{ xPos: 2.25 ; yPos: 1.36 ; zPos: -1.3 }
+ ListElement{ xPos: -2 ; yPos: -0.08 ; zPos: 1 }
+ ListElement{ xPos: 2.65 ; yPos: -1.2 ; zPos: 2.7 }
+ ListElement{ xPos: -2.55 ; yPos: 3.48 ; zPos: -0.45 }
+ ListElement{ xPos: -3.85 ; yPos: 0.2 ; zPos: 0.5 }
+ ListElement{ xPos: 2.85 ; yPos: 1.32 ; zPos: 1.05 }
+ ListElement{ xPos: -0.4 ; yPos: -2.36 ; zPos: -1.6 }
+ ListElement{ xPos: 1.5 ; yPos: 0.36 ; zPos: -0.55 }
+ ListElement{ xPos: 0.25 ; yPos: 0.12 ; zPos: -0.75 }
+ ListElement{ xPos: -2.45 ; yPos: -0.72 ; zPos: -1.1 }
+ ListElement{ xPos: 4.1 ; yPos: 1.92 ; zPos: -0.95 }
+ ListElement{ xPos: 2.05 ; yPos: 0.64 ; zPos: -0.1 }
+ ListElement{ xPos: 0.25 ; yPos: 0.8 ; zPos: 3.05 }
+ ListElement{ xPos: 1.5 ; yPos: 0.24 ; zPos: 2.25 }
+ ListElement{ xPos: 1.15 ; yPos: -0.4 ; zPos: 0.8 }
+ ListElement{ xPos: -0.05 ; yPos: 0.12 ; zPos: 0.25 }
+ ListElement{ xPos: 0.9 ; yPos: -0.48 ; zPos: -3.2 }
+ ListElement{ xPos: 3.55 ; yPos: -1.04 ; zPos: -0.95 }
+ ListElement{ xPos: -2.4 ; yPos: -0.96 ; zPos: -0.65 }
+ ListElement{ xPos: 4.25 ; yPos: 0.16 ; zPos: 2.05 }
+ ListElement{ xPos: -0.6 ; yPos: 1 ; zPos: -0.2 }
+ ListElement{ xPos: 0 ; yPos: -0.84 ; zPos: -0.95 }
+ ListElement{ xPos: -4.2 ; yPos: 1.44 ; zPos: 0.85 }
+ ListElement{ xPos: -1.5 ; yPos: -1.2 ; zPos: -1.5 }
+ ListElement{ xPos: -3.35 ; yPos: -1.96 ; zPos: 1.8 }
+ ListElement{ xPos: -2.75 ; yPos: -0.96 ; zPos: -1.2 }
+ ListElement{ xPos: -2.45 ; yPos: 0.28 ; zPos: -4.55 }
+ ListElement{ xPos: 2.7 ; yPos: -1.4 ; zPos: -0.65 }
+ ListElement{ xPos: 2.7 ; yPos: 2.2 ; zPos: -2.4 }
+ ListElement{ xPos: -0.8 ; yPos: -2.04 ; zPos: 3.75 }
+ ListElement{ xPos: -1 ; yPos: -1.84 ; zPos: 2.35 }
+ ListElement{ xPos: -3.25 ; yPos: -1.6 ; zPos: -4.4 }
+ ListElement{ xPos: -0.35 ; yPos: -0.56 ; zPos: -1.75 }
+ ListElement{ xPos: -0.8 ; yPos: -0.28 ; zPos: -0.05 }
+ ListElement{ xPos: 4.75 ; yPos: -1.48 ; zPos: -2.45 }
+ ListElement{ xPos: 4.35 ; yPos: 1.4 ; zPos: 0.8 }
+ ListElement{ xPos: -3.2 ; yPos: 2 ; zPos: 0.5 }
+ ListElement{ xPos: 2 ; yPos: 1.92 ; zPos: 0.55 }
+ ListElement{ xPos: -0.45 ; yPos: 0.68 ; zPos: -0.8 }
+ ListElement{ xPos: -2.7 ; yPos: 2 ; zPos: -2.4 }
+ ListElement{ xPos: -1.65 ; yPos: 1.32 ; zPos: -2.05 }
+ ListElement{ xPos: -1.6 ; yPos: 1.8 ; zPos: -3.65 }
+ ListElement{ xPos: -1.2 ; yPos: -0.72 ; zPos: 0.85 }
+ ListElement{ xPos: 1.4 ; yPos: 1.08 ; zPos: 2.1 }
+ ListElement{ xPos: -3.9 ; yPos: -1.16 ; zPos: -0.85 }
+ ListElement{ xPos: 3.15 ; yPos: 0.12 ; zPos: -0.95 }
+ ListElement{ xPos: -1.35 ; yPos: -2.64 ; zPos: -0.5 }
+ ListElement{ xPos: -4.15 ; yPos: 1.28 ; zPos: -4.4 }
+ ListElement{ xPos: -2 ; yPos: 2.48 ; zPos: -0.15 }
+ ListElement{ xPos: -3.4 ; yPos: 0.6 ; zPos: 0 }
+ ListElement{ xPos: -1.5 ; yPos: -0.96 ; zPos: 2.35 }
+ ListElement{ xPos: -0.75 ; yPos: 1.16 ; zPos: -0.75 }
+ ListElement{ xPos: -0.85 ; yPos: 0.64 ; zPos: -1.75 }
+ ListElement{ xPos: 0.85 ; yPos: 0.48 ; zPos: 2.9 }
+ ListElement{ xPos: 4.05 ; yPos: 3.24 ; zPos: -0.1 }
+ ListElement{ xPos: 0.65 ; yPos: 0.84 ; zPos: 0.3 }
+ ListElement{ xPos: -2.1 ; yPos: 0.92 ; zPos: -2.75 }
+ ListElement{ xPos: -0.65 ; yPos: 0.16 ; zPos: 1.6 }
+ ListElement{ xPos: -1.8 ; yPos: -1.48 ; zPos: -2.15 }
+ ListElement{ xPos: -1.6 ; yPos: 2.96 ; zPos: 1.85 }
+ ListElement{ xPos: -0.75 ; yPos: 0.28 ; zPos: -0.75 }
+ ListElement{ xPos: 2.2 ; yPos: 1.16 ; zPos: 2.65 }
+ ListElement{ xPos: 2.6 ; yPos: 2.92 ; zPos: -0.2 }
+ ListElement{ xPos: -1.65 ; yPos: 3.28 ; zPos: 2.5 }
+ ListElement{ xPos: -0.5 ; yPos: 2.52 ; zPos: -1.15 }
+ ListElement{ xPos: -1.85 ; yPos: 0.52 ; zPos: -2 }
+ ListElement{ xPos: 0.15 ; yPos: -2.36 ; zPos: -0.5 }
+ ListElement{ xPos: -3.9 ; yPos: 0.28 ; zPos: -0.25 }
+ ListElement{ xPos: 0.1 ; yPos: -3.88 ; zPos: -0.7 }
+ ListElement{ xPos: -1 ; yPos: -1.96 ; zPos: 0.95 }
+ ListElement{ xPos: -0.3 ; yPos: -3.52 ; zPos: -1.45 }
+ ListElement{ xPos: 3.2 ; yPos: -2.56 ; zPos: 2.5 }
+ ListElement{ xPos: 0 ; yPos: -2.44 ; zPos: 1.35 }
+ ListElement{ xPos: 1.45 ; yPos: -1.96 ; zPos: 0.1 }
+ ListElement{ xPos: 3.55 ; yPos: -2.16 ; zPos: 1.75 }
+ ListElement{ xPos: 2.8 ; yPos: -0.72 ; zPos: -0.3 }
+ ListElement{ xPos: -1.65 ; yPos: -0.6 ; zPos: 0.25 }
+ ListElement{ xPos: -4.35 ; yPos: -1.32 ; zPos: -2.3 }
+ ListElement{ xPos: 2.75 ; yPos: -1.88 ; zPos: 1.7 }
+ ListElement{ xPos: 2.75 ; yPos: -0.6 ; zPos: 2.45 }
+ ListElement{ xPos: 0.15 ; yPos: -0.88 ; zPos: -0.2 }
+ ListElement{ xPos: 0.15 ; yPos: 0.04 ; zPos: -0.1 }
+ ListElement{ xPos: -1.2 ; yPos: -2.92 ; zPos: -3 }
+ ListElement{ xPos: -0.7 ; yPos: 0.16 ; zPos: 3.5 }
+ ListElement{ xPos: -1.8 ; yPos: -2.4 ; zPos: 0.2 }
+ ListElement{ xPos: 1.25 ; yPos: 2.64 ; zPos: 1.65 }
+ ListElement{ xPos: -0.65 ; yPos: 1.32 ; zPos: -0.55 }
+ ListElement{ xPos: 3.85 ; yPos: 2.32 ; zPos: -1 }
+ ListElement{ xPos: 1.65 ; yPos: -2.28 ; zPos: 0.95 }
+ ListElement{ xPos: -2.45 ; yPos: -2.96 ; zPos: 3.45 }
+ ListElement{ xPos: -1.75 ; yPos: 0.36 ; zPos: 1.6 }
+ ListElement{ xPos: 1.1 ; yPos: -0.84 ; zPos: 0.35 }
+ ListElement{ xPos: -1.55 ; yPos: 1.6 ; zPos: -3.1 }
+ ListElement{ xPos: 0.4 ; yPos: -1.36 ; zPos: -1.55 }
+ ListElement{ xPos: -3.95 ; yPos: 0.2 ; zPos: 3.7 }
+ ListElement{ xPos: -1.8 ; yPos: -0.24 ; zPos: 2.2 }
+ ListElement{ xPos: -0.45 ; yPos: 1.64 ; zPos: 1.35 }
+ ListElement{ xPos: -0.6 ; yPos: -0.72 ; zPos: 2.5 }
+ ListElement{ xPos: -1.2 ; yPos: -3.04 ; zPos: -1.55 }
+ ListElement{ xPos: -0.95 ; yPos: 1.48 ; zPos: 0.95 }
+ ListElement{ xPos: 1.7 ; yPos: -1.36 ; zPos: 2.15 }
+ ListElement{ xPos: -3.9 ; yPos: -0.32 ; zPos: -2.45 }
+ ListElement{ xPos: 2.95 ; yPos: 3.12 ; zPos: -2.4 }
+ ListElement{ xPos: 3.55 ; yPos: -1.48 ; zPos: 0.15 }
+ ListElement{ xPos: -1.4 ; yPos: 3.24 ; zPos: 0.7 }
+ ListElement{ xPos: -3.3 ; yPos: -0.8 ; zPos: 0 }
+ ListElement{ xPos: 1.15 ; yPos: 0.36 ; zPos: -2.7 }
+ ListElement{ xPos: 0.4 ; yPos: 0.12 ; zPos: 1.35 }
+ ListElement{ xPos: 1.9 ; yPos: -3.32 ; zPos: -0.75 }
+ ListElement{ xPos: 0.4 ; yPos: -0.2 ; zPos: -2.4 }
+ ListElement{ xPos: 0.55 ; yPos: 1.56 ; zPos: 2.25 }
+ ListElement{ xPos: 4.35 ; yPos: -0.96 ; zPos: -0.7 }
+ ListElement{ xPos: 3.35 ; yPos: -1.04 ; zPos: -0.85 }
+ ListElement{ xPos: 1.7 ; yPos: -0.28 ; zPos: -0.25 }
+ ListElement{ xPos: -3.05 ; yPos: -0.44 ; zPos: 1.3 }
+ ListElement{ xPos: -3.95 ; yPos: -2.72 ; zPos: -3.8 }
+ ListElement{ xPos: 2.1 ; yPos: 1.32 ; zPos: 1.15 }
+ ListElement{ xPos: 1.4 ; yPos: -0.44 ; zPos: -2.85 }
+ ListElement{ xPos: -2.1 ; yPos: 0.04 ; zPos: 2 }
+ ListElement{ xPos: 2.45 ; yPos: -2.44 ; zPos: -2.85 }
+ ListElement{ xPos: 4.35 ; yPos: 0.24 ; zPos: 1.1 }
+ ListElement{ xPos: 1.8 ; yPos: 1.8 ; zPos: -0.7 }
+ ListElement{ xPos: 1.8 ; yPos: 2.04 ; zPos: -0.95 }
+ ListElement{ xPos: 1.65 ; yPos: -2.48 ; zPos: 0.35 }
+ ListElement{ xPos: -3.3 ; yPos: 0.28 ; zPos: -1.6 }
+ ListElement{ xPos: 1.85 ; yPos: 1 ; zPos: 2.25 }
+ ListElement{ xPos: -2 ; yPos: -0.88 ; zPos: -2.6 }
+ ListElement{ xPos: -0.1 ; yPos: 0.28 ; zPos: -1.75 }
+ ListElement{ xPos: -2.5 ; yPos: -2.76 ; zPos: -0.2 }
+ ListElement{ xPos: 0.3 ; yPos: -1.64 ; zPos: -0.75 }
+ ListElement{ xPos: 2.3 ; yPos: -1.28 ; zPos: -2.7 }
+ ListElement{ xPos: -1.7 ; yPos: -1.48 ; zPos: -2.6 }
+ ListElement{ xPos: 0.5 ; yPos: 0.24 ; zPos: -2.2 }
+ ListElement{ xPos: 0.45 ; yPos: -1.88 ; zPos: -0.95 }
+ ListElement{ xPos: -1.2 ; yPos: 0.96 ; zPos: 2.35 }
+ ListElement{ xPos: -0.55 ; yPos: -0.36 ; zPos: -1.8 }
+ ListElement{ xPos: 2.7 ; yPos: -0.56 ; zPos: -0.4 }
+ ListElement{ xPos: 1.1 ; yPos: 2.76 ; zPos: -2.35 }
+ ListElement{ xPos: -1.2 ; yPos: -2.16 ; zPos: 3.1 }
+ ListElement{ xPos: -0.05 ; yPos: 1.76 ; zPos: 1 }
+ ListElement{ xPos: 1.45 ; yPos: -0.72 ; zPos: 0.7 }
+ ListElement{ xPos: 0.2 ; yPos: -3.2 ; zPos: -0.25 }
+ ListElement{ xPos: -0.8 ; yPos: 1.08 ; zPos: -0.1 }
+ ListElement{ xPos: -2.45 ; yPos: 0.56 ; zPos: -0.55 }
+ ListElement{ xPos: 2 ; yPos: 1.12 ; zPos: 2 }
+ ListElement{ xPos: -1.05 ; yPos: -2.16 ; zPos: -1.8 }
+ ListElement{ xPos: 1.2 ; yPos: -2.12 ; zPos: -1.55 }
+ ListElement{ xPos: -4 ; yPos: -0.76 ; zPos: 0.2 }
+ ListElement{ xPos: -0.15 ; yPos: -0.2 ; zPos: -2 }
+ ListElement{ xPos: -2.95 ; yPos: 1.36 ; zPos: -3.65 }
+ ListElement{ xPos: 2.7 ; yPos: 1.16 ; zPos: 2.05 }
+ ListElement{ xPos: 0.95 ; yPos: -1.52 ; zPos: -1.05 }
+ ListElement{ xPos: -1.8 ; yPos: 2.72 ; zPos: -0.55 }
+ ListElement{ xPos: 0.45 ; yPos: 2.88 ; zPos: -4.4 }
+ ListElement{ xPos: 1.35 ; yPos: 1.08 ; zPos: -0.8 }
+ ListElement{ xPos: -2.7 ; yPos: -1.36 ; zPos: -2.65 }
+ ListElement{ xPos: 0.35 ; yPos: 2.32 ; zPos: -1.6 }
+ ListElement{ xPos: -0.45 ; yPos: 1.6 ; zPos: 0.1 }
+ ListElement{ xPos: 3.75 ; yPos: 1.12 ; zPos: -3.8 }
+ ListElement{ xPos: 0.5 ; yPos: 2.6 ; zPos: 0.5 }
+ ListElement{ xPos: -0.75 ; yPos: -3.52 ; zPos: -3.2 }
+ ListElement{ xPos: 0.25 ; yPos: -1.32 ; zPos: 2.25 }
+ ListElement{ xPos: -2.8 ; yPos: -1.6 ; zPos: -2.45 }
+ ListElement{ xPos: 0.15 ; yPos: -0.56 ; zPos: 3.9 }
+ ListElement{ xPos: 2.15 ; yPos: -1.68 ; zPos: -1.7 }
+ ListElement{ xPos: -4.2 ; yPos: -1.92 ; zPos: 2.35 }
+ ListElement{ xPos: 1.95 ; yPos: -1.32 ; zPos: 0.3 }
+ ListElement{ xPos: 0.5 ; yPos: 0.64 ; zPos: 0.75 }
+ ListElement{ xPos: 0.85 ; yPos: -0.84 ; zPos: -0.5 }
+ ListElement{ xPos: -2.15 ; yPos: -1.64 ; zPos: -2.3 }
+ ListElement{ xPos: -0.85 ; yPos: -2.84 ; zPos: -0.3 }
+ ListElement{ xPos: -3.1 ; yPos: -0.32 ; zPos: -0.85 }
+ ListElement{ xPos: 3.45 ; yPos: 0 ; zPos: 0.8 }
+ ListElement{ xPos: 1.4 ; yPos: 0.2 ; zPos: 0.3 }
+ ListElement{ xPos: 0.45 ; yPos: 1.76 ; zPos: -0.15 }
+ ListElement{ xPos: 0.85 ; yPos: 3.16 ; zPos: -2 }
+ ListElement{ xPos: 2.15 ; yPos: 0.72 ; zPos: -0.95 }
+ ListElement{ xPos: -2.4 ; yPos: 0.6 ; zPos: -0.5 }
+ ListElement{ xPos: 1.45 ; yPos: -0.4 ; zPos: -1.95 }
+ ListElement{ xPos: 0.6 ; yPos: -1.84 ; zPos: 1.8 }
+ ListElement{ xPos: 3.4 ; yPos: -0.2 ; zPos: -0.55 }
+ ListElement{ xPos: 0.2 ; yPos: -0.84 ; zPos: 4.6 }
+ ListElement{ xPos: -0.25 ; yPos: -2.4 ; zPos: 2.1 }
+ ListElement{ xPos: -1.15 ; yPos: -3.16 ; zPos: -3.05 }
+ ListElement{ xPos: 1.45 ; yPos: 0.96 ; zPos: -0.7 }
+ ListElement{ xPos: 0.35 ; yPos: 0.52 ; zPos: -1 }
+ ListElement{ xPos: 2.6 ; yPos: 0.28 ; zPos: -0.85 }
+ ListElement{ xPos: -1.25 ; yPos: 0.76 ; zPos: -1.6 }
+ ListElement{ xPos: -0.65 ; yPos: -2.16 ; zPos: 3 }
+ ListElement{ xPos: -0.25 ; yPos: -2.36 ; zPos: -1.8 }
+ ListElement{ xPos: 0.35 ; yPos: -0.8 ; zPos: 1.85 }
+ ListElement{ xPos: 0.05 ; yPos: 0.6 ; zPos: 0.85 }
+ ListElement{ xPos: -2.5 ; yPos: 2.28 ; zPos: -2.05 }
+ ListElement{ xPos: 1.65 ; yPos: 1.2 ; zPos: 2.1 }
+ ListElement{ xPos: -3 ; yPos: -0.24 ; zPos: 0.7 }
+ ListElement{ xPos: -2.1 ; yPos: -0.84 ; zPos: -0.2 }
+ ListElement{ xPos: 0.45 ; yPos: 0.96 ; zPos: 2.5 }
+ ListElement{ xPos: -2.4 ; yPos: 1.28 ; zPos: 2.75 }
+ ListElement{ xPos: -1.7 ; yPos: -3.2 ; zPos: -2.3 }
+ ListElement{ xPos: 0.95 ; yPos: -0.08 ; zPos: 0.3 }
+ ListElement{ xPos: 1.4 ; yPos: 0.88 ; zPos: 0.45 }
+ ListElement{ xPos: 2.1 ; yPos: 1.08 ; zPos: 0.2 }
+ ListElement{ xPos: -2.1 ; yPos: -0.2 ; zPos: -0.6 }
+ ListElement{ xPos: 0.5 ; yPos: 1.24 ; zPos: -0.45 }
+ ListElement{ xPos: 2.55 ; yPos: -0.56 ; zPos: -2.65 }
+ ListElement{ xPos: -4.5 ; yPos: -0.48 ; zPos: -1.25 }
+ ListElement{ xPos: 3.45 ; yPos: -0.44 ; zPos: 2.2 }
+ ListElement{ xPos: -0.25 ; yPos: 0.64 ; zPos: 1.65 }
+ ListElement{ xPos: 1.25 ; yPos: -0.6 ; zPos: -0.35 }
+ ListElement{ xPos: 1.95 ; yPos: -1.56 ; zPos: -4.1 }
+ ListElement{ xPos: 2.75 ; yPos: -1 ; zPos: 3.3 }
+ ListElement{ xPos: 3.05 ; yPos: 1.04 ; zPos: -0.9 }
+ ListElement{ xPos: -2.95 ; yPos: 1.4 ; zPos: -2.25 }
+ ListElement{ xPos: 1.3 ; yPos: 0.36 ; zPos: -2.9 }
+ ListElement{ xPos: 0.4 ; yPos: -2.48 ; zPos: 3.25 }
+ ListElement{ xPos: -1.15 ; yPos: 0.36 ; zPos: 0.45 }
+ ListElement{ xPos: -2.25 ; yPos: 0.04 ; zPos: 0.65 }
+ ListElement{ xPos: -1.85 ; yPos: -0.96 ; zPos: 4.25 }
+ ListElement{ xPos: 1.5 ; yPos: 0.04 ; zPos: -3.85 }
+ ListElement{ xPos: 0.05 ; yPos: 0.68 ; zPos: -2.45 }
+ ListElement{ xPos: -0.1 ; yPos: -0.48 ; zPos: 1.9 }
+ ListElement{ xPos: 2.1 ; yPos: -1.52 ; zPos: -4 }
+ ListElement{ xPos: 3.4 ; yPos: 0 ; zPos: -2.05 }
+ ListElement{ xPos: 0.7 ; yPos: 2.68 ; zPos: -0.85 }
+ ListElement{ xPos: 1.6 ; yPos: 1.68 ; zPos: -0.8 }
+ ListElement{ xPos: 2.1 ; yPos: -2.44 ; zPos: 1.2 }
+ ListElement{ xPos: -0.15 ; yPos: -1.88 ; zPos: -0.35 }
+ ListElement{ xPos: -0.35 ; yPos: 1.76 ; zPos: 1.6 }
+ ListElement{ xPos: -2.15 ; yPos: 0.08 ; zPos: 0.75 }
+ ListElement{ xPos: -0.15 ; yPos: -3.36 ; zPos: 0.35 }
+ ListElement{ xPos: 2.7 ; yPos: -2.84 ; zPos: 0.35 }
+ ListElement{ xPos: -1.35 ; yPos: 0 ; zPos: -0.5 }
+ ListElement{ xPos: -0.35 ; yPos: -2.56 ; zPos: -0.9 }
+ ListElement{ xPos: -2.75 ; yPos: -3.56 ; zPos: 1.55 }
+ ListElement{ xPos: -2.5 ; yPos: -0.68 ; zPos: 2.7 }
+ ListElement{ xPos: 1.35 ; yPos: 0.6 ; zPos: -2.2 }
+ ListElement{ xPos: -1.3 ; yPos: -0.24 ; zPos: -1.65 }
+ ListElement{ xPos: -1.4 ; yPos: -1.44 ; zPos: 4.45 }
+ ListElement{ xPos: -1.8 ; yPos: 3.64 ; zPos: 2.05 }
+ ListElement{ xPos: -0.65 ; yPos: 0.08 ; zPos: 3.9 }
+ ListElement{ xPos: 2.25 ; yPos: 2.96 ; zPos: -2.35 }
+ ListElement{ xPos: 1.3 ; yPos: 1.64 ; zPos: -0.05 }
+ ListElement{ xPos: 1.75 ; yPos: 2.24 ; zPos: -2.85 }
+ ListElement{ xPos: -0.05 ; yPos: -1.56 ; zPos: -0.05 }
+ ListElement{ xPos: -3.85 ; yPos: -0.8 ; zPos: -0.3 }
+ ListElement{ xPos: 0.95 ; yPos: 0.32 ; zPos: -2.5 }
+ ListElement{ xPos: -2.4 ; yPos: 0.4 ; zPos: -3.55 }
+ ListElement{ xPos: 3.7 ; yPos: 2.36 ; zPos: 3.6 }
+ ListElement{ xPos: 0.55 ; yPos: 0.88 ; zPos: 3.15 }
+ ListElement{ xPos: -1 ; yPos: -1.36 ; zPos: -2.1 }
+ ListElement{ xPos: 2.05 ; yPos: 0.44 ; zPos: -0.8 }
+ ListElement{ xPos: -4.75 ; yPos: 1.8 ; zPos: -1.7 }
+ ListElement{ xPos: 0.15 ; yPos: 2.64 ; zPos: -2.2 }
+ ListElement{ xPos: -2.05 ; yPos: -2.56 ; zPos: 1.15 }
+ ListElement{ xPos: -3.7 ; yPos: 2.12 ; zPos: 1.3 }
+ ListElement{ xPos: 1.05 ; yPos: 0 ; zPos: 4 }
+ ListElement{ xPos: -0.7 ; yPos: -0.88 ; zPos: 1.35 }
+ ListElement{ xPos: 0.95 ; yPos: -1.84 ; zPos: 0.1 }
+ ListElement{ xPos: 0.75 ; yPos: 1.16 ; zPos: 4.25 }
+ ListElement{ xPos: -1.3 ; yPos: 0.72 ; zPos: 0.65 }
+ ListElement{ xPos: 3 ; yPos: -0.08 ; zPos: -1.75 }
+ ListElement{ xPos: 2.85 ; yPos: -0.68 ; zPos: 0.65 }
+ ListElement{ xPos: -0.4 ; yPos: 3.04 ; zPos: -2.35 }
+ ListElement{ xPos: 3.05 ; yPos: -0.6 ; zPos: -0.6 }
+ ListElement{ xPos: -0.85 ; yPos: -0.44 ; zPos: 0.35 }
+ ListElement{ xPos: 0 ; yPos: -1.92 ; zPos: 0 }
+ ListElement{ xPos: -1.25 ; yPos: -1.44 ; zPos: 1.9 }
+ ListElement{ xPos: -1.6 ; yPos: 0.04 ; zPos: -0.7 }
+ ListElement{ xPos: 1.45 ; yPos: -1 ; zPos: -3.4 }
+ ListElement{ xPos: -2.8 ; yPos: -1.24 ; zPos: -3 }
+ ListElement{ xPos: 0.2 ; yPos: -0.68 ; zPos: -3.7 }
+ ListElement{ xPos: 3.35 ; yPos: 0.68 ; zPos: -1.9 }
+ ListElement{ xPos: -2.3 ; yPos: 1.08 ; zPos: -1 }
+ ListElement{ xPos: 1.5 ; yPos: 1.8 ; zPos: -1.2 }
+ ListElement{ xPos: 1.55 ; yPos: 3.64 ; zPos: 1.35 }
+ ListElement{ xPos: 1.15 ; yPos: -1.36 ; zPos: 0.75 }
+ ListElement{ xPos: -1.95 ; yPos: 0.08 ; zPos: -0.85 }
+ ListElement{ xPos: -2.25 ; yPos: -0.52 ; zPos: 1.05 }
+ ListElement{ xPos: -2.6 ; yPos: -1.32 ; zPos: 1.05 }
+ ListElement{ xPos: -0.4 ; yPos: -1.52 ; zPos: 2.45 }
+ ListElement{ xPos: -0.05 ; yPos: 0.64 ; zPos: -2.85 }
+ ListElement{ xPos: 4.45 ; yPos: -0.24 ; zPos: -0.15 }
+ ListElement{ xPos: 3.45 ; yPos: 1.72 ; zPos: -1.1 }
+ ListElement{ xPos: 3.3 ; yPos: -1.72 ; zPos: -0.25 }
+ ListElement{ xPos: 1.7 ; yPos: 2.76 ; zPos: 2 }
+ ListElement{ xPos: 2.1 ; yPos: -2.88 ; zPos: -1.75 }
+ ListElement{ xPos: -3.7 ; yPos: -0.04 ; zPos: 0.25 }
+ ListElement{ xPos: -0.45 ; yPos: -3 ; zPos: -2.95 }
+ ListElement{ xPos: 3.1 ; yPos: -2.32 ; zPos: 0.1 }
+ ListElement{ xPos: 0.7 ; yPos: -2.88 ; zPos: -3.45 }
+ ListElement{ xPos: 2.9 ; yPos: 0.4 ; zPos: -0.65 }
+ ListElement{ xPos: -1.8 ; yPos: -2.48 ; zPos: -3.5 }
+ ListElement{ xPos: 1.65 ; yPos: 3.16 ; zPos: 2.15 }
+ ListElement{ xPos: -1.25 ; yPos: -0.76 ; zPos: 2.15 }
+ ListElement{ xPos: 3.55 ; yPos: 0.28 ; zPos: 2.4 }
+ ListElement{ xPos: 0.25 ; yPos: 0.52 ; zPos: 2.3 }
+ ListElement{ xPos: -1.7 ; yPos: -1.36 ; zPos: -2.5 }
+ ListElement{ xPos: 3.8 ; yPos: 1.04 ; zPos: 0.45 }
+ ListElement{ xPos: 2.45 ; yPos: -0.72 ; zPos: -4.05 }
+ ListElement{ xPos: -0.85 ; yPos: 0.16 ; zPos: -0.55 }
+ ListElement{ xPos: 0.65 ; yPos: 0.52 ; zPos: 3.3 }
+ ListElement{ xPos: 0.85 ; yPos: -0.08 ; zPos: 0.6 }
+ ListElement{ xPos: -0.1 ; yPos: 1.12 ; zPos: -3.15 }
+ ListElement{ xPos: -2.95 ; yPos: 0.24 ; zPos: 0.8 }
+ ListElement{ xPos: 0.2 ; yPos: -0.6 ; zPos: -0.45 }
+ ListElement{ xPos: 0.15 ; yPos: 2.52 ; zPos: 1.5 }
+ ListElement{ xPos: 0.65 ; yPos: -1.4 ; zPos: -1.5 }
+ ListElement{ xPos: 4.75 ; yPos: 1.76 ; zPos: 1.15 }
+ ListElement{ xPos: -1.75 ; yPos: -1.44 ; zPos: -3.6 }
+ ListElement{ xPos: 0.85 ; yPos: 0.04 ; zPos: -0.3 }
+ ListElement{ xPos: -0.55 ; yPos: -0.28 ; zPos: -1.85 }
+ ListElement{ xPos: -4.05 ; yPos: 0.52 ; zPos: -2.35 }
+ ListElement{ xPos: -0.35 ; yPos: -0.96 ; zPos: 0.8 }
+ ListElement{ xPos: -1.8 ; yPos: -0.04 ; zPos: 0.05 }
+ ListElement{ xPos: -2 ; yPos: 0.12 ; zPos: -2.5 }
+ ListElement{ xPos: -1.85 ; yPos: -1.04 ; zPos: -1.2 }
+ ListElement{ xPos: -1 ; yPos: -3.44 ; zPos: -1 }
+ ListElement{ xPos: 2.25 ; yPos: 0.16 ; zPos: -0.05 }
+ ListElement{ xPos: -1.3 ; yPos: 0.24 ; zPos: -1.5 }
+ ListElement{ xPos: -0.05 ; yPos: -0.48 ; zPos: 1.7 }
+ ListElement{ xPos: -2.5 ; yPos: 0.28 ; zPos: -2.1 }
+ ListElement{ xPos: 3.9 ; yPos: -0.44 ; zPos: -0.85 }
+ ListElement{ xPos: -0.3 ; yPos: -1.96 ; zPos: 1.3 }
+ ListElement{ xPos: 1.35 ; yPos: 2.92 ; zPos: -1.15 }
+ ListElement{ xPos: -2.2 ; yPos: -2.2 ; zPos: -0.45 }
+ ListElement{ xPos: -0.2 ; yPos: -0.12 ; zPos: 0.15 }
+ ListElement{ xPos: 0.7 ; yPos: 1.4 ; zPos: -3 }
+ ListElement{ xPos: -0.3 ; yPos: 3.16 ; zPos: 2.65 }
+ ListElement{ xPos: -1.1 ; yPos: -1.44 ; zPos: 0.45 }
+ ListElement{ xPos: 0.25 ; yPos: -1.04 ; zPos: 4.3 }
+ ListElement{ xPos: -2.2 ; yPos: -2.48 ; zPos: 0.4 }
+ ListElement{ xPos: 0.95 ; yPos: -3.4 ; zPos: -1.2 }
+ ListElement{ xPos: 2.75 ; yPos: -1.6 ; zPos: -1.95 }
+ ListElement{ xPos: 0.75 ; yPos: -1.84 ; zPos: -0.15 }
+ ListElement{ xPos: -0.75 ; yPos: -1.84 ; zPos: 0.35 }
+ ListElement{ xPos: -2.85 ; yPos: -2.12 ; zPos: -0.95 }
+ ListElement{ xPos: -0.8 ; yPos: -2.84 ; zPos: -0.15 }
+ ListElement{ xPos: -1.95 ; yPos: -0.44 ; zPos: 2.1 }
+ ListElement{ xPos: -1.05 ; yPos: -2.48 ; zPos: -1.25 }
+ ListElement{ xPos: -2.6 ; yPos: -1.48 ; zPos: 0.8 }
+ ListElement{ xPos: 2.5 ; yPos: -1.08 ; zPos: 1.9 }
+ ListElement{ xPos: 0.45 ; yPos: 2.52 ; zPos: 0.45 }
+ ListElement{ xPos: 1.55 ; yPos: -0.16 ; zPos: 0.25 }
+ ListElement{ xPos: -2.9 ; yPos: 0.36 ; zPos: 0.35 }
+ ListElement{ xPos: 2.95 ; yPos: -1.56 ; zPos: -2.7 }
+ ListElement{ xPos: 3.4 ; yPos: -1.76 ; zPos: 3.05 }
+ ListElement{ xPos: 1.75 ; yPos: -2.84 ; zPos: 0.5 }
+ ListElement{ xPos: -0.95 ; yPos: 0.64 ; zPos: 1.1 }
+ ListElement{ xPos: 2 ; yPos: 2.04 ; zPos: 0.1 }
+ ListElement{ xPos: -0.15 ; yPos: -0.08 ; zPos: -0.9 }
+ ListElement{ xPos: 2.2 ; yPos: -1.2 ; zPos: 2.8 }
+ ListElement{ xPos: -0.8 ; yPos: 2.68 ; zPos: -0.3 }
+ ListElement{ xPos: 3.4 ; yPos: 0.84 ; zPos: -2.65 }
+ ListElement{ xPos: -0.25 ; yPos: -0.24 ; zPos: 0.45 }
+ ListElement{ xPos: 2.7 ; yPos: 1.64 ; zPos: -1.95 }
+ ListElement{ xPos: 1.35 ; yPos: -2.96 ; zPos: 0.65 }
+ ListElement{ xPos: -1.45 ; yPos: -0.2 ; zPos: 0.8 }
+ ListElement{ xPos: 1.45 ; yPos: 1.64 ; zPos: -3.45 }
+ ListElement{ xPos: -1.1 ; yPos: 3.08 ; zPos: 1.1 }
+ ListElement{ xPos: 0.8 ; yPos: 1.88 ; zPos: -2.1 }
+ ListElement{ xPos: 1.15 ; yPos: 3.04 ; zPos: -0.75 }
+ ListElement{ xPos: -0.45 ; yPos: 1.36 ; zPos: -0.15 }
+ ListElement{ xPos: -2.8 ; yPos: -1.24 ; zPos: 2.55 }
+ ListElement{ xPos: 4.4 ; yPos: 2.04 ; zPos: 1.25 }
+ ListElement{ xPos: -0.95 ; yPos: 1.24 ; zPos: 3.65 }
+ ListElement{ xPos: 3.45 ; yPos: 1.32 ; zPos: 2.5 }
+ ListElement{ xPos: -3 ; yPos: 1.12 ; zPos: -1.2 }
+ ListElement{ xPos: -2.45 ; yPos: 0.68 ; zPos: 4.35 }
+ ListElement{ xPos: 0.55 ; yPos: -0.12 ; zPos: -3.95 }
+ ListElement{ xPos: -0.35 ; yPos: 3.08 ; zPos: -0.3 }
+ ListElement{ xPos: 1.35 ; yPos: -2.92 ; zPos: -3.3 }
+ ListElement{ xPos: 0.5 ; yPos: -0.2 ; zPos: 0.95 }
+ ListElement{ xPos: 1.2 ; yPos: -0.24 ; zPos: -0.75 }
+ ListElement{ xPos: -1.2 ; yPos: 2.16 ; zPos: 3.35 }
+ ListElement{ xPos: -3.35 ; yPos: 2.36 ; zPos: 3.45 }
+ ListElement{ xPos: 0.95 ; yPos: -0.88 ; zPos: 1.25 }
+ ListElement{ xPos: 0.1 ; yPos: 1.24 ; zPos: 0 }
+ ListElement{ xPos: 1.8 ; yPos: 1.56 ; zPos: -1.05 }
+ ListElement{ xPos: -1.35 ; yPos: 3.8 ; zPos: -1.45 }
+ ListElement{ xPos: 1.45 ; yPos: -2.64 ; zPos: 0.5 }
+ ListElement{ xPos: 2.05 ; yPos: 1.16 ; zPos: 1.4 }
+ ListElement{ xPos: 2.9 ; yPos: -2.4 ; zPos: 0.15 }
+ ListElement{ xPos: -1.1 ; yPos: 0.76 ; zPos: -1.65 }
+ ListElement{ xPos: -2.5 ; yPos: -2.4 ; zPos: 1.05 }
+ ListElement{ xPos: 3.55 ; yPos: -1.8 ; zPos: -2.55 }
+ ListElement{ xPos: -0.8 ; yPos: 1.24 ; zPos: -3.75 }
+ ListElement{ xPos: -1.35 ; yPos: -2.48 ; zPos: 2.85 }
+ ListElement{ xPos: -2.1 ; yPos: 1.48 ; zPos: -0.15 }
+ ListElement{ xPos: -0.45 ; yPos: 2.68 ; zPos: 2.85 }
+ ListElement{ xPos: 0.8 ; yPos: 1.4 ; zPos: -3.35 }
+ ListElement{ xPos: -2.2 ; yPos: -2.24 ; zPos: 0.35 }
+ ListElement{ xPos: 1.4 ; yPos: -2.32 ; zPos: 0.55 }
+ ListElement{ xPos: 3.65 ; yPos: 1.12 ; zPos: -4.5 }
+ ListElement{ xPos: 0.1 ; yPos: -0.68 ; zPos: 1.85 }
+ ListElement{ xPos: -1.95 ; yPos: -0.56 ; zPos: -2.05 }
+ ListElement{ xPos: 1.85 ; yPos: 1.32 ; zPos: -4.4 }
+ ListElement{ xPos: -0.6 ; yPos: 0.64 ; zPos: -0.3 }
+ ListElement{ xPos: -1.55 ; yPos: 1.52 ; zPos: -3.75 }
+ ListElement{ xPos: 1.85 ; yPos: 0.48 ; zPos: 0.65 }
+ ListElement{ xPos: 3.35 ; yPos: 2.52 ; zPos: 1.9 }
+ ListElement{ xPos: 0.4 ; yPos: 1.4 ; zPos: -1.3 }
+ ListElement{ xPos: -2.7 ; yPos: 0.84 ; zPos: 1.6 }
+ ListElement{ xPos: -0.5 ; yPos: 1 ; zPos: 0.4 }
+ ListElement{ xPos: 2.25 ; yPos: -1 ; zPos: 1.25 }
+ ListElement{ xPos: 1.7 ; yPos: 2.4 ; zPos: -0.95 }
+ ListElement{ xPos: -3.55 ; yPos: 1.04 ; zPos: 3.95 }
+ ListElement{ xPos: 0.9 ; yPos: 1.28 ; zPos: 2.05 }
+ ListElement{ xPos: -3.15 ; yPos: 1.96 ; zPos: -0.3 }
+ ListElement{ xPos: 1.35 ; yPos: -0.92 ; zPos: -1 }
+ ListElement{ xPos: -3.1 ; yPos: -3.08 ; zPos: 0.9 }
+ ListElement{ xPos: 1.25 ; yPos: -2.44 ; zPos: 2.25 }
+ ListElement{ xPos: -3.8 ; yPos: 0.76 ; zPos: -1.05 }
+ ListElement{ xPos: -1.05 ; yPos: -3.8 ; zPos: -0.8 }
+ ListElement{ xPos: -4 ; yPos: 1.24 ; zPos: -2.6 }
+ ListElement{ xPos: 2.45 ; yPos: -1.84 ; zPos: 0.35 }
+ ListElement{ xPos: -1.5 ; yPos: 2.16 ; zPos: 4.3 }
+ ListElement{ xPos: 2.1 ; yPos: -1.8 ; zPos: -0.95 }
+ ListElement{ xPos: -1.8 ; yPos: -0.2 ; zPos: 0.2 }
+ ListElement{ xPos: 0.75 ; yPos: 1.04 ; zPos: -1.3 }
+ ListElement{ xPos: 2.85 ; yPos: 1.6 ; zPos: -2.05 }
+ ListElement{ xPos: -2 ; yPos: -0.2 ; zPos: -2.15 }
+ ListElement{ xPos: 1.75 ; yPos: 2.28 ; zPos: 0.75 }
+ ListElement{ xPos: 1.95 ; yPos: -0.68 ; zPos: -2.3 }
+ ListElement{ xPos: -0.8 ; yPos: 1.08 ; zPos: 1.65 }
+ ListElement{ xPos: -1.85 ; yPos: 1.8 ; zPos: -0.75 }
+ ListElement{ xPos: -3.05 ; yPos: 2.44 ; zPos: 0.35 }
+ ListElement{ xPos: -0.4 ; yPos: -3 ; zPos: -2.85 }
+ ListElement{ xPos: -0.95 ; yPos: 0.64 ; zPos: 2.15 }
+ ListElement{ xPos: -1.35 ; yPos: -0.2 ; zPos: -0.8 }
+ ListElement{ xPos: 2.1 ; yPos: -0.04 ; zPos: 0.65 }
+ ListElement{ xPos: 2.6 ; yPos: 0.2 ; zPos: 2.75 }
+ ListElement{ xPos: 1.65 ; yPos: -0.16 ; zPos: 1.65 }
+ ListElement{ xPos: -1.85 ; yPos: 0.68 ; zPos: 1.95 }
+ ListElement{ xPos: -3.05 ; yPos: -2.28 ; zPos: 0.1 }
+ ListElement{ xPos: 3.4 ; yPos: -1.88 ; zPos: 3 }
+ ListElement{ xPos: -0.75 ; yPos: 0.36 ; zPos: 1.5 }
+ ListElement{ xPos: 2.9 ; yPos: -1 ; zPos: -1.85 }
+ ListElement{ xPos: 0.4 ; yPos: 1.08 ; zPos: 0.8 }
+ ListElement{ xPos: -1.05 ; yPos: 1.04 ; zPos: 2.15 }
+ ListElement{ xPos: 2.6 ; yPos: -2.08 ; zPos: -0.1 }
+ ListElement{ xPos: 0 ; yPos: -2.84 ; zPos: -0.95 }
+ ListElement{ xPos: 0.4 ; yPos: 1.88 ; zPos: 2.05 }
+ ListElement{ xPos: -3.1 ; yPos: -2.76 ; zPos: -2.75 }
+ ListElement{ xPos: -2.65 ; yPos: 3.52 ; zPos: -1.2 }
+ ListElement{ xPos: -4.3 ; yPos: -0.28 ; zPos: 3 }
+ ListElement{ xPos: -2.8 ; yPos: -2.56 ; zPos: -2.85 }
+ ListElement{ xPos: -0.15 ; yPos: 2.72 ; zPos: -2.8 }
+ ListElement{ xPos: -0.95 ; yPos: -0.6 ; zPos: 1.05 }
+ ListElement{ xPos: 1.9 ; yPos: 2.56 ; zPos: 1.25 }
+ ListElement{ xPos: -0.85 ; yPos: 0.24 ; zPos: 0.05 }
+ ListElement{ xPos: 2.4 ; yPos: 2.56 ; zPos: -1.2 }
+ ListElement{ xPos: 2.35 ; yPos: -1.08 ; zPos: 2.7 }
+ ListElement{ xPos: -2.1 ; yPos: -0.76 ; zPos: 2.8 }
+ ListElement{ xPos: 1.4 ; yPos: 1 ; zPos: 2.35 }
+ ListElement{ xPos: -0.9 ; yPos: 1.72 ; zPos: 4.1 }
+ ListElement{ xPos: 3.7 ; yPos: -1.4 ; zPos: 2.05 }
+ ListElement{ xPos: -0.25 ; yPos: 0.76 ; zPos: -1.4 }
+ ListElement{ xPos: -1.6 ; yPos: 0.32 ; zPos: 0.05 }
+ ListElement{ xPos: 2.5 ; yPos: -3.08 ; zPos: 0.85 }
+ ListElement{ xPos: 0.05 ; yPos: -1.96 ; zPos: 1.55 }
+ ListElement{ xPos: -3.7 ; yPos: 0.84 ; zPos: -0.25 }
+ ListElement{ xPos: 2.35 ; yPos: 0.6 ; zPos: -1.5 }
+ ListElement{ xPos: 1.1 ; yPos: 2.64 ; zPos: -1.45 }
+ ListElement{ xPos: 2.55 ; yPos: -1.56 ; zPos: 2.05 }
+ ListElement{ xPos: -2.15 ; yPos: 3.56 ; zPos: 3.25 }
+ ListElement{ xPos: -0.55 ; yPos: -1.24 ; zPos: 2.65 }
+ ListElement{ xPos: -0.3 ; yPos: 1.32 ; zPos: 0.85 }
+ ListElement{ xPos: -1.9 ; yPos: 1.24 ; zPos: 1.15 }
+ ListElement{ xPos: 0.35 ; yPos: -2.44 ; zPos: -1.35 }
+ ListElement{ xPos: 2.9 ; yPos: -1.08 ; zPos: -4.3 }
+ ListElement{ xPos: 1.8 ; yPos: -0.44 ; zPos: 1.25 }
+ ListElement{ xPos: -0.6 ; yPos: -1.08 ; zPos: -0.6 }
+ ListElement{ xPos: -0.3 ; yPos: -0.88 ; zPos: -1.45 }
+ ListElement{ xPos: -1 ; yPos: 2.12 ; zPos: 2.3 }
+ ListElement{ xPos: 3.15 ; yPos: 0.52 ; zPos: -2.8 }
+ ListElement{ xPos: 0.45 ; yPos: 2.48 ; zPos: -1.3 }
+ ListElement{ xPos: 0.5 ; yPos: -0.84 ; zPos: 0.7 }
+ ListElement{ xPos: -0.6 ; yPos: -0.44 ; zPos: -1.35 }
+ ListElement{ xPos: -1.7 ; yPos: -0.12 ; zPos: -2.55 }
+ ListElement{ xPos: -0.5 ; yPos: 0.52 ; zPos: 1.4 }
+ ListElement{ xPos: 4 ; yPos: -1.68 ; zPos: -0.1 }
+ ListElement{ xPos: 1.4 ; yPos: -1.64 ; zPos: 1.35 }
+ ListElement{ xPos: 0.05 ; yPos: 0.28 ; zPos: -2.2 }
+ ListElement{ xPos: 1.55 ; yPos: -1.2 ; zPos: 0.45 }
+ ListElement{ xPos: 3.1 ; yPos: 3.64 ; zPos: 1.45 }
+ ListElement{ xPos: -1.55 ; yPos: 2.16 ; zPos: 0.15 }
+ ListElement{ xPos: 3.9 ; yPos: -2.56 ; zPos: -1.25 }
+ ListElement{ xPos: 4.15 ; yPos: 0.64 ; zPos: 2.65 }
+ ListElement{ xPos: -2.8 ; yPos: 0.56 ; zPos: -1.35 }
+ ListElement{ xPos: 1.3 ; yPos: 1.28 ; zPos: 0.8 }
+ ListElement{ xPos: -2.3 ; yPos: -3.08 ; zPos: 1.2 }
+ ListElement{ xPos: 0.5 ; yPos: -0.36 ; zPos: -2.4 }
+ ListElement{ xPos: 0.6 ; yPos: 0.52 ; zPos: 2.75 }
+ ListElement{ xPos: 3.9 ; yPos: -0.52 ; zPos: -4.25 }
+ ListElement{ xPos: -0.5 ; yPos: 1.28 ; zPos: -0.05 }
+ ListElement{ xPos: -0.25 ; yPos: -3.84 ; zPos: 3.15 }
+ ListElement{ xPos: -0.9 ; yPos: -1.72 ; zPos: -3.15 }
+ ListElement{ xPos: 0.85 ; yPos: 0.84 ; zPos: -1.7 }
+ ListElement{ xPos: -3.35 ; yPos: 0.72 ; zPos: 2.15 }
+ ListElement{ xPos: -1.6 ; yPos: 0.6 ; zPos: 1.65 }
+ ListElement{ xPos: -3.6 ; yPos: 0.8 ; zPos: 2.6 }
+ ListElement{ xPos: -0.7 ; yPos: 1.96 ; zPos: -0.9 }
+ ListElement{ xPos: -2.4 ; yPos: 1.32 ; zPos: -2.75 }
+ ListElement{ xPos: -1.75 ; yPos: 0.72 ; zPos: -0.85 }
+ ListElement{ xPos: -2.7 ; yPos: 0.6 ; zPos: -2.5 }
+ ListElement{ xPos: -2.2 ; yPos: -3.4 ; zPos: -1.85 }
+ ListElement{ xPos: 0.85 ; yPos: 2.2 ; zPos: -3.75 }
+ ListElement{ xPos: -3.85 ; yPos: 2.44 ; zPos: 4.3 }
+ ListElement{ xPos: -3.65 ; yPos: 0.52 ; zPos: 0.2 }
+ ListElement{ xPos: -4.35 ; yPos: -0.52 ; zPos: 1.5 }
+ ListElement{ xPos: 1.45 ; yPos: -0.08 ; zPos: -0.4 }
+ ListElement{ xPos: 1.85 ; yPos: -0.76 ; zPos: -4.6 }
+ ListElement{ xPos: 0.95 ; yPos: 0.52 ; zPos: -1 }
+ ListElement{ xPos: -2.5 ; yPos: -0.88 ; zPos: -0.3 }
+ ListElement{ xPos: -2.9 ; yPos: 1.68 ; zPos: -1.15 }
+ ListElement{ xPos: -3.2 ; yPos: 0.2 ; zPos: 1.1 }
+ ListElement{ xPos: 0.9 ; yPos: -0.2 ; zPos: 0.7 }
+ ListElement{ xPos: 3.6 ; yPos: 1.08 ; zPos: -2.15 }
+ ListElement{ xPos: -0.8 ; yPos: 1.72 ; zPos: 2.85 }
+ ListElement{ xPos: 0.3 ; yPos: 1.76 ; zPos: 0.9 }
+ ListElement{ xPos: -1.3 ; yPos: -0.56 ; zPos: -2.3 }
+ ListElement{ xPos: -2.8 ; yPos: 0.4 ; zPos: 4.2 }
+ ListElement{ xPos: 1 ; yPos: -0.32 ; zPos: 0.35 }
+ ListElement{ xPos: -0.6 ; yPos: -0.24 ; zPos: 4.05 }
+ ListElement{ xPos: -2 ; yPos: -1.84 ; zPos: -2.2 }
+ ListElement{ xPos: -1.95 ; yPos: -0.8 ; zPos: 1.85 }
+ ListElement{ xPos: -0.05 ; yPos: -0.16 ; zPos: 3.85 }
+ ListElement{ xPos: 0.15 ; yPos: -2.64 ; zPos: 1.7 }
+ ListElement{ xPos: -3.85 ; yPos: 1.4 ; zPos: 0.1 }
+ ListElement{ xPos: 0.25 ; yPos: 1 ; zPos: -2.45 }
+ ListElement{ xPos: -4.1 ; yPos: 0 ; zPos: -0.1 }
+ ListElement{ xPos: -1.4 ; yPos: -0.32 ; zPos: -0.8 }
+ ListElement{ xPos: -1.9 ; yPos: -1.84 ; zPos: -3 }
+ ListElement{ xPos: 0.35 ; yPos: 1.32 ; zPos: -3.95 }
+ ListElement{ xPos: -2.6 ; yPos: -1.04 ; zPos: 4.25 }
+ ListElement{ xPos: -3.1 ; yPos: -0.96 ; zPos: -1.65 }
+ ListElement{ xPos: -0.55 ; yPos: -1.16 ; zPos: 4.05 }
+ ListElement{ xPos: -3.1 ; yPos: -1 ; zPos: -0.5 }
+ ListElement{ xPos: 2.25 ; yPos: 1.24 ; zPos: 3.4 }
+ ListElement{ xPos: -1.2 ; yPos: -1.24 ; zPos: -4.05 }
+ ListElement{ xPos: 3.05 ; yPos: 1.92 ; zPos: 1 }
+ ListElement{ xPos: 0.55 ; yPos: -2.76 ; zPos: -3.25 }
+ ListElement{ xPos: -2.05 ; yPos: 1.6 ; zPos: 0.6 }
+ ListElement{ xPos: -0.45 ; yPos: 0.12 ; zPos: -0.15 }
+ ListElement{ xPos: 2.1 ; yPos: 2.96 ; zPos: 1.1 }
+ ListElement{ xPos: 0.05 ; yPos: -2.08 ; zPos: -0.7 }
+ ListElement{ xPos: -3.15 ; yPos: 1.08 ; zPos: -0.1 }
+ ListElement{ xPos: -1.95 ; yPos: 0.44 ; zPos: 0.6 }
+ ListElement{ xPos: 0.15 ; yPos: -0.32 ; zPos: 2.85 }
+ ListElement{ xPos: 0.55 ; yPos: 1 ; zPos: 0.55 }
+ ListElement{ xPos: -2.05 ; yPos: 1.84 ; zPos: -1 }
+ ListElement{ xPos: -0.25 ; yPos: 0.36 ; zPos: 1.2 }
+ ListElement{ xPos: 4.6 ; yPos: -0.2 ; zPos: 0.6 }
+ ListElement{ xPos: -1.95 ; yPos: -0.8 ; zPos: 0.05 }
+ ListElement{ xPos: -0.35 ; yPos: -1.04 ; zPos: 0.8 }
+ ListElement{ xPos: 0.7 ; yPos: 3.04 ; zPos: -3.55 }
+ ListElement{ xPos: -0.15 ; yPos: 1.12 ; zPos: -2.5 }
+ ListElement{ xPos: -0.5 ; yPos: -1.68 ; zPos: 1.5 }
+ ListElement{ xPos: 1 ; yPos: -0.44 ; zPos: -1.5 }
+ ListElement{ xPos: 4.05 ; yPos: -1.32 ; zPos: 2.85 }
+ ListElement{ xPos: 1.6 ; yPos: -1.56 ; zPos: 2.15 }
+ ListElement{ xPos: 0.3 ; yPos: -1.16 ; zPos: 1.25 }
+ ListElement{ xPos: -2.65 ; yPos: -1.28 ; zPos: 0.45 }
+ ListElement{ xPos: 0 ; yPos: 1.52 ; zPos: -1.35 }
+ ListElement{ xPos: 1.3 ; yPos: 1.68 ; zPos: -2.75 }
+ ListElement{ xPos: 1.25 ; yPos: 0.4 ; zPos: 0.3 }
+ ListElement{ xPos: -0.95 ; yPos: 3.68 ; zPos: 1.75 }
+ ListElement{ xPos: -3.55 ; yPos: 0.48 ; zPos: 1.15 }
+ ListElement{ xPos: -1.7 ; yPos: -2.64 ; zPos: -3.3 }
+ ListElement{ xPos: -2.2 ; yPos: -2.4 ; zPos: 1.05 }
+ ListElement{ xPos: 0.1 ; yPos: 0.44 ; zPos: -1.05 }
+ ListElement{ xPos: 2.05 ; yPos: 0.4 ; zPos: 0.8 }
+ ListElement{ xPos: 0.4 ; yPos: 0.04 ; zPos: 4.2 }
+ ListElement{ xPos: -1.25 ; yPos: 0.76 ; zPos: 0.45 }
+ ListElement{ xPos: 1.6 ; yPos: 2.04 ; zPos: -2.95 }
+ ListElement{ xPos: -2.05 ; yPos: -0.44 ; zPos: 1.35 }
+ ListElement{ xPos: -3.25 ; yPos: 0.44 ; zPos: 2.15 }
+ ListElement{ xPos: -1.75 ; yPos: 0.04 ; zPos: 2.35 }
+ ListElement{ xPos: -4.15 ; yPos: 0.68 ; zPos: 0.8 }
+ ListElement{ xPos: -1.6 ; yPos: 1.12 ; zPos: 0.55 }
+ ListElement{ xPos: -0.15 ; yPos: 3.4 ; zPos: 3.05 }
+ ListElement{ xPos: -0.2 ; yPos: 0.04 ; zPos: -1.45 }
+ ListElement{ xPos: 2.9 ; yPos: -0.36 ; zPos: 1.45 }
+ ListElement{ xPos: -1.4 ; yPos: 1.56 ; zPos: 1 }
+ ListElement{ xPos: 3.4 ; yPos: -1.2 ; zPos: -4.2 }
+ ListElement{ xPos: -1.1 ; yPos: 0.6 ; zPos: 1.55 }
+ ListElement{ xPos: -0.35 ; yPos: 1.52 ; zPos: -0.35 }
+ ListElement{ xPos: 0.3 ; yPos: 0.96 ; zPos: 1.8 }
+ ListElement{ xPos: 2.5 ; yPos: -1.84 ; zPos: 1.65 }
+ ListElement{ xPos: -0.6 ; yPos: 2.24 ; zPos: -2.9 }
+ ListElement{ xPos: -0.25 ; yPos: -2.32 ; zPos: -0.7 }
+ ListElement{ xPos: 3.35 ; yPos: -2.24 ; zPos: 1.5 }
+ ListElement{ xPos: 1.6 ; yPos: 1.96 ; zPos: 3.9 }
+ ListElement{ xPos: 1.8 ; yPos: 0.68 ; zPos: -1.55 }
+ ListElement{ xPos: 2.7 ; yPos: 1.76 ; zPos: -2.9 }
+ ListElement{ xPos: -2.35 ; yPos: -0.6 ; zPos: -3.9 }
+ ListElement{ xPos: -1.85 ; yPos: 1.96 ; zPos: -1.2 }
+ ListElement{ xPos: -4.05 ; yPos: 1.12 ; zPos: -2.75 }
+ ListElement{ xPos: -2.85 ; yPos: -1.36 ; zPos: 0.65 }
+ ListElement{ xPos: -1.75 ; yPos: 2.12 ; zPos: -1.35 }
+ ListElement{ xPos: -2.95 ; yPos: -0.08 ; zPos: 3.65 }
+ ListElement{ xPos: -2.4 ; yPos: 2 ; zPos: 4.5 }
+ ListElement{ xPos: -0.05 ; yPos: 0.04 ; zPos: 0.35 }
+ ListElement{ xPos: -3.2 ; yPos: 0.16 ; zPos: 1.1 }
+ ListElement{ xPos: 3 ; yPos: 2.32 ; zPos: 1.3 }
+ ListElement{ xPos: 4.9 ; yPos: -1.88 ; zPos: 0.45 }
+ ListElement{ xPos: -2.35 ; yPos: -1.44 ; zPos: -0.7 }
+ ListElement{ xPos: 2.4 ; yPos: -0.6 ; zPos: 0.1 }
+ ListElement{ xPos: 1 ; yPos: 1.6 ; zPos: 1 }
+ ListElement{ xPos: 1.3 ; yPos: -0.4 ; zPos: -0.4 }
+ ListElement{ xPos: -0.9 ; yPos: -2.72 ; zPos: -3.6 }
+ ListElement{ xPos: 1.2 ; yPos: -0.44 ; zPos: 2.1 }
+ ListElement{ xPos: 0.65 ; yPos: 3 ; zPos: -1.55 }
+ ListElement{ xPos: -1.55 ; yPos: -2.64 ; zPos: 0.55 }
+ ListElement{ xPos: 1.9 ; yPos: -0.32 ; zPos: -2.1 }
+ ListElement{ xPos: 1.35 ; yPos: -2.84 ; zPos: -0.4 }
+ ListElement{ xPos: 0.25 ; yPos: -2.68 ; zPos: -0.2 }
+ ListElement{ xPos: -2.05 ; yPos: -1.6 ; zPos: -3.05 }
+ ListElement{ xPos: 1.65 ; yPos: -0.44 ; zPos: -0.75 }
+ ListElement{ xPos: -1.25 ; yPos: 0.96 ; zPos: -4.15 }
+ ListElement{ xPos: -4.2 ; yPos: -0.56 ; zPos: 1.45 }
+ ListElement{ xPos: 0.95 ; yPos: -2.4 ; zPos: -1.6 }
+ ListElement{ xPos: -0.05 ; yPos: 0.88 ; zPos: 3.15 }
+ ListElement{ xPos: -1.65 ; yPos: -0.88 ; zPos: -3.85 }
+ ListElement{ xPos: 0.35 ; yPos: 0.2 ; zPos: 4.25 }
+ ListElement{ xPos: 0.8 ; yPos: 0.84 ; zPos: 3.1 }
+ ListElement{ xPos: 1.85 ; yPos: -2.16 ; zPos: -2.2 }
+ ListElement{ xPos: -2.05 ; yPos: 0.16 ; zPos: -0.4 }
+ ListElement{ xPos: 0.85 ; yPos: 1.84 ; zPos: -1.45 }
+ ListElement{ xPos: 1.6 ; yPos: 1.56 ; zPos: -1.45 }
+ ListElement{ xPos: 1.25 ; yPos: -0.84 ; zPos: -2.95 }
+ ListElement{ xPos: -1.9 ; yPos: 2.32 ; zPos: -1.8 }
+ ListElement{ xPos: -0.6 ; yPos: 2.4 ; zPos: -3.65 }
+ ListElement{ xPos: 4.45 ; yPos: 0.52 ; zPos: 3 }
+ ListElement{ xPos: 2.7 ; yPos: 0.28 ; zPos: -1.8 }
+ ListElement{ xPos: 0.35 ; yPos: -2.56 ; zPos: 3.9 }
+ ListElement{ xPos: -0.95 ; yPos: -1.28 ; zPos: 1.6 }
+ ListElement{ xPos: 0.4 ; yPos: -0.2 ; zPos: -2.15 }
+ ListElement{ xPos: -0.05 ; yPos: -1.08 ; zPos: -4.1 }
+ ListElement{ xPos: 3.1 ; yPos: -1.2 ; zPos: -3.85 }
+ ListElement{ xPos: 0.75 ; yPos: 0.12 ; zPos: -3.1 }
+ ListElement{ xPos: -1.65 ; yPos: -1.16 ; zPos: -1.65 }
+ ListElement{ xPos: -1.65 ; yPos: 3.84 ; zPos: 4.65 }
+ ListElement{ xPos: 2.8 ; yPos: -2.6 ; zPos: -1.65 }
+ ListElement{ xPos: 1.2 ; yPos: -2.76 ; zPos: -2.2 }
+ ListElement{ xPos: 0.4 ; yPos: 3.04 ; zPos: 3.45 }
+ ListElement{ xPos: -3.6 ; yPos: 1.04 ; zPos: -0.6 }
+ ListElement{ xPos: 2.25 ; yPos: 1.64 ; zPos: 2.9 }
+ ListElement{ xPos: -3.05 ; yPos: -0.76 ; zPos: -2.3 }
+ ListElement{ xPos: -2.85 ; yPos: 2.12 ; zPos: -0.65 }
+ ListElement{ xPos: -0.1 ; yPos: 0.08 ; zPos: -1.6 }
+ ListElement{ xPos: -1.55 ; yPos: -1.36 ; zPos: 2.2 }
+ ListElement{ xPos: -0.4 ; yPos: 1.56 ; zPos: -0.3 }
+ ListElement{ xPos: 0.3 ; yPos: -2.36 ; zPos: 1.35 }
+ ListElement{ xPos: 0.2 ; yPos: -0.6 ; zPos: 1.6 }
+ ListElement{ xPos: -0.65 ; yPos: 1.96 ; zPos: -3.1 }
+ ListElement{ xPos: 0.6 ; yPos: -1.04 ; zPos: 2.5 }
+ ListElement{ xPos: -2 ; yPos: -1.08 ; zPos: -0.85 }
+ ListElement{ xPos: 1.45 ; yPos: -2.56 ; zPos: -2.6 }
+ ListElement{ xPos: -2.45 ; yPos: 0.04 ; zPos: -2.85 }
+ ListElement{ xPos: -0.05 ; yPos: -1.24 ; zPos: -1.25 }
+ ListElement{ xPos: -2.95 ; yPos: -1.8 ; zPos: -2.05 }
+ ListElement{ xPos: 4.3 ; yPos: -0.96 ; zPos: 3.5 }
+ ListElement{ xPos: 2.15 ; yPos: -1.6 ; zPos: -0.8 }
+ ListElement{ xPos: -1.2 ; yPos: -1 ; zPos: 1.75 }
+ ListElement{ xPos: -1.5 ; yPos: -1.28 ; zPos: -0.25 }
+ ListElement{ xPos: 2.5 ; yPos: -2.6 ; zPos: -0.3 }
+ ListElement{ xPos: -1.6 ; yPos: -0.36 ; zPos: 3.15 }
+ ListElement{ xPos: -0.1 ; yPos: -0.64 ; zPos: -3.6 }
+ ListElement{ xPos: -1.9 ; yPos: 1.88 ; zPos: 2.1 }
+ ListElement{ xPos: -2.85 ; yPos: -2.28 ; zPos: -1.55 }
+ ListElement{ xPos: -1.3 ; yPos: -0.48 ; zPos: -2.2 }
+ ListElement{ xPos: 0.5 ; yPos: 0.28 ; zPos: 0.65 }
+ ListElement{ xPos: -1.1 ; yPos: 0.24 ; zPos: -2.25 }
+ ListElement{ xPos: 1.75 ; yPos: -1.4 ; zPos: 0.3 }
+ ListElement{ xPos: 1.5 ; yPos: -1.32 ; zPos: -2.8 }
+ ListElement{ xPos: -0.95 ; yPos: 2.08 ; zPos: -0.3 }
+ ListElement{ xPos: 2.75 ; yPos: 0.24 ; zPos: 0.75 }
+ ListElement{ xPos: 0.75 ; yPos: 0.56 ; zPos: -1.5 }
+ ListElement{ xPos: 1.1 ; yPos: -3.76 ; zPos: 0 }
+ ListElement{ xPos: 0.3 ; yPos: -1.2 ; zPos: 2.6 }
+ ListElement{ xPos: -0.25 ; yPos: 2.68 ; zPos: -3 }
+ ListElement{ xPos: 1.8 ; yPos: -0.76 ; zPos: 4.4 }
+ ListElement{ xPos: 0 ; yPos: 0 ; zPos: -1.9 }
+ ListElement{ xPos: -1.6 ; yPos: -0.12 ; zPos: -2.4 }
+ ListElement{ xPos: -1.25 ; yPos: 2.36 ; zPos: -2.9 }
+ ListElement{ xPos: 2.65 ; yPos: 0.04 ; zPos: 0.1 }
+ ListElement{ xPos: -3.35 ; yPos: 0.08 ; zPos: -1.3 }
+ ListElement{ xPos: 3.35 ; yPos: 0.04 ; zPos: 2.8 }
+ ListElement{ xPos: 4.45 ; yPos: 1.24 ; zPos: -0.95 }
+ ListElement{ xPos: -0.1 ; yPos: -1.52 ; zPos: -4.6 }
+ ListElement{ xPos: 1.1 ; yPos: 1.72 ; zPos: -3.2 }
+ ListElement{ xPos: -0.45 ; yPos: 1.92 ; zPos: 1.2 }
+ ListElement{ xPos: -0.7 ; yPos: -0.16 ; zPos: 0.8 }
+ ListElement{ xPos: 2.3 ; yPos: 0.2 ; zPos: 2.75 }
+ ListElement{ xPos: 1.7 ; yPos: 2.08 ; zPos: -0.95 }
+ ListElement{ xPos: 2.1 ; yPos: 1.56 ; zPos: 1.2 }
+ ListElement{ xPos: 3.05 ; yPos: -1.56 ; zPos: -0.45 }
+ ListElement{ xPos: 0.1 ; yPos: -3.08 ; zPos: -1.3 }
+ ListElement{ xPos: 1.65 ; yPos: -0.32 ; zPos: -0.8 }
+ ListElement{ xPos: 2.05 ; yPos: -1.8 ; zPos: 1.8 }
+ ListElement{ xPos: -0.55 ; yPos: 1.52 ; zPos: -0.8 }
+ ListElement{ xPos: -2.05 ; yPos: 1.52 ; zPos: 2.3 }
+ ListElement{ xPos: -2.35 ; yPos: -3.28 ; zPos: 3.5 }
+ ListElement{ xPos: -2.25 ; yPos: 2.56 ; zPos: -1.9 }
+ ListElement{ xPos: 0.3 ; yPos: -3.28 ; zPos: 3.4 }
+ ListElement{ xPos: 0.95 ; yPos: -1.68 ; zPos: -1.8 }
+ ListElement{ xPos: 2 ; yPos: 2.2 ; zPos: -0.05 }
+ ListElement{ xPos: 3 ; yPos: 2.92 ; zPos: -2.1 }
+ ListElement{ xPos: 2.55 ; yPos: 3.12 ; zPos: 2.95 }
+ ListElement{ xPos: -0.5 ; yPos: -2.8 ; zPos: -0.3 }
+ ListElement{ xPos: 0.35 ; yPos: 0.64 ; zPos: 0.35 }
+ ListElement{ xPos: -1.15 ; yPos: -0.16 ; zPos: -0.45 }
+ ListElement{ xPos: -2.4 ; yPos: -0.88 ; zPos: -0.3 }
+ ListElement{ xPos: 1.55 ; yPos: -1.48 ; zPos: -0.5 }
+ ListElement{ xPos: -0.85 ; yPos: -2.08 ; zPos: -1.1 }
+ ListElement{ xPos: 0.5 ; yPos: -0.8 ; zPos: 1.35 }
+ ListElement{ xPos: -2.15 ; yPos: 1.04 ; zPos: -3.25 }
+ ListElement{ xPos: -0.65 ; yPos: -1.32 ; zPos: -3.1 }
+ ListElement{ xPos: 0.35 ; yPos: -0.84 ; zPos: -1.7 }
+ ListElement{ xPos: -2.1 ; yPos: 0.96 ; zPos: 2.5 }
+ ListElement{ xPos: 1 ; yPos: -0.6 ; zPos: -3.15 }
+ ListElement{ xPos: -1.35 ; yPos: 0.76 ; zPos: 3.45 }
+ ListElement{ xPos: -3.05 ; yPos: -1.2 ; zPos: 1.45 }
+ ListElement{ xPos: -1.6 ; yPos: 0.8 ; zPos: -1.9 }
+ ListElement{ xPos: 0.7 ; yPos: 1.68 ; zPos: 2.3 }
+ ListElement{ xPos: 0 ; yPos: -0.76 ; zPos: -0.95 }
+ ListElement{ xPos: -2.3 ; yPos: -0.16 ; zPos: -1.25 }
+ ListElement{ xPos: -0.55 ; yPos: -2.28 ; zPos: 1.5 }
+ ListElement{ xPos: 0 ; yPos: -0.24 ; zPos: 0.55 }
+ ListElement{ xPos: -0.4 ; yPos: -0.92 ; zPos: -0.7 }
+ ListElement{ xPos: -2.6 ; yPos: -1.64 ; zPos: -0.9 }
+ ListElement{ xPos: 0.25 ; yPos: -1.24 ; zPos: 0.9 }
+ ListElement{ xPos: 0.7 ; yPos: 2.88 ; zPos: 0.4 }
+ ListElement{ xPos: -0.6 ; yPos: -1.84 ; zPos: -2.4 }
+ ListElement{ xPos: 0.5 ; yPos: 2.8 ; zPos: 1.6 }
+ ListElement{ xPos: -3.2 ; yPos: 3.28 ; zPos: -3.45 }
+ ListElement{ xPos: -1.45 ; yPos: 2.52 ; zPos: 2.7 }
+ ListElement{ xPos: 1 ; yPos: -2.68 ; zPos: 3 }
+ ListElement{ xPos: -0.6 ; yPos: -2.56 ; zPos: 1.35 }
+ ListElement{ xPos: 1.95 ; yPos: -1.48 ; zPos: -3.85 }
+ ListElement{ xPos: 3.85 ; yPos: 0.08 ; zPos: -1.65 }
+ ListElement{ xPos: -1.1 ; yPos: -1.6 ; zPos: -1.05 }
+ ListElement{ xPos: 1.25 ; yPos: -0.04 ; zPos: 1.35 }
+ ListElement{ xPos: 2.9 ; yPos: 2.08 ; zPos: 0.2 }
+ ListElement{ xPos: 0.7 ; yPos: 2.52 ; zPos: 0.65 }
+ ListElement{ xPos: -1.85 ; yPos: -1.8 ; zPos: 1.05 }
+ ListElement{ xPos: 1.6 ; yPos: 1.12 ; zPos: -3.05 }
+ ListElement{ xPos: -2.8 ; yPos: 0.12 ; zPos: 0.5 }
+ ListElement{ xPos: -1.4 ; yPos: 1.64 ; zPos: -1.95 }
+ ListElement{ xPos: 2.35 ; yPos: 0.4 ; zPos: -0.95 }
+ ListElement{ xPos: 0.95 ; yPos: -0.28 ; zPos: -0.8 }
+ ListElement{ xPos: -1.5 ; yPos: -1.76 ; zPos: 2.5 }
+ ListElement{ xPos: -3.05 ; yPos: 2.44 ; zPos: -0.2 }
+ ListElement{ xPos: -0.6 ; yPos: 1.12 ; zPos: -0.5 }
+ ListElement{ xPos: -1.7 ; yPos: -0.72 ; zPos: -1.05 }
+ ListElement{ xPos: 0.45 ; yPos: 0.84 ; zPos: -0.1 }
+ ListElement{ xPos: -3.5 ; yPos: 0.36 ; zPos: 1.1 }
+ ListElement{ xPos: 0.2 ; yPos: -2.08 ; zPos: 0.25 }
+ ListElement{ xPos: -2.1 ; yPos: 0.72 ; zPos: 0.85 }
+ ListElement{ xPos: -2.45 ; yPos: -0.72 ; zPos: -0.8 }
+ ListElement{ xPos: 4.25 ; yPos: 1.84 ; zPos: -0.55 }
+ ListElement{ xPos: 0.1 ; yPos: -1.32 ; zPos: -1.45 }
+ ListElement{ xPos: -3.65 ; yPos: 0.36 ; zPos: 0.3 }
+ ListElement{ xPos: 0.9 ; yPos: 0.32 ; zPos: -3.6 }
+ ListElement{ xPos: -0.25 ; yPos: 1.84 ; zPos: 0 }
+ ListElement{ xPos: 3.5 ; yPos: 0.92 ; zPos: -2.1 }
+ ListElement{ xPos: 0.65 ; yPos: 2.36 ; zPos: 4 }
+ ListElement{ xPos: 0.55 ; yPos: -1.08 ; zPos: 0.2 }
+ ListElement{ xPos: 1 ; yPos: 0.04 ; zPos: -3.75 }
+ ListElement{ xPos: 0.05 ; yPos: 0.52 ; zPos: -3.8 }
+ ListElement{ xPos: 3.45 ; yPos: 0.56 ; zPos: 4.2 }
+ ListElement{ xPos: -0.25 ; yPos: 2.36 ; zPos: -3.55 }
+ ListElement{ xPos: 1.95 ; yPos: 1.28 ; zPos: 4.25 }
+ ListElement{ xPos: 1.8 ; yPos: 3.12 ; zPos: 0.65 }
+ ListElement{ xPos: -3.35 ; yPos: 0.8 ; zPos: -1 }
+ ListElement{ xPos: 2.4 ; yPos: -0.16 ; zPos: 1.25 }
+ ListElement{ xPos: 2.5 ; yPos: 0.96 ; zPos: 1.45 }
+ ListElement{ xPos: 0.8 ; yPos: -0.16 ; zPos: -0.55 }
+ ListElement{ xPos: -3.45 ; yPos: -0.08 ; zPos: 0.85 }
+ ListElement{ xPos: -3.4 ; yPos: 0.8 ; zPos: 1.35 }
+ ListElement{ xPos: -0.8 ; yPos: 0.24 ; zPos: -1.2 }
+ ListElement{ xPos: 3.6 ; yPos: 1.16 ; zPos: -0.1 }
+ ListElement{ xPos: -1.45 ; yPos: -3.08 ; zPos: -0.3 }
+ ListElement{ xPos: -3.65 ; yPos: -1.04 ; zPos: 0.15 }
+ ListElement{ xPos: 1.35 ; yPos: -0.76 ; zPos: 0.55 }
+ ListElement{ xPos: -2.75 ; yPos: -1 ; zPos: -1.55 }
+ ListElement{ xPos: 1.6 ; yPos: 2.04 ; zPos: 0.9 }
+ ListElement{ xPos: 3 ; yPos: -3.24 ; zPos: 0.1 }
+ ListElement{ xPos: -4.25 ; yPos: 0.56 ; zPos: -4.35 }
+ ListElement{ xPos: -2.6 ; yPos: -0.44 ; zPos: 0.5 }
+ ListElement{ xPos: 0.2 ; yPos: -0.64 ; zPos: -0.35 }
+ ListElement{ xPos: -3.2 ; yPos: -3.52 ; zPos: 1 }
+ ListElement{ xPos: -0.7 ; yPos: -1.84 ; zPos: -2.45 }
+ ListElement{ xPos: -4.1 ; yPos: 0.12 ; zPos: 3.85 }
+ ListElement{ xPos: -4.05 ; yPos: 0.04 ; zPos: -0.3 }
+ ListElement{ xPos: 2 ; yPos: 2.32 ; zPos: 1.2 }
+ ListElement{ xPos: -0.35 ; yPos: 1 ; zPos: -0.7 }
+ ListElement{ xPos: -0.9 ; yPos: 0.36 ; zPos: 1.55 }
+ ListElement{ xPos: -0.05 ; yPos: 2.4 ; zPos: -4.35 }
+ ListElement{ xPos: 1.5 ; yPos: -0.96 ; zPos: -3.4 }
+ ListElement{ xPos: -2.8 ; yPos: 2.08 ; zPos: -1.75 }
+ ListElement{ xPos: -0.2 ; yPos: 0.72 ; zPos: 0.9 }
+ ListElement{ xPos: -1.1 ; yPos: -1.68 ; zPos: 0.1 }
+ ListElement{ xPos: -1.2 ; yPos: -0.32 ; zPos: -0.85 }
+ ListElement{ xPos: 0.75 ; yPos: 0.56 ; zPos: 3.95 }
+ ListElement{ xPos: 1.15 ; yPos: 2.8 ; zPos: 0.65 }
+ ListElement{ xPos: -2.55 ; yPos: -2.56 ; zPos: 0.75 }
+ ListElement{ xPos: 0.95 ; yPos: 0.84 ; zPos: -0.85 }
+ ListElement{ xPos: -2.15 ; yPos: 0.24 ; zPos: -3.1 }
+ ListElement{ xPos: 0.35 ; yPos: -1.68 ; zPos: 0.45 }
+ ListElement{ xPos: -0.75 ; yPos: -2.4 ; zPos: -0.35 }
+ ListElement{ xPos: 0.2 ; yPos: 2.04 ; zPos: 0.1 }
+ ListElement{ xPos: -2.4 ; yPos: 0.68 ; zPos: 1.8 }
+ ListElement{ xPos: 1.9 ; yPos: 0.88 ; zPos: 1.45 }
+ ListElement{ xPos: 0.25 ; yPos: 1.92 ; zPos: -1.7 }
+ ListElement{ xPos: -0.95 ; yPos: -0.6 ; zPos: -2 }
+ ListElement{ xPos: 0.2 ; yPos: -2.44 ; zPos: 1.05 }
+ ListElement{ xPos: 0.3 ; yPos: -0.6 ; zPos: -3.35 }
+ ListElement{ xPos: 0.05 ; yPos: 0.52 ; zPos: -3.3 }
+ ListElement{ xPos: -0.05 ; yPos: -0.88 ; zPos: -0.8 }
+ ListElement{ xPos: 0.45 ; yPos: 2.84 ; zPos: -1.9 }
+ ListElement{ xPos: 2.85 ; yPos: -0.68 ; zPos: -2.45 }
+ ListElement{ xPos: -1.05 ; yPos: -1.92 ; zPos: 0.9 }
+ ListElement{ xPos: -2.75 ; yPos: -0.16 ; zPos: -1.55 }
+ ListElement{ xPos: 1.9 ; yPos: 1 ; zPos: 3.15 }
+ ListElement{ xPos: -2.25 ; yPos: 0.8 ; zPos: -4.35 }
+ ListElement{ xPos: 1.8 ; yPos: -0.72 ; zPos: -3.8 }
+ ListElement{ xPos: -3.25 ; yPos: -1.16 ; zPos: -1.85 }
+ ListElement{ xPos: -1.6 ; yPos: -2.32 ; zPos: -0.8 }
+ ListElement{ xPos: 3.1 ; yPos: 0.32 ; zPos: 2.15 }
+ ListElement{ xPos: -1.05 ; yPos: -0.56 ; zPos: -3.45 }
+ ListElement{ xPos: 0.75 ; yPos: -1.08 ; zPos: -0.25 }
+ ListElement{ xPos: -0.45 ; yPos: -2.24 ; zPos: 2.5 }
+ ListElement{ xPos: 0.2 ; yPos: 0.12 ; zPos: 0 }
+ ListElement{ xPos: -1 ; yPos: 1.56 ; zPos: -1.6 }
+ ListElement{ xPos: 1.3 ; yPos: -2.84 ; zPos: -0.25 }
+ ListElement{ xPos: 0.55 ; yPos: 1.36 ; zPos: 2.95 }
+ ListElement{ xPos: -1.9 ; yPos: -0.88 ; zPos: 0.05 }
+ ListElement{ xPos: -1.9 ; yPos: 0.56 ; zPos: -0.7 }
+ ListElement{ xPos: -1.25 ; yPos: -0.52 ; zPos: 2.35 }
+ ListElement{ xPos: 2.1 ; yPos: -0.72 ; zPos: -1.4 }
+ ListElement{ xPos: -0.9 ; yPos: -0.72 ; zPos: -2.05 }
+ ListElement{ xPos: 0.9 ; yPos: -0.96 ; zPos: -3 }
+ ListElement{ xPos: 2.7 ; yPos: -2.36 ; zPos: 1.25 }
+ ListElement{ xPos: 3.3 ; yPos: -1 ; zPos: -3.55 }
+ ListElement{ xPos: -0.75 ; yPos: -1.96 ; zPos: 2 }
+ ListElement{ xPos: -0.45 ; yPos: 0.52 ; zPos: -0.1 }
+ ListElement{ xPos: 0.8 ; yPos: 0 ; zPos: -3.3 }
+ ListElement{ xPos: -0.45 ; yPos: -0.44 ; zPos: -2.8 }
+ ListElement{ xPos: -3.2 ; yPos: 3.12 ; zPos: 0.5 }
+ ListElement{ xPos: -3.1 ; yPos: 2.84 ; zPos: -0.45 }
+ ListElement{ xPos: 0.2 ; yPos: -1.2 ; zPos: 0.9 }
+ ListElement{ xPos: -0.65 ; yPos: -1.4 ; zPos: -1.35 }
+ ListElement{ xPos: -0.45 ; yPos: 1.84 ; zPos: -0.95 }
+ ListElement{ xPos: -1.3 ; yPos: 0.8 ; zPos: -1 }
+ ListElement{ xPos: 2.35 ; yPos: -0.28 ; zPos: 1.55 }
+ ListElement{ xPos: 2 ; yPos: -2.4 ; zPos: 1.2 }
+ ListElement{ xPos: 1.2 ; yPos: -1.72 ; zPos: -0.4 }
+ ListElement{ xPos: -2 ; yPos: 3.04 ; zPos: 1.9 }
+ ListElement{ xPos: -1.85 ; yPos: -0.16 ; zPos: -2.9 }
+ ListElement{ xPos: -0.95 ; yPos: -2.76 ; zPos: 2.5 }
+ ListElement{ xPos: 2.55 ; yPos: -0.64 ; zPos: 3.25 }
+ ListElement{ xPos: -0.6 ; yPos: -0.72 ; zPos: -1.45 }
+ ListElement{ xPos: 0.8 ; yPos: 0.16 ; zPos: 2.2 }
+ ListElement{ xPos: 0.6 ; yPos: 0.04 ; zPos: 3.2 }
+ ListElement{ xPos: -3.75 ; yPos: -0.24 ; zPos: 0.2 }
+ ListElement{ xPos: 0.4 ; yPos: -0.32 ; zPos: 0.6 }
+ ListElement{ xPos: -2.1 ; yPos: -3.68 ; zPos: 0.2 }
+ ListElement{ xPos: 0.45 ; yPos: -2.44 ; zPos: 3 }
+ ListElement{ xPos: 0.5 ; yPos: -1.8 ; zPos: -1.9 }
+ ListElement{ xPos: 0 ; yPos: 1.8 ; zPos: -1.25 }
+ ListElement{ xPos: 2.6 ; yPos: 2.2 ; zPos: -4.25 }
+ ListElement{ xPos: 0.25 ; yPos: 2.28 ; zPos: -0.4 }
+ ListElement{ xPos: -0.3 ; yPos: -1.24 ; zPos: 0.7 }
+ ListElement{ xPos: 0.1 ; yPos: -3 ; zPos: 0.05 }
+ ListElement{ xPos: -1.2 ; yPos: -0.76 ; zPos: 2.65 }
+ ListElement{ xPos: 2.8 ; yPos: 0.44 ; zPos: 0.55 }
+ ListElement{ xPos: 2.6 ; yPos: -0.68 ; zPos: 0.2 }
+ ListElement{ xPos: 1.75 ; yPos: -0.16 ; zPos: -3.6 }
+ ListElement{ xPos: -0.55 ; yPos: -0.16 ; zPos: 2.3 }
+ ListElement{ xPos: 0.1 ; yPos: -1.72 ; zPos: -0.4 }
+ ListElement{ xPos: 3.6 ; yPos: -0.84 ; zPos: -0.2 }
+ ListElement{ xPos: -1.4 ; yPos: -1.48 ; zPos: -2.7 }
+ ListElement{ xPos: 1.1 ; yPos: -0.2 ; zPos: -2.75 }
+ ListElement{ xPos: -1.85 ; yPos: 1.76 ; zPos: -0.85 }
+ ListElement{ xPos: 0.05 ; yPos: -0.4 ; zPos: 1.05 }
+ ListElement{ xPos: -1.25 ; yPos: 0.52 ; zPos: -0.3 }
+ ListElement{ xPos: -0.85 ; yPos: -0.24 ; zPos: 1.9 }
+ ListElement{ xPos: -1.95 ; yPos: -0.08 ; zPos: -1.95 }
+ ListElement{ xPos: -2.7 ; yPos: -0.52 ; zPos: -0.35 }
+ ListElement{ xPos: 0.1 ; yPos: 0.16 ; zPos: 4.1 }
+ ListElement{ xPos: -0.6 ; yPos: -0.52 ; zPos: -1.2 }
+ ListElement{ xPos: -2.3 ; yPos: -0.4 ; zPos: -2.85 }
+ ListElement{ xPos: -0.35 ; yPos: -1.2 ; zPos: -1.85 }
+ ListElement{ xPos: 1.7 ; yPos: -0.2 ; zPos: 3.35 }
+ ListElement{ xPos: 2.75 ; yPos: -2.32 ; zPos: 3.15 }
+ ListElement{ xPos: 2.85 ; yPos: 0.44 ; zPos: 0.9 }
+ ListElement{ xPos: -2.1 ; yPos: 0.4 ; zPos: 1 }
+ ListElement{ xPos: 4.45 ; yPos: -0.4 ; zPos: -3.75 }
+ ListElement{ xPos: 0.7 ; yPos: -1.44 ; zPos: 0.85 }
+ ListElement{ xPos: -0.85 ; yPos: 1.76 ; zPos: 1.05 }
+ ListElement{ xPos: -0.4 ; yPos: -0.92 ; zPos: -2.4 }
+ ListElement{ xPos: -1 ; yPos: -0.28 ; zPos: -1.6 }
+ ListElement{ xPos: -0.75 ; yPos: 0.56 ; zPos: -0.75 }
+ ListElement{ xPos: 0.55 ; yPos: 1.72 ; zPos: -0.2 }
+ ListElement{ xPos: 2.75 ; yPos: -0.24 ; zPos: -0.5 }
+ ListElement{ xPos: -2.2 ; yPos: -1.04 ; zPos: -4.05 }
+ ListElement{ xPos: 3.35 ; yPos: -0.56 ; zPos: -2.9 }
+ ListElement{ xPos: 2.4 ; yPos: -0.32 ; zPos: -1.55 }
+ ListElement{ xPos: 0.85 ; yPos: -0.88 ; zPos: -2.1 }
+ ListElement{ xPos: 0.4 ; yPos: 0.24 ; zPos: -0.45 }
+ ListElement{ xPos: -4.1 ; yPos: -0.72 ; zPos: 0.35 }
+ ListElement{ xPos: -0.5 ; yPos: 0.04 ; zPos: -0.95 }
+ ListElement{ xPos: -2.8 ; yPos: 2.92 ; zPos: 0.95 }
+ ListElement{ xPos: -1.65 ; yPos: 0.96 ; zPos: 1.25 }
+ ListElement{ xPos: 1.45 ; yPos: 0.84 ; zPos: 0.25 }
+ ListElement{ xPos: 2.2 ; yPos: -1.76 ; zPos: 0 }
+ ListElement{ xPos: -0.75 ; yPos: 1.08 ; zPos: -2.1 }
+ ListElement{ xPos: -3.15 ; yPos: -0.16 ; zPos: -1.1 }
+ ListElement{ xPos: 2.55 ; yPos: -1.6 ; zPos: 1.1 }
+ ListElement{ xPos: 0.15 ; yPos: 1.84 ; zPos: 0.4 }
+ ListElement{ xPos: -1.5 ; yPos: 2.04 ; zPos: 3.2 }
+ ListElement{ xPos: -1.05 ; yPos: -0.84 ; zPos: -1.9 }
+ ListElement{ xPos: 0.1 ; yPos: -2.96 ; zPos: -0.2 }
+ ListElement{ xPos: 2.6 ; yPos: 0.68 ; zPos: -2.6 }
+ ListElement{ xPos: -0.4 ; yPos: -0.36 ; zPos: -1.05 }
+ ListElement{ xPos: 1.1 ; yPos: 0.04 ; zPos: -2.4 }
+ ListElement{ xPos: -2.3 ; yPos: 1.4 ; zPos: -0.1 }
+ ListElement{ xPos: 0.85 ; yPos: -1.2 ; zPos: 1.5 }
+ ListElement{ xPos: 0.1 ; yPos: 0.24 ; zPos: -2.75 }
+ ListElement{ xPos: 1.15 ; yPos: 1.32 ; zPos: -1.7 }
+ ListElement{ xPos: 0.35 ; yPos: -1.6 ; zPos: -2.75 }
+ ListElement{ xPos: 0.35 ; yPos: -1.36 ; zPos: 2.55 }
+ ListElement{ xPos: -1.65 ; yPos: -0.28 ; zPos: 2.75 }
+ ListElement{ xPos: -3.8 ; yPos: -3.28 ; zPos: 2.55 }
+ ListElement{ xPos: -2.6 ; yPos: 1.08 ; zPos: -0.45 }
+ ListElement{ xPos: 1.6 ; yPos: -2.2 ; zPos: 2.45 }
+ ListElement{ xPos: -0.75 ; yPos: 1.16 ; zPos: -1.9 }
+ ListElement{ xPos: -2.05 ; yPos: 3.04 ; zPos: 1.9 }
+ ListElement{ xPos: -0.6 ; yPos: 2.88 ; zPos: 1 }
+ ListElement{ xPos: 3.25 ; yPos: -2 ; zPos: -0.35 }
+ ListElement{ xPos: -0.7 ; yPos: 1.36 ; zPos: 1.85 }
+ ListElement{ xPos: 0.85 ; yPos: 1.08 ; zPos: 0.95 }
+ ListElement{ xPos: 1.15 ; yPos: 1.32 ; zPos: 3.4 }
+ ListElement{ xPos: 3.6 ; yPos: 0.44 ; zPos: -0.4 }
+ ListElement{ xPos: 0.9 ; yPos: 2.12 ; zPos: 1.95 }
+ ListElement{ xPos: -0.6 ; yPos: -0.24 ; zPos: 1.05 }
+ ListElement{ xPos: -1.6 ; yPos: 0.64 ; zPos: -1.3 }
+ ListElement{ xPos: -1.3 ; yPos: -0.6 ; zPos: -1.95 }
+ ListElement{ xPos: -0.1 ; yPos: 0.36 ; zPos: -1.25 }
+ ListElement{ xPos: 1 ; yPos: -1.48 ; zPos: 0.95 }
+ ListElement{ xPos: 1.2 ; yPos: -1.92 ; zPos: -0.9 }
+ ListElement{ xPos: 0.1 ; yPos: 2.2 ; zPos: -0.4 }
+ ListElement{ xPos: -2.85 ; yPos: 0.64 ; zPos: 0.55 }
+ ListElement{ xPos: -1.6 ; yPos: 2.56 ; zPos: -2.2 }
+ ListElement{ xPos: -3.2 ; yPos: -0.08 ; zPos: -0.65 }
+ ListElement{ xPos: 3.15 ; yPos: -0.76 ; zPos: 1.15 }
+ ListElement{ xPos: 1.2 ; yPos: 0.6 ; zPos: -2.6 }
+ ListElement{ xPos: 2.65 ; yPos: -3.52 ; zPos: 1.5 }
+ ListElement{ xPos: -1.85 ; yPos: -1.76 ; zPos: -1.7 }
+ ListElement{ xPos: -1.55 ; yPos: 1.2 ; zPos: 2.15 }
+ ListElement{ xPos: -0.55 ; yPos: 2.88 ; zPos: -2.85 }
+ ListElement{ xPos: -3.1 ; yPos: -0.28 ; zPos: -3.35 }
+ ListElement{ xPos: 2.45 ; yPos: 0.08 ; zPos: -2.2 }
+ ListElement{ xPos: -2.05 ; yPos: 0.88 ; zPos: -0.65 }
+ ListElement{ xPos: 1.1 ; yPos: -0.56 ; zPos: -3.65 }
+ ListElement{ xPos: -0.5 ; yPos: -0.68 ; zPos: 0.3 }
+ ListElement{ xPos: 0.4 ; yPos: 0.88 ; zPos: -1.65 }
+ ListElement{ xPos: 1.65 ; yPos: 0.16 ; zPos: 0.75 }
+ ListElement{ xPos: -0.2 ; yPos: 1.72 ; zPos: 0.6 }
+ ListElement{ xPos: 1.15 ; yPos: -0.48 ; zPos: 0.1 }
+ ListElement{ xPos: 0.05 ; yPos: 1.04 ; zPos: 2.15 }
+ ListElement{ xPos: 0.15 ; yPos: -0.64 ; zPos: -1.3 }
+ ListElement{ xPos: 1.7 ; yPos: -1.88 ; zPos: -2.85 }
+ ListElement{ xPos: 3.35 ; yPos: 1.28 ; zPos: -1.05 }
+ ListElement{ xPos: -3.7 ; yPos: -2.88 ; zPos: -1.05 }
+ ListElement{ xPos: -1.7 ; yPos: 3.08 ; zPos: 0.15 }
+ ListElement{ xPos: 3 ; yPos: -2.52 ; zPos: -2.45 }
+ ListElement{ xPos: -0.15 ; yPos: 0.16 ; zPos: -0.3 }
+ ListElement{ xPos: -2.15 ; yPos: -0.8 ; zPos: 1.25 }
+ ListElement{ xPos: -1.95 ; yPos: -0.84 ; zPos: -3.1 }
+ ListElement{ xPos: -0.2 ; yPos: -0.8 ; zPos: -3.55 }
+ ListElement{ xPos: 0.4 ; yPos: 0.32 ; zPos: -1.55 }
+ ListElement{ xPos: 1.9 ; yPos: -2.84 ; zPos: -0.55 }
+ ListElement{ xPos: 1.05 ; yPos: 1.32 ; zPos: 0.6 }
+ ListElement{ xPos: 2.4 ; yPos: 1 ; zPos: 2.35 }
+ ListElement{ xPos: -0.7 ; yPos: 0.28 ; zPos: -1.3 }
+ ListElement{ xPos: 0.85 ; yPos: 0.96 ; zPos: -2.7 }
+ ListElement{ xPos: -0.85 ; yPos: -0.88 ; zPos: 1.1 }
+ ListElement{ xPos: 1.5 ; yPos: 0.28 ; zPos: -3.1 }
+ ListElement{ xPos: 1.9 ; yPos: 0.28 ; zPos: -1.75 }
+ ListElement{ xPos: 0.2 ; yPos: -2.04 ; zPos: -0.85 }
+ ListElement{ xPos: -1.5 ; yPos: 2.04 ; zPos: -1.35 }
+ ListElement{ xPos: -0.7 ; yPos: 1.24 ; zPos: 1.95 }
+ ListElement{ xPos: 1.65 ; yPos: -1.04 ; zPos: -0.95 }
+ ListElement{ xPos: -2.35 ; yPos: -1.76 ; zPos: -0.2 }
+ ListElement{ xPos: 0.85 ; yPos: -2.92 ; zPos: 3.4 }
+ ListElement{ xPos: -0.7 ; yPos: 2.52 ; zPos: 1 }
+ ListElement{ xPos: -3.4 ; yPos: 0.6 ; zPos: 0.9 }
+
+ ListElement{ xPos: 8.0; yPos: -2.0; zPos: 4.0 }
+ ListElement{ xPos: 7.8; yPos: -2.2; zPos: 5.0 }
+ ListElement{ xPos: 7.6; yPos: -2.4; zPos: 4.5 }
+ ListElement{ xPos: 7.4; yPos: -2.6; zPos: 3.8 }
+ ListElement{ xPos: 7.2; yPos: -2.8; zPos: 4.8 }
+ ListElement{ xPos: 7.0; yPos: -2.3; zPos: 4.1 }
+ ListElement{ xPos: 6.9; yPos: -3.3; zPos: 4.9 }
+ ListElement{ xPos: 6.7; yPos: -3.5; zPos: 3.5 }
+ ListElement{ xPos: 6.5; yPos: -3.7; zPos: 3.3 }
+ ListElement{ xPos: 6.3; yPos: -3.4; zPos: 3.7 }
+ ListElement{ xPos: 7.9 ; yPos: -3.32 ; zPos: 2.48 }
+ ListElement{ xPos: 6.2 ; yPos: -4.04 ; zPos: 3.4 }
+ ListElement{ xPos: 8.06 ; yPos: -4.6 ; zPos: 4.08 }
+ ListElement{ xPos: 5.98 ; yPos: -2.26 ; zPos: 2.82 }
+ ListElement{ xPos: 5.46 ; yPos: -3.9 ; zPos: 3.2 }
+ ListElement{ xPos: 8.14 ; yPos: -3.34 ; zPos: 3.42 }
+ ListElement{ xPos: 6.84 ; yPos: -5.0 ; zPos: 2.36 }
+ ListElement{ xPos: 7.6 ; yPos: -3.82 ; zPos: 2.78 }
+ ListElement{ xPos: 7.1 ; yPos: -3.94 ; zPos: 2.7 }
+ ListElement{ xPos: 6.02 ; yPos: -4.36 ; zPos: 2.56 }
+ ListElement{ xPos: 8.64 ; yPos: -3.04 ; zPos: 2.62 }
+ ListElement{ xPos: 7.82 ; yPos: -3.68 ; zPos: 2.96 }
+ ListElement{ xPos: 7.1 ; yPos: -3.6 ; zPos: 4.22 }
+ ListElement{ xPos: 7.6 ; yPos: -3.88 ; zPos: 3.9 }
+ ListElement{ xPos: 7.46 ; yPos: -4.2 ; zPos: 3.32 }
+ ListElement{ xPos: 6.98 ; yPos: -3.94 ; zPos: 3.1 }
+ ListElement{ xPos: 7.36 ; yPos: -4.24 ; zPos: 1.72 }
+ ListElement{ xPos: 8.42 ; yPos: -4.52 ; zPos: 2.62 }
+ ListElement{ xPos: 6.04 ; yPos: -4.48 ; zPos: 2.74 }
+ ListElement{ xPos: 8.7 ; yPos: -3.92 ; zPos: 3.82 }
+ ListElement{ xPos: 6.76 ; yPos: -3.5 ; zPos: 2.92 }
+ ListElement{ xPos: 7 ; yPos: -4.42 ; zPos: 2.62 }
+ ListElement{ xPos: 5.32 ; yPos: -3.28 ; zPos: 3.34 }
+ ListElement{ xPos: 6.4 ; yPos: -4.6 ; zPos: 2.4 }
+ ListElement{ xPos: 5.66 ; yPos: -4.98 ; zPos: 3.72 }
+ }
+}
diff --git a/examples/qmlscatter/qml/qmlscatter/main.qml b/examples/qmlscatter/qml/qmlscatter/main.qml
index 6238529d..e5f1de62 100644
--- a/examples/qmlscatter/qml/qmlscatter/main.qml
+++ b/examples/qmlscatter/qml/qmlscatter/main.qml
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -16,194 +16,146 @@
**
****************************************************************************/
+//! [0]
import QtQuick 2.1
-import QtQuick.Controls 1.0
-import com.digia.QtDataVis3D 1.0
+import com.digia.QtDataVisualization 1.0
+import "."
+//! [0]
+//! [1]
Item {
- id: mainview
- width: 800
- height: 700
+ id: mainView
visible: true
+ //! [1]
+ //! [4]
+ Data {
+ id: graphData
+ }
+ //! [4]
+
+ //! [8]
+ //! [9]
Item {
id: dataView
+ anchors.bottom: parent.bottom
+ //! [9]
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 }
- }
+ //! [8]
+ //! [2]
Scatter3D {
- id: testscatter
+ id: scatterGraph
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
- }
+ //! [2]
+ //! [3]
+ font.family: "Lucida Handwriting"
+ font.pointSize: 40
+ theme: AbstractGraph3D.ThemeIsabelle
+ shadowQuality: AbstractGraph3D.ShadowQualitySoftLow
+ //! [3]
+ //! [5]
+ dataProxy: graphData.proxy
+ //! [5]
+ //! [6]
+ itemLabelFormat: "X:@xLabel Y:@yLabel Z:@zLabel"
+ axisX.segmentCount: 3
+ axisX.subSegmentCount: 2
+ axisX.labelFormat: "%.2f"
+ axisZ.segmentCount: 2
+ axisZ.subSegmentCount: 2
+ axisZ.labelFormat: "%.2f"
+ axisY.segmentCount: 2
+ axisY.subSegmentCount: 2
+ axisY.labelFormat: "%.2f"
+ //! [6]
}
}
- Rectangle {
+ //! [7]
+ NewButton {
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";
- }
+ width: parent.width / 6 // We're adding 6 buttons and want to divide them equally
+ text: "Hide Shadows"
+ onClicked: {
+ if (scatterGraph.shadowQuality === AbstractGraph3D.ShadowQualityNone) {
+ scatterGraph.shadowQuality = AbstractGraph3D.ShadowQualitySoftLow;
+ text = "Hide Shadows";
+ } else {
+ scatterGraph.shadowQuality = AbstractGraph3D.ShadowQualityNone;
+ text = "Show Shadows";
}
}
}
- Rectangle {
+ //! [7]
+
+ NewButton {
id: smoothToggle
- width: 140
- height: 30
+ width: parent.width / 6
+ text: "Use Smooth Dots"
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;
- }
+ onClicked: {
+ if (scatterGraph.objectSmoothingEnabled === false) {
+ text = "Use Flat Dots";
+ scatterGraph.objectSmoothingEnabled = true;
+ } else {
+ text = "Use Smooth Dots"
+ scatterGraph.objectSmoothingEnabled = false;
}
}
}
- Rectangle {
+
+ NewButton {
id: cameraToggle
- width: 130
- height: 30
+ width: parent.width / 6
+ text: "Change Camera Placement"
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;
- }
+ onClicked: {
+ if (scatterGraph.scene.activeCamera.cameraPreset === AbstractGraph3D.CameraPresetFront) {
+ scatterGraph.scene.activeCamera.cameraPreset = AbstractGraph3D.CameraPresetIsometricRightHigh;
+ } else {
+ scatterGraph.scene.activeCamera.cameraPreset = AbstractGraph3D.CameraPresetFront;
}
}
}
- Rectangle {
+
+ NewButton {
id: themeToggle
- width: 120
- height: 30
+ width: parent.width / 6
+ text: "Change Theme"
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;
- }
+ onClicked: {
+ if (scatterGraph.theme === AbstractGraph3D.ThemeArmyBlue) {
+ scatterGraph.theme = AbstractGraph3D.ThemeIsabelle;
+ } else {
+ scatterGraph.theme = AbstractGraph3D.ThemeArmyBlue;
}
}
}
- Rectangle {
+
+ NewButton {
id: backgroundToggle
- width: 130
- height: 30
+ width: parent.width / 6
+ text: "Hide Background"
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";
- }
+ onClicked: {
+ if (scatterGraph.backgroundVisible === true) {
+ scatterGraph.backgroundVisible = false;
+ text = "Show Background";
+ } else {
+ scatterGraph.backgroundVisible = true;
+ text = "Hide Background";
}
}
}
+ NewButton {
+ id: exitButton
+ width: parent.width / 6
+ text: "Quit"
+ anchors.left: backgroundToggle.right
+ onClicked: Qt.quit(0);
+ }
}
diff --git a/examples/qmlscatter/qml/qmlscatter/newbutton.qml b/examples/qmlscatter/qml/qmlscatter/newbutton.qml
new file mode 100644
index 00000000..895db183
--- /dev/null
+++ b/examples/qmlscatter/qml/qmlscatter/newbutton.qml
@@ -0,0 +1,43 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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
+
+Item {
+ id: newbutton
+
+ property alias text: buttonText.text
+
+ signal clicked
+
+ height: 80
+
+ Button {
+ width: parent.width
+ height: parent.height
+ Text {
+ id: buttonText
+ wrapMode: Text.WordWrap
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignHCenter
+ anchors.fill: parent
+ }
+ onClicked: newbutton.clicked()
+ }
+}
diff --git a/examples/qmlscatter/qmlscatter.pro b/examples/qmlscatter/qmlscatter.pro
index 6f89fbae..0c66c5ae 100644
--- a/examples/qmlscatter/qmlscatter.pro
+++ b/examples/qmlscatter/qmlscatter.pro
@@ -2,6 +2,8 @@
error( "Couldn't find the examples.pri file!" )
}
+QT += widgets
+
# Add more folders to ship with the application, here
folder_01.source = qml/qmlscatter
folder_01.target = qml
@@ -13,11 +15,11 @@ 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
+
+OTHER_FILES += doc/src/* \
+ doc/images/*
diff --git a/examples/qmlscatter/qmlscatter.qrc b/examples/qmlscatter/qmlscatter.qrc
index 62f5931b..6b77a4bc 100644
--- a/examples/qmlscatter/qmlscatter.qrc
+++ b/examples/qmlscatter/qmlscatter.qrc
@@ -1,5 +1,7 @@
<RCC>
<qresource prefix="/qml">
<file alias="main.qml">qml/qmlscatter/main.qml</file>
+ <file alias="Data.qml">qml/qmlscatter/data.qml</file>
+ <file alias="NewButton.qml">qml/qmlscatter/newbutton.qml</file>
</qresource>
</RCC>
diff --git a/examples/qmlscatter/qtquick2applicationviewer/qtquick2applicationviewer.pri b/examples/qmlscatter/qtquick2applicationviewer/qtquick2applicationviewer.pri
index e5f7990f..a071e63d 100644
--- a/examples/qmlscatter/qtquick2applicationviewer/qtquick2applicationviewer.pri
+++ b/examples/qmlscatter/qtquick2applicationviewer/qtquick2applicationviewer.pri
@@ -61,16 +61,6 @@ android-no-sdk {
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 =
diff --git a/examples/qmlsurface/doc/images/qmlsurface-example.png b/examples/qmlsurface/doc/images/qmlsurface-example.png
new file mode 100644
index 00000000..32396b40
--- /dev/null
+++ b/examples/qmlsurface/doc/images/qmlsurface-example.png
Binary files differ
diff --git a/examples/qmlsurface/doc/src/qmlsurface.qdoc b/examples/qmlsurface/doc/src/qmlsurface.qdoc
new file mode 100644
index 00000000..c93ed2d6
--- /dev/null
+++ b/examples/qmlsurface/doc/src/qmlsurface.qdoc
@@ -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 QtDataVisualization 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 qmlsurface
+ \title Qt Quick 2 Surface Example
+ \ingroup qtdatavisualization_examples
+ \brief Using Surface3D in a QML application.
+
+ The Qt Quick 2 surface example shows how to make a simple 3D surface plot using Surface3D with
+ Qt Quick 2.
+
+ \image qmlsurface-example.png
+
+ The focus in this example is on generating a surface graph from height data, so in this section
+ we skip explaining application creation. For more detailed QML example documentation,
+ see \l{Qt Quick 2 Scatter Example}.
+
+ \section1 Adding data to the graph
+
+ This example shows two method to set data to surface graph, using the HeightMapSurfaceDataProxy
+ and ItemModelSurfaceDataProxy. First we go through setting the data using height map specific
+ data proxy. It is done with the code snippet below. The \c heightMapFile property specifies the image
+ file containing the height data. The value properties defines the minimum and maximum values for
+ surface area width and depth. This example shows the terrain around Tycho crater at imaginary
+ position from 67 to 97 and from 30 to 60. Note that on the graph the scale on the Y dimension
+ exaggerates the height.
+
+ \snippet ../examples/qmlsurface/qml/qmlsurface/data.qml 0
+
+ The other method to set surface data used in this example is with model mapping. We do that by first
+ defining a ListModel containing the data for the surface:
+
+ \snippet ../examples/qmlsurface/qml/qmlsurface/data.qml 1
+ \dots 4
+
+ Then we set up a SurfaceDataMapping which maps the roles for columns, rows and values. In this
+ example the row holds values for longitude, column for latitude and the value is for height.
+
+ \snippet ../examples/qmlsurface/qml/qmlsurface/data.qml 2
+
+ The ItemModelSurfaceDataProxy is created to tie the model and the mapping together.
+
+ \snippet ../examples/qmlsurface/qml/qmlsurface/data.qml 3
+
+ \section1 Showing data
+
+ In the \c main.qml, we set up the Surface3D element to show the data and various UI elements
+ to illustrate few interesting features. First is the surface gradient, which can be defined
+ as seen in this code snippet. With the \c ColorGradient we set example colors from position 0.0 to
+ 1.0. This element is set for \c gradient property in Surface3D.
+
+ \snippet ../examples/qmlsurface/qml/qmlsurface/main.qml 0
+
+ Other interesting features can be controlled with buttons. The first button is to toggle on and off
+ the surface grid, for which use the following code.
+
+ \snippet ../examples/qmlsurface/qml/qmlsurface/main.qml 1
+
+ Second button is for surface smooth status, which is controlled with this code.
+
+ \snippet ../examples/qmlsurface/qml/qmlsurface/main.qml 2
+
+ Third and fourth buttons are for controlling background features. The last button is for switching
+ between HeightMapSurfaceDataProxy and ItemModelSurfaceDataProxy, for which we use the following
+ code. We also set the maximum value to 500 in model proxy to make the surface flatter and
+ 250 on height map proxy to show exaggerated height. At the same time the color position
+ on the gradient is modified.
+
+ \snippet ../examples/qmlsurface/qml/qmlsurface/main.qml 3
+
+ \section1 Example contents
+*/
diff --git a/examples/qmlsurface/heightmap.png b/examples/qmlsurface/heightmap.png
new file mode 100644
index 00000000..051a0125
--- /dev/null
+++ b/examples/qmlsurface/heightmap.png
Binary files differ
diff --git a/examples/qmlsurface/main.cpp b/examples/qmlsurface/main.cpp
new file mode 100644
index 00000000..ac9dda35
--- /dev/null
+++ b/examples/qmlsurface/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 QtDataVisualization 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
+
+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")));
+#endif
+
+ viewer.setSource(QUrl("qrc:/qml/main.qml"));
+
+ viewer.setTitle(QStringLiteral("Tycho crater on the Moon (height exaggerated)"));
+ viewer.setResizeMode(QQuickView::SizeRootObjectToView);
+ viewer.show();
+
+ return app.exec();
+}
diff --git a/examples/qmlsurface/qml/qmlsurface/data.qml b/examples/qmlsurface/qml/qmlsurface/data.qml
new file mode 100644
index 00000000..80ed471a
--- /dev/null
+++ b/examples/qmlsurface/qml/qmlsurface/data.qml
@@ -0,0 +1,10062 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 com.digia.QtDataVisualization 1.0
+
+Item {
+ property alias mapping: surfaceMapping
+ property alias model: dataModel
+ property alias proxy: modelProxy
+ property alias heightProxy: heightMapProxy
+
+ //! [0]
+ HeightMapSurfaceDataProxy {
+ id: heightMapProxy
+ heightMapFile: ":/heightmaps/image"
+ // We don't want the default data values set by heightmap proxy.
+ minZValue: 30
+ maxZValue: 60
+ minXValue: 67
+ maxXValue: 97
+ }
+ //! [0]
+
+ //! [2]
+ SurfaceDataMapping {
+ id: surfaceMapping
+ rowRole: "longitude"
+ columnRole: "latitude"
+ valueRole: "height"
+ }
+ //! [2]
+
+ //! [3]
+ ItemModelSurfaceDataProxy {
+ id: modelProxy
+ activeMapping: surfaceMapping
+ itemModel: dataModel
+ }
+ //! [3]
+
+ //! [1]
+ ListModel {
+ id: dataModel
+ ListElement{ longitude: "0"; latitude: "0"; height: "124"; }
+ ListElement{ longitude: "0"; latitude: "1"; height: "125"; }
+ ListElement{ longitude: "0"; latitude: "2"; height: "124"; }
+ //! [1]
+ ListElement{ longitude: "0"; latitude: "3"; height: "118"; }
+ ListElement{ longitude: "0"; latitude: "4"; height: "112"; }
+ ListElement{ longitude: "0"; latitude: "5"; height: "111"; }
+ ListElement{ longitude: "0"; latitude: "6"; height: "115"; }
+ ListElement{ longitude: "0"; latitude: "7"; height: "102"; }
+ ListElement{ longitude: "0"; latitude: "8"; height: "115"; }
+ ListElement{ longitude: "0"; latitude: "9"; height: "126"; }
+ ListElement{ longitude: "0"; latitude: "10"; height: "127"; }
+ ListElement{ longitude: "0"; latitude: "11"; height: "127"; }
+ ListElement{ longitude: "0"; latitude: "12"; height: "124"; }
+ ListElement{ longitude: "0"; latitude: "13"; height: "120"; }
+ ListElement{ longitude: "0"; latitude: "14"; height: "117"; }
+ ListElement{ longitude: "0"; latitude: "15"; height: "116"; }
+ ListElement{ longitude: "0"; latitude: "16"; height: "114"; }
+ ListElement{ longitude: "0"; latitude: "17"; height: "112"; }
+ ListElement{ longitude: "0"; latitude: "18"; height: "114"; }
+ ListElement{ longitude: "0"; latitude: "19"; height: "114"; }
+ ListElement{ longitude: "0"; latitude: "20"; height: "112"; }
+ ListElement{ longitude: "0"; latitude: "21"; height: "112"; }
+ ListElement{ longitude: "0"; latitude: "22"; height: "116"; }
+ ListElement{ longitude: "0"; latitude: "23"; height: "117"; }
+ ListElement{ longitude: "0"; latitude: "24"; height: "118"; }
+ ListElement{ longitude: "0"; latitude: "25"; height: "119"; }
+ ListElement{ longitude: "0"; latitude: "26"; height: "117"; }
+ ListElement{ longitude: "0"; latitude: "27"; height: "115"; }
+ ListElement{ longitude: "0"; latitude: "28"; height: "112"; }
+ ListElement{ longitude: "0"; latitude: "29"; height: "109"; }
+ ListElement{ longitude: "0"; latitude: "30"; height: "108"; }
+ ListElement{ longitude: "0"; latitude: "31"; height: "105"; }
+ ListElement{ longitude: "0"; latitude: "32"; height: "105"; }
+ ListElement{ longitude: "0"; latitude: "33"; height: "104"; }
+ ListElement{ longitude: "0"; latitude: "34"; height: "105"; }
+ ListElement{ longitude: "0"; latitude: "35"; height: "107"; }
+ ListElement{ longitude: "0"; latitude: "36"; height: "110"; }
+ ListElement{ longitude: "0"; latitude: "37"; height: "114"; }
+ ListElement{ longitude: "0"; latitude: "38"; height: "117"; }
+ ListElement{ longitude: "0"; latitude: "39"; height: "119"; }
+ ListElement{ longitude: "0"; latitude: "40"; height: "121"; }
+ ListElement{ longitude: "0"; latitude: "41"; height: "123"; }
+ ListElement{ longitude: "0"; latitude: "42"; height: "125"; }
+ ListElement{ longitude: "0"; latitude: "43"; height: "126"; }
+ ListElement{ longitude: "0"; latitude: "44"; height: "119"; }
+ ListElement{ longitude: "0"; latitude: "45"; height: "115"; }
+ ListElement{ longitude: "0"; latitude: "46"; height: "114"; }
+ ListElement{ longitude: "0"; latitude: "47"; height: "123"; }
+ ListElement{ longitude: "0"; latitude: "48"; height: "131"; }
+ ListElement{ longitude: "0"; latitude: "49"; height: "130"; }
+ ListElement{ longitude: "0"; latitude: "50"; height: "128"; }
+ ListElement{ longitude: "0"; latitude: "51"; height: "124"; }
+ ListElement{ longitude: "0"; latitude: "52"; height: "121"; }
+ ListElement{ longitude: "0"; latitude: "53"; height: "120"; }
+ ListElement{ longitude: "0"; latitude: "54"; height: "118"; }
+ ListElement{ longitude: "0"; latitude: "55"; height: "116"; }
+ ListElement{ longitude: "0"; latitude: "56"; height: "116"; }
+ ListElement{ longitude: "0"; latitude: "57"; height: "115"; }
+ ListElement{ longitude: "0"; latitude: "58"; height: "112"; }
+ ListElement{ longitude: "0"; latitude: "59"; height: "110"; }
+ ListElement{ longitude: "0"; latitude: "60"; height: "109"; }
+ ListElement{ longitude: "0"; latitude: "61"; height: "107"; }
+ ListElement{ longitude: "0"; latitude: "62"; height: "107"; }
+ ListElement{ longitude: "0"; latitude: "63"; height: "108"; }
+ ListElement{ longitude: "0"; latitude: "64"; height: "110"; }
+ ListElement{ longitude: "0"; latitude: "65"; height: "113"; }
+ ListElement{ longitude: "0"; latitude: "66"; height: "115"; }
+ ListElement{ longitude: "0"; latitude: "67"; height: "117"; }
+ ListElement{ longitude: "0"; latitude: "68"; height: "119"; }
+ ListElement{ longitude: "0"; latitude: "69"; height: "121"; }
+ ListElement{ longitude: "0"; latitude: "70"; height: "122"; }
+ ListElement{ longitude: "0"; latitude: "71"; height: "124"; }
+ ListElement{ longitude: "0"; latitude: "72"; height: "125"; }
+ ListElement{ longitude: "0"; latitude: "73"; height: "125"; }
+ ListElement{ longitude: "0"; latitude: "74"; height: "125"; }
+ ListElement{ longitude: "0"; latitude: "75"; height: "123"; }
+ ListElement{ longitude: "0"; latitude: "76"; height: "123"; }
+ ListElement{ longitude: "0"; latitude: "77"; height: "122"; }
+ ListElement{ longitude: "0"; latitude: "78"; height: "125"; }
+ ListElement{ longitude: "0"; latitude: "79"; height: "129"; }
+ ListElement{ longitude: "0"; latitude: "80"; height: "135"; }
+ ListElement{ longitude: "0"; latitude: "81"; height: "138"; }
+ ListElement{ longitude: "0"; latitude: "82"; height: "136"; }
+ ListElement{ longitude: "0"; latitude: "83"; height: "129"; }
+ ListElement{ longitude: "0"; latitude: "84"; height: "121"; }
+ ListElement{ longitude: "0"; latitude: "85"; height: "116"; }
+ ListElement{ longitude: "0"; latitude: "86"; height: "115"; }
+ ListElement{ longitude: "0"; latitude: "87"; height: "118"; }
+ ListElement{ longitude: "0"; latitude: "88"; height: "122"; }
+ ListElement{ longitude: "0"; latitude: "89"; height: "127"; }
+ ListElement{ longitude: "0"; latitude: "90"; height: "129"; }
+ ListElement{ longitude: "0"; latitude: "91"; height: "130"; }
+ ListElement{ longitude: "0"; latitude: "92"; height: "130"; }
+ ListElement{ longitude: "0"; latitude: "93"; height: "128"; }
+ ListElement{ longitude: "0"; latitude: "94"; height: "128"; }
+ ListElement{ longitude: "0"; latitude: "95"; height: "129"; }
+ ListElement{ longitude: "0"; latitude: "96"; height: "133"; }
+ ListElement{ longitude: "0"; latitude: "97"; height: "138"; }
+ ListElement{ longitude: "0"; latitude: "98"; height: "139"; }
+ ListElement{ longitude: "0"; latitude: "99"; height: "128"; }
+ ListElement{ longitude: "1"; latitude: "0"; height: "120"; }
+ ListElement{ longitude: "1"; latitude: "1"; height: "120"; }
+ ListElement{ longitude: "1"; latitude: "2"; height: "118"; }
+ ListElement{ longitude: "1"; latitude: "3"; height: "110"; }
+ ListElement{ longitude: "1"; latitude: "4"; height: "105"; }
+ ListElement{ longitude: "1"; latitude: "5"; height: "110"; }
+ ListElement{ longitude: "1"; latitude: "6"; height: "116"; }
+ ListElement{ longitude: "1"; latitude: "7"; height: "117"; }
+ ListElement{ longitude: "1"; latitude: "8"; height: "123"; }
+ ListElement{ longitude: "1"; latitude: "9"; height: "128"; }
+ ListElement{ longitude: "1"; latitude: "10"; height: "131"; }
+ ListElement{ longitude: "1"; latitude: "11"; height: "130"; }
+ ListElement{ longitude: "1"; latitude: "12"; height: "128"; }
+ ListElement{ longitude: "1"; latitude: "13"; height: "122"; }
+ ListElement{ longitude: "1"; latitude: "14"; height: "119"; }
+ ListElement{ longitude: "1"; latitude: "15"; height: "116"; }
+ ListElement{ longitude: "1"; latitude: "16"; height: "113"; }
+ ListElement{ longitude: "1"; latitude: "17"; height: "109"; }
+ ListElement{ longitude: "1"; latitude: "18"; height: "109"; }
+ ListElement{ longitude: "1"; latitude: "19"; height: "109"; }
+ ListElement{ longitude: "1"; latitude: "20"; height: "107"; }
+ ListElement{ longitude: "1"; latitude: "21"; height: "109"; }
+ ListElement{ longitude: "1"; latitude: "22"; height: "109"; }
+ ListElement{ longitude: "1"; latitude: "23"; height: "114"; }
+ ListElement{ longitude: "1"; latitude: "24"; height: "117"; }
+ ListElement{ longitude: "1"; latitude: "25"; height: "121"; }
+ ListElement{ longitude: "1"; latitude: "26"; height: "120"; }
+ ListElement{ longitude: "1"; latitude: "27"; height: "118"; }
+ ListElement{ longitude: "1"; latitude: "28"; height: "115"; }
+ ListElement{ longitude: "1"; latitude: "29"; height: "112"; }
+ ListElement{ longitude: "1"; latitude: "30"; height: "110"; }
+ ListElement{ longitude: "1"; latitude: "31"; height: "104"; }
+ ListElement{ longitude: "1"; latitude: "32"; height: "104"; }
+ ListElement{ longitude: "1"; latitude: "33"; height: "103"; }
+ ListElement{ longitude: "1"; latitude: "34"; height: "101"; }
+ ListElement{ longitude: "1"; latitude: "35"; height: "105"; }
+ ListElement{ longitude: "1"; latitude: "36"; height: "108"; }
+ ListElement{ longitude: "1"; latitude: "37"; height: "113"; }
+ ListElement{ longitude: "1"; latitude: "38"; height: "116"; }
+ ListElement{ longitude: "1"; latitude: "39"; height: "117"; }
+ ListElement{ longitude: "1"; latitude: "40"; height: "120"; }
+ ListElement{ longitude: "1"; latitude: "41"; height: "121"; }
+ ListElement{ longitude: "1"; latitude: "42"; height: "121"; }
+ ListElement{ longitude: "1"; latitude: "43"; height: "128"; }
+ ListElement{ longitude: "1"; latitude: "44"; height: "128"; }
+ ListElement{ longitude: "1"; latitude: "45"; height: "126"; }
+ ListElement{ longitude: "1"; latitude: "46"; height: "130"; }
+ ListElement{ longitude: "1"; latitude: "47"; height: "133"; }
+ ListElement{ longitude: "1"; latitude: "48"; height: "134"; }
+ ListElement{ longitude: "1"; latitude: "49"; height: "133"; }
+ ListElement{ longitude: "1"; latitude: "50"; height: "133"; }
+ ListElement{ longitude: "1"; latitude: "51"; height: "128"; }
+ ListElement{ longitude: "1"; latitude: "52"; height: "125"; }
+ ListElement{ longitude: "1"; latitude: "53"; height: "122"; }
+ ListElement{ longitude: "1"; latitude: "54"; height: "118"; }
+ ListElement{ longitude: "1"; latitude: "55"; height: "116"; }
+ ListElement{ longitude: "1"; latitude: "56"; height: "116"; }
+ ListElement{ longitude: "1"; latitude: "57"; height: "117"; }
+ ListElement{ longitude: "1"; latitude: "58"; height: "114"; }
+ ListElement{ longitude: "1"; latitude: "59"; height: "113"; }
+ ListElement{ longitude: "1"; latitude: "60"; height: "109"; }
+ ListElement{ longitude: "1"; latitude: "61"; height: "106"; }
+ ListElement{ longitude: "1"; latitude: "62"; height: "103"; }
+ ListElement{ longitude: "1"; latitude: "63"; height: "105"; }
+ ListElement{ longitude: "1"; latitude: "64"; height: "105"; }
+ ListElement{ longitude: "1"; latitude: "65"; height: "111"; }
+ ListElement{ longitude: "1"; latitude: "66"; height: "112"; }
+ ListElement{ longitude: "1"; latitude: "67"; height: "114"; }
+ ListElement{ longitude: "1"; latitude: "68"; height: "117"; }
+ ListElement{ longitude: "1"; latitude: "69"; height: "119"; }
+ ListElement{ longitude: "1"; latitude: "70"; height: "120"; }
+ ListElement{ longitude: "1"; latitude: "71"; height: "122"; }
+ ListElement{ longitude: "1"; latitude: "72"; height: "123"; }
+ ListElement{ longitude: "1"; latitude: "73"; height: "125"; }
+ ListElement{ longitude: "1"; latitude: "74"; height: "124"; }
+ ListElement{ longitude: "1"; latitude: "75"; height: "123"; }
+ ListElement{ longitude: "1"; latitude: "76"; height: "120"; }
+ ListElement{ longitude: "1"; latitude: "77"; height: "120"; }
+ ListElement{ longitude: "1"; latitude: "78"; height: "122"; }
+ ListElement{ longitude: "1"; latitude: "79"; height: "128"; }
+ ListElement{ longitude: "1"; latitude: "80"; height: "135"; }
+ ListElement{ longitude: "1"; latitude: "81"; height: "140"; }
+ ListElement{ longitude: "1"; latitude: "82"; height: "137"; }
+ ListElement{ longitude: "1"; latitude: "83"; height: "132"; }
+ ListElement{ longitude: "1"; latitude: "84"; height: "124"; }
+ ListElement{ longitude: "1"; latitude: "85"; height: "116"; }
+ ListElement{ longitude: "1"; latitude: "86"; height: "115"; }
+ ListElement{ longitude: "1"; latitude: "87"; height: "120"; }
+ ListElement{ longitude: "1"; latitude: "88"; height: "125"; }
+ ListElement{ longitude: "1"; latitude: "89"; height: "131"; }
+ ListElement{ longitude: "1"; latitude: "90"; height: "134"; }
+ ListElement{ longitude: "1"; latitude: "91"; height: "136"; }
+ ListElement{ longitude: "1"; latitude: "92"; height: "134"; }
+ ListElement{ longitude: "1"; latitude: "93"; height: "131"; }
+ ListElement{ longitude: "1"; latitude: "94"; height: "130"; }
+ ListElement{ longitude: "1"; latitude: "95"; height: "130"; }
+ ListElement{ longitude: "1"; latitude: "96"; height: "133"; }
+ ListElement{ longitude: "1"; latitude: "97"; height: "139"; }
+ ListElement{ longitude: "1"; latitude: "98"; height: "140"; }
+ ListElement{ longitude: "1"; latitude: "99"; height: "124"; }
+ ListElement{ longitude: "2"; latitude: "0"; height: "116"; }
+ ListElement{ longitude: "2"; latitude: "1"; height: "116"; }
+ ListElement{ longitude: "2"; latitude: "2"; height: "111"; }
+ ListElement{ longitude: "2"; latitude: "3"; height: "105"; }
+ ListElement{ longitude: "2"; latitude: "4"; height: "108"; }
+ ListElement{ longitude: "2"; latitude: "5"; height: "110"; }
+ ListElement{ longitude: "2"; latitude: "6"; height: "114"; }
+ ListElement{ longitude: "2"; latitude: "7"; height: "118"; }
+ ListElement{ longitude: "2"; latitude: "8"; height: "124"; }
+ ListElement{ longitude: "2"; latitude: "9"; height: "130"; }
+ ListElement{ longitude: "2"; latitude: "10"; height: "131"; }
+ ListElement{ longitude: "2"; latitude: "11"; height: "134"; }
+ ListElement{ longitude: "2"; latitude: "12"; height: "133"; }
+ ListElement{ longitude: "2"; latitude: "13"; height: "128"; }
+ ListElement{ longitude: "2"; latitude: "14"; height: "125"; }
+ ListElement{ longitude: "2"; latitude: "15"; height: "119"; }
+ ListElement{ longitude: "2"; latitude: "16"; height: "115"; }
+ ListElement{ longitude: "2"; latitude: "17"; height: "111"; }
+ ListElement{ longitude: "2"; latitude: "18"; height: "105"; }
+ ListElement{ longitude: "2"; latitude: "19"; height: "102"; }
+ ListElement{ longitude: "2"; latitude: "20"; height: "99"; }
+ ListElement{ longitude: "2"; latitude: "21"; height: "102"; }
+ ListElement{ longitude: "2"; latitude: "22"; height: "106"; }
+ ListElement{ longitude: "2"; latitude: "23"; height: "110"; }
+ ListElement{ longitude: "2"; latitude: "24"; height: "115"; }
+ ListElement{ longitude: "2"; latitude: "25"; height: "122"; }
+ ListElement{ longitude: "2"; latitude: "26"; height: "122"; }
+ ListElement{ longitude: "2"; latitude: "27"; height: "121"; }
+ ListElement{ longitude: "2"; latitude: "28"; height: "118"; }
+ ListElement{ longitude: "2"; latitude: "29"; height: "115"; }
+ ListElement{ longitude: "2"; latitude: "30"; height: "111"; }
+ ListElement{ longitude: "2"; latitude: "31"; height: "79"; }
+ ListElement{ longitude: "2"; latitude: "32"; height: "94"; }
+ ListElement{ longitude: "2"; latitude: "33"; height: "103"; }
+ ListElement{ longitude: "2"; latitude: "34"; height: "102"; }
+ ListElement{ longitude: "2"; latitude: "35"; height: "103"; }
+ ListElement{ longitude: "2"; latitude: "36"; height: "107"; }
+ ListElement{ longitude: "2"; latitude: "37"; height: "113"; }
+ ListElement{ longitude: "2"; latitude: "38"; height: "116"; }
+ ListElement{ longitude: "2"; latitude: "39"; height: "118"; }
+ ListElement{ longitude: "2"; latitude: "40"; height: "117"; }
+ ListElement{ longitude: "2"; latitude: "41"; height: "119"; }
+ ListElement{ longitude: "2"; latitude: "42"; height: "119"; }
+ ListElement{ longitude: "2"; latitude: "43"; height: "121"; }
+ ListElement{ longitude: "2"; latitude: "44"; height: "123"; }
+ ListElement{ longitude: "2"; latitude: "45"; height: "127"; }
+ ListElement{ longitude: "2"; latitude: "46"; height: "131"; }
+ ListElement{ longitude: "2"; latitude: "47"; height: "132"; }
+ ListElement{ longitude: "2"; latitude: "48"; height: "132"; }
+ ListElement{ longitude: "2"; latitude: "49"; height: "135"; }
+ ListElement{ longitude: "2"; latitude: "50"; height: "134"; }
+ ListElement{ longitude: "2"; latitude: "51"; height: "130"; }
+ ListElement{ longitude: "2"; latitude: "52"; height: "128"; }
+ ListElement{ longitude: "2"; latitude: "53"; height: "123"; }
+ ListElement{ longitude: "2"; latitude: "54"; height: "120"; }
+ ListElement{ longitude: "2"; latitude: "55"; height: "118"; }
+ ListElement{ longitude: "2"; latitude: "56"; height: "118"; }
+ ListElement{ longitude: "2"; latitude: "57"; height: "123"; }
+ ListElement{ longitude: "2"; latitude: "58"; height: "121"; }
+ ListElement{ longitude: "2"; latitude: "59"; height: "120"; }
+ ListElement{ longitude: "2"; latitude: "60"; height: "114"; }
+ ListElement{ longitude: "2"; latitude: "61"; height: "107"; }
+ ListElement{ longitude: "2"; latitude: "62"; height: "103"; }
+ ListElement{ longitude: "2"; latitude: "63"; height: "103"; }
+ ListElement{ longitude: "2"; latitude: "64"; height: "106"; }
+ ListElement{ longitude: "2"; latitude: "65"; height: "108"; }
+ ListElement{ longitude: "2"; latitude: "66"; height: "109"; }
+ ListElement{ longitude: "2"; latitude: "67"; height: "114"; }
+ ListElement{ longitude: "2"; latitude: "68"; height: "117"; }
+ ListElement{ longitude: "2"; latitude: "69"; height: "121"; }
+ ListElement{ longitude: "2"; latitude: "70"; height: "121"; }
+ ListElement{ longitude: "2"; latitude: "71"; height: "122"; }
+ ListElement{ longitude: "2"; latitude: "72"; height: "123"; }
+ ListElement{ longitude: "2"; latitude: "73"; height: "123"; }
+ ListElement{ longitude: "2"; latitude: "74"; height: "122"; }
+ ListElement{ longitude: "2"; latitude: "75"; height: "123"; }
+ ListElement{ longitude: "2"; latitude: "76"; height: "120"; }
+ ListElement{ longitude: "2"; latitude: "77"; height: "118"; }
+ ListElement{ longitude: "2"; latitude: "78"; height: "119"; }
+ ListElement{ longitude: "2"; latitude: "79"; height: "125"; }
+ ListElement{ longitude: "2"; latitude: "80"; height: "130"; }
+ ListElement{ longitude: "2"; latitude: "81"; height: "138"; }
+ ListElement{ longitude: "2"; latitude: "82"; height: "138"; }
+ ListElement{ longitude: "2"; latitude: "83"; height: "131"; }
+ ListElement{ longitude: "2"; latitude: "84"; height: "125"; }
+ ListElement{ longitude: "2"; latitude: "85"; height: "122"; }
+ ListElement{ longitude: "2"; latitude: "86"; height: "121"; }
+ ListElement{ longitude: "2"; latitude: "87"; height: "133"; }
+ ListElement{ longitude: "2"; latitude: "88"; height: "132"; }
+ ListElement{ longitude: "2"; latitude: "89"; height: "135"; }
+ ListElement{ longitude: "2"; latitude: "90"; height: "138"; }
+ ListElement{ longitude: "2"; latitude: "91"; height: "137"; }
+ ListElement{ longitude: "2"; latitude: "92"; height: "137"; }
+ ListElement{ longitude: "2"; latitude: "93"; height: "134"; }
+ ListElement{ longitude: "2"; latitude: "94"; height: "133"; }
+ ListElement{ longitude: "2"; latitude: "95"; height: "133"; }
+ ListElement{ longitude: "2"; latitude: "96"; height: "133"; }
+ ListElement{ longitude: "2"; latitude: "97"; height: "140"; }
+ ListElement{ longitude: "2"; latitude: "98"; height: "140"; }
+ ListElement{ longitude: "2"; latitude: "99"; height: "121"; }
+ ListElement{ longitude: "3"; latitude: "0"; height: "115"; }
+ ListElement{ longitude: "3"; latitude: "1"; height: "111"; }
+ ListElement{ longitude: "3"; latitude: "2"; height: "108"; }
+ ListElement{ longitude: "3"; latitude: "3"; height: "107"; }
+ ListElement{ longitude: "3"; latitude: "4"; height: "108"; }
+ ListElement{ longitude: "3"; latitude: "5"; height: "111"; }
+ ListElement{ longitude: "3"; latitude: "6"; height: "117"; }
+ ListElement{ longitude: "3"; latitude: "7"; height: "119"; }
+ ListElement{ longitude: "3"; latitude: "8"; height: "124"; }
+ ListElement{ longitude: "3"; latitude: "9"; height: "130"; }
+ ListElement{ longitude: "3"; latitude: "10"; height: "133"; }
+ ListElement{ longitude: "3"; latitude: "11"; height: "136"; }
+ ListElement{ longitude: "3"; latitude: "12"; height: "136"; }
+ ListElement{ longitude: "3"; latitude: "13"; height: "132"; }
+ ListElement{ longitude: "3"; latitude: "14"; height: "129"; }
+ ListElement{ longitude: "3"; latitude: "15"; height: "125"; }
+ ListElement{ longitude: "3"; latitude: "16"; height: "119"; }
+ ListElement{ longitude: "3"; latitude: "17"; height: "115"; }
+ ListElement{ longitude: "3"; latitude: "18"; height: "106"; }
+ ListElement{ longitude: "3"; latitude: "19"; height: "101"; }
+ ListElement{ longitude: "3"; latitude: "20"; height: "99"; }
+ ListElement{ longitude: "3"; latitude: "21"; height: "98"; }
+ ListElement{ longitude: "3"; latitude: "22"; height: "103"; }
+ ListElement{ longitude: "3"; latitude: "23"; height: "109"; }
+ ListElement{ longitude: "3"; latitude: "24"; height: "115"; }
+ ListElement{ longitude: "3"; latitude: "25"; height: "121"; }
+ ListElement{ longitude: "3"; latitude: "26"; height: "126"; }
+ ListElement{ longitude: "3"; latitude: "27"; height: "127"; }
+ ListElement{ longitude: "3"; latitude: "28"; height: "123"; }
+ ListElement{ longitude: "3"; latitude: "29"; height: "117"; }
+ ListElement{ longitude: "3"; latitude: "30"; height: "116"; }
+ ListElement{ longitude: "3"; latitude: "31"; height: "106"; }
+ ListElement{ longitude: "3"; latitude: "32"; height: "105"; }
+ ListElement{ longitude: "3"; latitude: "33"; height: "100"; }
+ ListElement{ longitude: "3"; latitude: "34"; height: "99"; }
+ ListElement{ longitude: "3"; latitude: "35"; height: "103"; }
+ ListElement{ longitude: "3"; latitude: "36"; height: "106"; }
+ ListElement{ longitude: "3"; latitude: "37"; height: "114"; }
+ ListElement{ longitude: "3"; latitude: "38"; height: "115"; }
+ ListElement{ longitude: "3"; latitude: "39"; height: "115"; }
+ ListElement{ longitude: "3"; latitude: "40"; height: "115"; }
+ ListElement{ longitude: "3"; latitude: "41"; height: "116"; }
+ ListElement{ longitude: "3"; latitude: "42"; height: "117"; }
+ ListElement{ longitude: "3"; latitude: "43"; height: "119"; }
+ ListElement{ longitude: "3"; latitude: "44"; height: "124"; }
+ ListElement{ longitude: "3"; latitude: "45"; height: "127"; }
+ ListElement{ longitude: "3"; latitude: "46"; height: "129"; }
+ ListElement{ longitude: "3"; latitude: "47"; height: "128"; }
+ ListElement{ longitude: "3"; latitude: "48"; height: "135"; }
+ ListElement{ longitude: "3"; latitude: "49"; height: "139"; }
+ ListElement{ longitude: "3"; latitude: "50"; height: "139"; }
+ ListElement{ longitude: "3"; latitude: "51"; height: "136"; }
+ ListElement{ longitude: "3"; latitude: "52"; height: "130"; }
+ ListElement{ longitude: "3"; latitude: "53"; height: "126"; }
+ ListElement{ longitude: "3"; latitude: "54"; height: "121"; }
+ ListElement{ longitude: "3"; latitude: "55"; height: "120"; }
+ ListElement{ longitude: "3"; latitude: "56"; height: "121"; }
+ ListElement{ longitude: "3"; latitude: "57"; height: "128"; }
+ ListElement{ longitude: "3"; latitude: "58"; height: "98"; }
+ ListElement{ longitude: "3"; latitude: "59"; height: "78"; }
+ ListElement{ longitude: "3"; latitude: "60"; height: "115"; }
+ ListElement{ longitude: "3"; latitude: "61"; height: "112"; }
+ ListElement{ longitude: "3"; latitude: "62"; height: "108"; }
+ ListElement{ longitude: "3"; latitude: "63"; height: "106"; }
+ ListElement{ longitude: "3"; latitude: "64"; height: "105"; }
+ ListElement{ longitude: "3"; latitude: "65"; height: "108"; }
+ ListElement{ longitude: "3"; latitude: "66"; height: "111"; }
+ ListElement{ longitude: "3"; latitude: "67"; height: "115"; }
+ ListElement{ longitude: "3"; latitude: "68"; height: "120"; }
+ ListElement{ longitude: "3"; latitude: "69"; height: "121"; }
+ ListElement{ longitude: "3"; latitude: "70"; height: "123"; }
+ ListElement{ longitude: "3"; latitude: "71"; height: "124"; }
+ ListElement{ longitude: "3"; latitude: "72"; height: "126"; }
+ ListElement{ longitude: "3"; latitude: "73"; height: "127"; }
+ ListElement{ longitude: "3"; latitude: "74"; height: "126"; }
+ ListElement{ longitude: "3"; latitude: "75"; height: "124"; }
+ ListElement{ longitude: "3"; latitude: "76"; height: "121"; }
+ ListElement{ longitude: "3"; latitude: "77"; height: "117"; }
+ ListElement{ longitude: "3"; latitude: "78"; height: "113"; }
+ ListElement{ longitude: "3"; latitude: "79"; height: "119"; }
+ ListElement{ longitude: "3"; latitude: "80"; height: "124"; }
+ ListElement{ longitude: "3"; latitude: "81"; height: "130"; }
+ ListElement{ longitude: "3"; latitude: "82"; height: "133"; }
+ ListElement{ longitude: "3"; latitude: "83"; height: "131"; }
+ ListElement{ longitude: "3"; latitude: "84"; height: "124"; }
+ ListElement{ longitude: "3"; latitude: "85"; height: "122"; }
+ ListElement{ longitude: "3"; latitude: "86"; height: "66"; }
+ ListElement{ longitude: "3"; latitude: "87"; height: "109"; }
+ ListElement{ longitude: "3"; latitude: "88"; height: "136"; }
+ ListElement{ longitude: "3"; latitude: "89"; height: "142"; }
+ ListElement{ longitude: "3"; latitude: "90"; height: "144"; }
+ ListElement{ longitude: "3"; latitude: "91"; height: "144"; }
+ ListElement{ longitude: "3"; latitude: "92"; height: "141"; }
+ ListElement{ longitude: "3"; latitude: "93"; height: "137"; }
+ ListElement{ longitude: "3"; latitude: "94"; height: "136"; }
+ ListElement{ longitude: "3"; latitude: "95"; height: "136"; }
+ ListElement{ longitude: "3"; latitude: "96"; height: "139"; }
+ ListElement{ longitude: "3"; latitude: "97"; height: "142"; }
+ ListElement{ longitude: "3"; latitude: "98"; height: "142"; }
+ ListElement{ longitude: "3"; latitude: "99"; height: "120"; }
+ ListElement{ longitude: "4"; latitude: "0"; height: "112"; }
+ ListElement{ longitude: "4"; latitude: "1"; height: "107"; }
+ ListElement{ longitude: "4"; latitude: "2"; height: "107"; }
+ ListElement{ longitude: "4"; latitude: "3"; height: "106"; }
+ ListElement{ longitude: "4"; latitude: "4"; height: "110"; }
+ ListElement{ longitude: "4"; latitude: "5"; height: "113"; }
+ ListElement{ longitude: "4"; latitude: "6"; height: "117"; }
+ ListElement{ longitude: "4"; latitude: "7"; height: "122"; }
+ ListElement{ longitude: "4"; latitude: "8"; height: "128"; }
+ ListElement{ longitude: "4"; latitude: "9"; height: "131"; }
+ ListElement{ longitude: "4"; latitude: "10"; height: "134"; }
+ ListElement{ longitude: "4"; latitude: "11"; height: "135"; }
+ ListElement{ longitude: "4"; latitude: "12"; height: "135"; }
+ ListElement{ longitude: "4"; latitude: "13"; height: "135"; }
+ ListElement{ longitude: "4"; latitude: "14"; height: "133"; }
+ ListElement{ longitude: "4"; latitude: "15"; height: "131"; }
+ ListElement{ longitude: "4"; latitude: "16"; height: "125"; }
+ ListElement{ longitude: "4"; latitude: "17"; height: "119"; }
+ ListElement{ longitude: "4"; latitude: "18"; height: "111"; }
+ ListElement{ longitude: "4"; latitude: "19"; height: "107"; }
+ ListElement{ longitude: "4"; latitude: "20"; height: "100"; }
+ ListElement{ longitude: "4"; latitude: "21"; height: "102"; }
+ ListElement{ longitude: "4"; latitude: "22"; height: "103"; }
+ ListElement{ longitude: "4"; latitude: "23"; height: "110"; }
+ ListElement{ longitude: "4"; latitude: "24"; height: "115"; }
+ ListElement{ longitude: "4"; latitude: "25"; height: "124"; }
+ ListElement{ longitude: "4"; latitude: "26"; height: "126"; }
+ ListElement{ longitude: "4"; latitude: "27"; height: "131"; }
+ ListElement{ longitude: "4"; latitude: "28"; height: "108"; }
+ ListElement{ longitude: "4"; latitude: "29"; height: "103"; }
+ ListElement{ longitude: "4"; latitude: "30"; height: "117"; }
+ ListElement{ longitude: "4"; latitude: "31"; height: "114"; }
+ ListElement{ longitude: "4"; latitude: "32"; height: "105"; }
+ ListElement{ longitude: "4"; latitude: "33"; height: "101"; }
+ ListElement{ longitude: "4"; latitude: "34"; height: "101"; }
+ ListElement{ longitude: "4"; latitude: "35"; height: "103"; }
+ ListElement{ longitude: "4"; latitude: "36"; height: "108"; }
+ ListElement{ longitude: "4"; latitude: "37"; height: "112"; }
+ ListElement{ longitude: "4"; latitude: "38"; height: "114"; }
+ ListElement{ longitude: "4"; latitude: "39"; height: "116"; }
+ ListElement{ longitude: "4"; latitude: "40"; height: "116"; }
+ ListElement{ longitude: "4"; latitude: "41"; height: "117"; }
+ ListElement{ longitude: "4"; latitude: "42"; height: "117"; }
+ ListElement{ longitude: "4"; latitude: "43"; height: "121"; }
+ ListElement{ longitude: "4"; latitude: "44"; height: "122"; }
+ ListElement{ longitude: "4"; latitude: "45"; height: "125"; }
+ ListElement{ longitude: "4"; latitude: "46"; height: "127"; }
+ ListElement{ longitude: "4"; latitude: "47"; height: "130"; }
+ ListElement{ longitude: "4"; latitude: "48"; height: "137"; }
+ ListElement{ longitude: "4"; latitude: "49"; height: "147"; }
+ ListElement{ longitude: "4"; latitude: "50"; height: "143"; }
+ ListElement{ longitude: "4"; latitude: "51"; height: "143"; }
+ ListElement{ longitude: "4"; latitude: "52"; height: "133"; }
+ ListElement{ longitude: "4"; latitude: "53"; height: "127"; }
+ ListElement{ longitude: "4"; latitude: "54"; height: "123"; }
+ ListElement{ longitude: "4"; latitude: "55"; height: "121"; }
+ ListElement{ longitude: "4"; latitude: "56"; height: "123"; }
+ ListElement{ longitude: "4"; latitude: "57"; height: "132"; }
+ ListElement{ longitude: "4"; latitude: "58"; height: "125"; }
+ ListElement{ longitude: "4"; latitude: "59"; height: "120"; }
+ ListElement{ longitude: "4"; latitude: "60"; height: "123"; }
+ ListElement{ longitude: "4"; latitude: "61"; height: "116"; }
+ ListElement{ longitude: "4"; latitude: "62"; height: "111"; }
+ ListElement{ longitude: "4"; latitude: "63"; height: "109"; }
+ ListElement{ longitude: "4"; latitude: "64"; height: "107"; }
+ ListElement{ longitude: "4"; latitude: "65"; height: "110"; }
+ ListElement{ longitude: "4"; latitude: "66"; height: "113"; }
+ ListElement{ longitude: "4"; latitude: "67"; height: "117"; }
+ ListElement{ longitude: "4"; latitude: "68"; height: "123"; }
+ ListElement{ longitude: "4"; latitude: "69"; height: "126"; }
+ ListElement{ longitude: "4"; latitude: "70"; height: "127"; }
+ ListElement{ longitude: "4"; latitude: "71"; height: "128"; }
+ ListElement{ longitude: "4"; latitude: "72"; height: "128"; }
+ ListElement{ longitude: "4"; latitude: "73"; height: "128"; }
+ ListElement{ longitude: "4"; latitude: "74"; height: "116"; }
+ ListElement{ longitude: "4"; latitude: "75"; height: "116"; }
+ ListElement{ longitude: "4"; latitude: "76"; height: "130"; }
+ ListElement{ longitude: "4"; latitude: "77"; height: "116"; }
+ ListElement{ longitude: "4"; latitude: "78"; height: "112"; }
+ ListElement{ longitude: "4"; latitude: "79"; height: "115"; }
+ ListElement{ longitude: "4"; latitude: "80"; height: "120"; }
+ ListElement{ longitude: "4"; latitude: "81"; height: "126"; }
+ ListElement{ longitude: "4"; latitude: "82"; height: "128"; }
+ ListElement{ longitude: "4"; latitude: "83"; height: "126"; }
+ ListElement{ longitude: "4"; latitude: "84"; height: "124"; }
+ ListElement{ longitude: "4"; latitude: "85"; height: "128"; }
+ ListElement{ longitude: "4"; latitude: "86"; height: "121"; }
+ ListElement{ longitude: "4"; latitude: "87"; height: "132"; }
+ ListElement{ longitude: "4"; latitude: "88"; height: "141"; }
+ ListElement{ longitude: "4"; latitude: "89"; height: "147"; }
+ ListElement{ longitude: "4"; latitude: "90"; height: "148"; }
+ ListElement{ longitude: "4"; latitude: "91"; height: "147"; }
+ ListElement{ longitude: "4"; latitude: "92"; height: "144"; }
+ ListElement{ longitude: "4"; latitude: "93"; height: "141"; }
+ ListElement{ longitude: "4"; latitude: "94"; height: "138"; }
+ ListElement{ longitude: "4"; latitude: "95"; height: "138"; }
+ ListElement{ longitude: "4"; latitude: "96"; height: "141"; }
+ ListElement{ longitude: "4"; latitude: "97"; height: "145"; }
+ ListElement{ longitude: "4"; latitude: "98"; height: "143"; }
+ ListElement{ longitude: "4"; latitude: "99"; height: "121"; }
+ ListElement{ longitude: "5"; latitude: "0"; height: "112"; }
+ ListElement{ longitude: "5"; latitude: "1"; height: "109"; }
+ ListElement{ longitude: "5"; latitude: "2"; height: "108"; }
+ ListElement{ longitude: "5"; latitude: "3"; height: "107"; }
+ ListElement{ longitude: "5"; latitude: "4"; height: "112"; }
+ ListElement{ longitude: "5"; latitude: "5"; height: "116"; }
+ ListElement{ longitude: "5"; latitude: "6"; height: "122"; }
+ ListElement{ longitude: "5"; latitude: "7"; height: "126"; }
+ ListElement{ longitude: "5"; latitude: "8"; height: "130"; }
+ ListElement{ longitude: "5"; latitude: "9"; height: "133"; }
+ ListElement{ longitude: "5"; latitude: "10"; height: "135"; }
+ ListElement{ longitude: "5"; latitude: "11"; height: "136"; }
+ ListElement{ longitude: "5"; latitude: "12"; height: "137"; }
+ ListElement{ longitude: "5"; latitude: "13"; height: "129"; }
+ ListElement{ longitude: "5"; latitude: "14"; height: "126"; }
+ ListElement{ longitude: "5"; latitude: "15"; height: "134"; }
+ ListElement{ longitude: "5"; latitude: "16"; height: "129"; }
+ ListElement{ longitude: "5"; latitude: "17"; height: "123"; }
+ ListElement{ longitude: "5"; latitude: "18"; height: "116"; }
+ ListElement{ longitude: "5"; latitude: "19"; height: "108"; }
+ ListElement{ longitude: "5"; latitude: "20"; height: "102"; }
+ ListElement{ longitude: "5"; latitude: "21"; height: "102"; }
+ ListElement{ longitude: "5"; latitude: "22"; height: "105"; }
+ ListElement{ longitude: "5"; latitude: "23"; height: "113"; }
+ ListElement{ longitude: "5"; latitude: "24"; height: "118"; }
+ ListElement{ longitude: "5"; latitude: "25"; height: "127"; }
+ ListElement{ longitude: "5"; latitude: "26"; height: "130"; }
+ ListElement{ longitude: "5"; latitude: "27"; height: "133"; }
+ ListElement{ longitude: "5"; latitude: "28"; height: "129"; }
+ ListElement{ longitude: "5"; latitude: "29"; height: "123"; }
+ ListElement{ longitude: "5"; latitude: "30"; height: "66"; }
+ ListElement{ longitude: "5"; latitude: "31"; height: "102"; }
+ ListElement{ longitude: "5"; latitude: "32"; height: "106"; }
+ ListElement{ longitude: "5"; latitude: "33"; height: "100"; }
+ ListElement{ longitude: "5"; latitude: "34"; height: "100"; }
+ ListElement{ longitude: "5"; latitude: "35"; height: "104"; }
+ ListElement{ longitude: "5"; latitude: "36"; height: "107"; }
+ ListElement{ longitude: "5"; latitude: "37"; height: "110"; }
+ ListElement{ longitude: "5"; latitude: "38"; height: "112"; }
+ ListElement{ longitude: "5"; latitude: "39"; height: "113"; }
+ ListElement{ longitude: "5"; latitude: "40"; height: "114"; }
+ ListElement{ longitude: "5"; latitude: "41"; height: "116"; }
+ ListElement{ longitude: "5"; latitude: "42"; height: "118"; }
+ ListElement{ longitude: "5"; latitude: "43"; height: "121"; }
+ ListElement{ longitude: "5"; latitude: "44"; height: "123"; }
+ ListElement{ longitude: "5"; latitude: "45"; height: "127"; }
+ ListElement{ longitude: "5"; latitude: "46"; height: "127"; }
+ ListElement{ longitude: "5"; latitude: "47"; height: "130"; }
+ ListElement{ longitude: "5"; latitude: "48"; height: "137"; }
+ ListElement{ longitude: "5"; latitude: "49"; height: "139"; }
+ ListElement{ longitude: "5"; latitude: "50"; height: "77"; }
+ ListElement{ longitude: "5"; latitude: "51"; height: "123"; }
+ ListElement{ longitude: "5"; latitude: "52"; height: "131"; }
+ ListElement{ longitude: "5"; latitude: "53"; height: "126"; }
+ ListElement{ longitude: "5"; latitude: "54"; height: "123"; }
+ ListElement{ longitude: "5"; latitude: "55"; height: "123"; }
+ ListElement{ longitude: "5"; latitude: "56"; height: "124"; }
+ ListElement{ longitude: "5"; latitude: "57"; height: "127"; }
+ ListElement{ longitude: "5"; latitude: "58"; height: "129"; }
+ ListElement{ longitude: "5"; latitude: "59"; height: "129"; }
+ ListElement{ longitude: "5"; latitude: "60"; height: "123"; }
+ ListElement{ longitude: "5"; latitude: "61"; height: "121"; }
+ ListElement{ longitude: "5"; latitude: "62"; height: "116"; }
+ ListElement{ longitude: "5"; latitude: "63"; height: "113"; }
+ ListElement{ longitude: "5"; latitude: "64"; height: "110"; }
+ ListElement{ longitude: "5"; latitude: "65"; height: "111"; }
+ ListElement{ longitude: "5"; latitude: "66"; height: "116"; }
+ ListElement{ longitude: "5"; latitude: "67"; height: "121"; }
+ ListElement{ longitude: "5"; latitude: "68"; height: "127"; }
+ ListElement{ longitude: "5"; latitude: "69"; height: "130"; }
+ ListElement{ longitude: "5"; latitude: "70"; height: "130"; }
+ ListElement{ longitude: "5"; latitude: "71"; height: "131"; }
+ ListElement{ longitude: "5"; latitude: "72"; height: "133"; }
+ ListElement{ longitude: "5"; latitude: "73"; height: "128"; }
+ ListElement{ longitude: "5"; latitude: "74"; height: "107"; }
+ ListElement{ longitude: "5"; latitude: "75"; height: "74"; }
+ ListElement{ longitude: "5"; latitude: "76"; height: "121"; }
+ ListElement{ longitude: "5"; latitude: "77"; height: "116"; }
+ ListElement{ longitude: "5"; latitude: "78"; height: "109"; }
+ ListElement{ longitude: "5"; latitude: "79"; height: "110"; }
+ ListElement{ longitude: "5"; latitude: "80"; height: "113"; }
+ ListElement{ longitude: "5"; latitude: "81"; height: "118"; }
+ ListElement{ longitude: "5"; latitude: "82"; height: "120"; }
+ ListElement{ longitude: "5"; latitude: "83"; height: "124"; }
+ ListElement{ longitude: "5"; latitude: "84"; height: "123"; }
+ ListElement{ longitude: "5"; latitude: "85"; height: "122"; }
+ ListElement{ longitude: "5"; latitude: "86"; height: "127"; }
+ ListElement{ longitude: "5"; latitude: "87"; height: "135"; }
+ ListElement{ longitude: "5"; latitude: "88"; height: "140"; }
+ ListElement{ longitude: "5"; latitude: "89"; height: "146"; }
+ ListElement{ longitude: "5"; latitude: "90"; height: "150"; }
+ ListElement{ longitude: "5"; latitude: "91"; height: "148"; }
+ ListElement{ longitude: "5"; latitude: "92"; height: "146"; }
+ ListElement{ longitude: "5"; latitude: "93"; height: "142"; }
+ ListElement{ longitude: "5"; latitude: "94"; height: "140"; }
+ ListElement{ longitude: "5"; latitude: "95"; height: "140"; }
+ ListElement{ longitude: "5"; latitude: "96"; height: "142"; }
+ ListElement{ longitude: "5"; latitude: "97"; height: "144"; }
+ ListElement{ longitude: "5"; latitude: "98"; height: "145"; }
+ ListElement{ longitude: "5"; latitude: "99"; height: "123"; }
+ ListElement{ longitude: "6"; latitude: "0"; height: "115"; }
+ ListElement{ longitude: "6"; latitude: "1"; height: "111"; }
+ ListElement{ longitude: "6"; latitude: "2"; height: "110"; }
+ ListElement{ longitude: "6"; latitude: "3"; height: "111"; }
+ ListElement{ longitude: "6"; latitude: "4"; height: "116"; }
+ ListElement{ longitude: "6"; latitude: "5"; height: "119"; }
+ ListElement{ longitude: "6"; latitude: "6"; height: "125"; }
+ ListElement{ longitude: "6"; latitude: "7"; height: "129"; }
+ ListElement{ longitude: "6"; latitude: "8"; height: "132"; }
+ ListElement{ longitude: "6"; latitude: "9"; height: "132"; }
+ ListElement{ longitude: "6"; latitude: "10"; height: "135"; }
+ ListElement{ longitude: "6"; latitude: "11"; height: "136"; }
+ ListElement{ longitude: "6"; latitude: "12"; height: "135"; }
+ ListElement{ longitude: "6"; latitude: "13"; height: "126"; }
+ ListElement{ longitude: "6"; latitude: "14"; height: "137"; }
+ ListElement{ longitude: "6"; latitude: "15"; height: "136"; }
+ ListElement{ longitude: "6"; latitude: "16"; height: "132"; }
+ ListElement{ longitude: "6"; latitude: "17"; height: "128"; }
+ ListElement{ longitude: "6"; latitude: "18"; height: "118"; }
+ ListElement{ longitude: "6"; latitude: "19"; height: "111"; }
+ ListElement{ longitude: "6"; latitude: "20"; height: "105"; }
+ ListElement{ longitude: "6"; latitude: "21"; height: "106"; }
+ ListElement{ longitude: "6"; latitude: "22"; height: "107"; }
+ ListElement{ longitude: "6"; latitude: "23"; height: "115"; }
+ ListElement{ longitude: "6"; latitude: "24"; height: "121"; }
+ ListElement{ longitude: "6"; latitude: "25"; height: "111"; }
+ ListElement{ longitude: "6"; latitude: "26"; height: "78"; }
+ ListElement{ longitude: "6"; latitude: "27"; height: "131"; }
+ ListElement{ longitude: "6"; latitude: "28"; height: "130"; }
+ ListElement{ longitude: "6"; latitude: "29"; height: "129"; }
+ ListElement{ longitude: "6"; latitude: "30"; height: "103"; }
+ ListElement{ longitude: "6"; latitude: "31"; height: "113"; }
+ ListElement{ longitude: "6"; latitude: "32"; height: "108"; }
+ ListElement{ longitude: "6"; latitude: "33"; height: "103"; }
+ ListElement{ longitude: "6"; latitude: "34"; height: "103"; }
+ ListElement{ longitude: "6"; latitude: "35"; height: "107"; }
+ ListElement{ longitude: "6"; latitude: "36"; height: "109"; }
+ ListElement{ longitude: "6"; latitude: "37"; height: "113"; }
+ ListElement{ longitude: "6"; latitude: "38"; height: "112"; }
+ ListElement{ longitude: "6"; latitude: "39"; height: "115"; }
+ ListElement{ longitude: "6"; latitude: "40"; height: "115"; }
+ ListElement{ longitude: "6"; latitude: "41"; height: "119"; }
+ ListElement{ longitude: "6"; latitude: "42"; height: "122"; }
+ ListElement{ longitude: "6"; latitude: "43"; height: "125"; }
+ ListElement{ longitude: "6"; latitude: "44"; height: "127"; }
+ ListElement{ longitude: "6"; latitude: "45"; height: "127"; }
+ ListElement{ longitude: "6"; latitude: "46"; height: "129"; }
+ ListElement{ longitude: "6"; latitude: "47"; height: "131"; }
+ ListElement{ longitude: "6"; latitude: "48"; height: "133"; }
+ ListElement{ longitude: "6"; latitude: "49"; height: "141"; }
+ ListElement{ longitude: "6"; latitude: "50"; height: "135"; }
+ ListElement{ longitude: "6"; latitude: "51"; height: "137"; }
+ ListElement{ longitude: "6"; latitude: "52"; height: "132"; }
+ ListElement{ longitude: "6"; latitude: "53"; height: "124"; }
+ ListElement{ longitude: "6"; latitude: "54"; height: "122"; }
+ ListElement{ longitude: "6"; latitude: "55"; height: "125"; }
+ ListElement{ longitude: "6"; latitude: "56"; height: "126"; }
+ ListElement{ longitude: "6"; latitude: "57"; height: "127"; }
+ ListElement{ longitude: "6"; latitude: "58"; height: "128"; }
+ ListElement{ longitude: "6"; latitude: "59"; height: "127"; }
+ ListElement{ longitude: "6"; latitude: "60"; height: "126"; }
+ ListElement{ longitude: "6"; latitude: "61"; height: "124"; }
+ ListElement{ longitude: "6"; latitude: "62"; height: "120"; }
+ ListElement{ longitude: "6"; latitude: "63"; height: "118"; }
+ ListElement{ longitude: "6"; latitude: "64"; height: "118"; }
+ ListElement{ longitude: "6"; latitude: "65"; height: "117"; }
+ ListElement{ longitude: "6"; latitude: "66"; height: "119"; }
+ ListElement{ longitude: "6"; latitude: "67"; height: "124"; }
+ ListElement{ longitude: "6"; latitude: "68"; height: "125"; }
+ ListElement{ longitude: "6"; latitude: "69"; height: "130"; }
+ ListElement{ longitude: "6"; latitude: "70"; height: "132"; }
+ ListElement{ longitude: "6"; latitude: "71"; height: "135"; }
+ ListElement{ longitude: "6"; latitude: "72"; height: "136"; }
+ ListElement{ longitude: "6"; latitude: "73"; height: "135"; }
+ ListElement{ longitude: "6"; latitude: "74"; height: "131"; }
+ ListElement{ longitude: "6"; latitude: "75"; height: "135"; }
+ ListElement{ longitude: "6"; latitude: "76"; height: "123"; }
+ ListElement{ longitude: "6"; latitude: "77"; height: "112"; }
+ ListElement{ longitude: "6"; latitude: "78"; height: "106"; }
+ ListElement{ longitude: "6"; latitude: "79"; height: "106"; }
+ ListElement{ longitude: "6"; latitude: "80"; height: "107"; }
+ ListElement{ longitude: "6"; latitude: "81"; height: "110"; }
+ ListElement{ longitude: "6"; latitude: "82"; height: "114"; }
+ ListElement{ longitude: "6"; latitude: "83"; height: "116"; }
+ ListElement{ longitude: "6"; latitude: "84"; height: "92"; }
+ ListElement{ longitude: "6"; latitude: "85"; height: "105"; }
+ ListElement{ longitude: "6"; latitude: "86"; height: "124"; }
+ ListElement{ longitude: "6"; latitude: "87"; height: "130"; }
+ ListElement{ longitude: "6"; latitude: "88"; height: "138"; }
+ ListElement{ longitude: "6"; latitude: "89"; height: "142"; }
+ ListElement{ longitude: "6"; latitude: "90"; height: "147"; }
+ ListElement{ longitude: "6"; latitude: "91"; height: "147"; }
+ ListElement{ longitude: "6"; latitude: "92"; height: "142"; }
+ ListElement{ longitude: "6"; latitude: "93"; height: "139"; }
+ ListElement{ longitude: "6"; latitude: "94"; height: "138"; }
+ ListElement{ longitude: "6"; latitude: "95"; height: "136"; }
+ ListElement{ longitude: "6"; latitude: "96"; height: "141"; }
+ ListElement{ longitude: "6"; latitude: "97"; height: "142"; }
+ ListElement{ longitude: "6"; latitude: "98"; height: "146"; }
+ ListElement{ longitude: "6"; latitude: "99"; height: "126"; }
+ ListElement{ longitude: "7"; latitude: "0"; height: "117"; }
+ ListElement{ longitude: "7"; latitude: "1"; height: "111"; }
+ ListElement{ longitude: "7"; latitude: "2"; height: "108"; }
+ ListElement{ longitude: "7"; latitude: "3"; height: "112"; }
+ ListElement{ longitude: "7"; latitude: "4"; height: "119"; }
+ ListElement{ longitude: "7"; latitude: "5"; height: "124"; }
+ ListElement{ longitude: "7"; latitude: "6"; height: "130"; }
+ ListElement{ longitude: "7"; latitude: "7"; height: "131"; }
+ ListElement{ longitude: "7"; latitude: "8"; height: "133"; }
+ ListElement{ longitude: "7"; latitude: "9"; height: "136"; }
+ ListElement{ longitude: "7"; latitude: "10"; height: "133"; }
+ ListElement{ longitude: "7"; latitude: "11"; height: "134"; }
+ ListElement{ longitude: "7"; latitude: "12"; height: "138"; }
+ ListElement{ longitude: "7"; latitude: "13"; height: "138"; }
+ ListElement{ longitude: "7"; latitude: "14"; height: "138"; }
+ ListElement{ longitude: "7"; latitude: "15"; height: "138"; }
+ ListElement{ longitude: "7"; latitude: "16"; height: "136"; }
+ ListElement{ longitude: "7"; latitude: "17"; height: "129"; }
+ ListElement{ longitude: "7"; latitude: "18"; height: "123"; }
+ ListElement{ longitude: "7"; latitude: "19"; height: "115"; }
+ ListElement{ longitude: "7"; latitude: "20"; height: "109"; }
+ ListElement{ longitude: "7"; latitude: "21"; height: "109"; }
+ ListElement{ longitude: "7"; latitude: "22"; height: "109"; }
+ ListElement{ longitude: "7"; latitude: "23"; height: "117"; }
+ ListElement{ longitude: "7"; latitude: "24"; height: "124"; }
+ ListElement{ longitude: "7"; latitude: "25"; height: "122"; }
+ ListElement{ longitude: "7"; latitude: "26"; height: "105"; }
+ ListElement{ longitude: "7"; latitude: "27"; height: "131"; }
+ ListElement{ longitude: "7"; latitude: "28"; height: "127"; }
+ ListElement{ longitude: "7"; latitude: "29"; height: "127"; }
+ ListElement{ longitude: "7"; latitude: "30"; height: "121"; }
+ ListElement{ longitude: "7"; latitude: "31"; height: "115"; }
+ ListElement{ longitude: "7"; latitude: "32"; height: "110"; }
+ ListElement{ longitude: "7"; latitude: "33"; height: "108"; }
+ ListElement{ longitude: "7"; latitude: "34"; height: "107"; }
+ ListElement{ longitude: "7"; latitude: "35"; height: "113"; }
+ ListElement{ longitude: "7"; latitude: "36"; height: "115"; }
+ ListElement{ longitude: "7"; latitude: "37"; height: "115"; }
+ ListElement{ longitude: "7"; latitude: "38"; height: "114"; }
+ ListElement{ longitude: "7"; latitude: "39"; height: "114"; }
+ ListElement{ longitude: "7"; latitude: "40"; height: "116"; }
+ ListElement{ longitude: "7"; latitude: "41"; height: "119"; }
+ ListElement{ longitude: "7"; latitude: "42"; height: "122"; }
+ ListElement{ longitude: "7"; latitude: "43"; height: "127"; }
+ ListElement{ longitude: "7"; latitude: "44"; height: "129"; }
+ ListElement{ longitude: "7"; latitude: "45"; height: "129"; }
+ ListElement{ longitude: "7"; latitude: "46"; height: "132"; }
+ ListElement{ longitude: "7"; latitude: "47"; height: "132"; }
+ ListElement{ longitude: "7"; latitude: "48"; height: "135"; }
+ ListElement{ longitude: "7"; latitude: "49"; height: "136"; }
+ ListElement{ longitude: "7"; latitude: "50"; height: "137"; }
+ ListElement{ longitude: "7"; latitude: "51"; height: "133"; }
+ ListElement{ longitude: "7"; latitude: "52"; height: "130"; }
+ ListElement{ longitude: "7"; latitude: "53"; height: "126"; }
+ ListElement{ longitude: "7"; latitude: "54"; height: "124"; }
+ ListElement{ longitude: "7"; latitude: "55"; height: "125"; }
+ ListElement{ longitude: "7"; latitude: "56"; height: "124"; }
+ ListElement{ longitude: "7"; latitude: "57"; height: "125"; }
+ ListElement{ longitude: "7"; latitude: "58"; height: "127"; }
+ ListElement{ longitude: "7"; latitude: "59"; height: "127"; }
+ ListElement{ longitude: "7"; latitude: "60"; height: "127"; }
+ ListElement{ longitude: "7"; latitude: "61"; height: "127"; }
+ ListElement{ longitude: "7"; latitude: "62"; height: "126"; }
+ ListElement{ longitude: "7"; latitude: "63"; height: "125"; }
+ ListElement{ longitude: "7"; latitude: "64"; height: "121"; }
+ ListElement{ longitude: "7"; latitude: "65"; height: "122"; }
+ ListElement{ longitude: "7"; latitude: "66"; height: "127"; }
+ ListElement{ longitude: "7"; latitude: "67"; height: "129"; }
+ ListElement{ longitude: "7"; latitude: "68"; height: "130"; }
+ ListElement{ longitude: "7"; latitude: "69"; height: "129"; }
+ ListElement{ longitude: "7"; latitude: "70"; height: "130"; }
+ ListElement{ longitude: "7"; latitude: "71"; height: "136"; }
+ ListElement{ longitude: "7"; latitude: "72"; height: "135"; }
+ ListElement{ longitude: "7"; latitude: "73"; height: "136"; }
+ ListElement{ longitude: "7"; latitude: "74"; height: "132"; }
+ ListElement{ longitude: "7"; latitude: "75"; height: "124"; }
+ ListElement{ longitude: "7"; latitude: "76"; height: "118"; }
+ ListElement{ longitude: "7"; latitude: "77"; height: "110"; }
+ ListElement{ longitude: "7"; latitude: "78"; height: "103"; }
+ ListElement{ longitude: "7"; latitude: "79"; height: "101"; }
+ ListElement{ longitude: "7"; latitude: "80"; height: "103"; }
+ ListElement{ longitude: "7"; latitude: "81"; height: "105"; }
+ ListElement{ longitude: "7"; latitude: "82"; height: "107"; }
+ ListElement{ longitude: "7"; latitude: "83"; height: "112"; }
+ ListElement{ longitude: "7"; latitude: "84"; height: "104"; }
+ ListElement{ longitude: "7"; latitude: "85"; height: "109"; }
+ ListElement{ longitude: "7"; latitude: "86"; height: "119"; }
+ ListElement{ longitude: "7"; latitude: "87"; height: "125"; }
+ ListElement{ longitude: "7"; latitude: "88"; height: "132"; }
+ ListElement{ longitude: "7"; latitude: "89"; height: "139"; }
+ ListElement{ longitude: "7"; latitude: "90"; height: "143"; }
+ ListElement{ longitude: "7"; latitude: "91"; height: "146"; }
+ ListElement{ longitude: "7"; latitude: "92"; height: "143"; }
+ ListElement{ longitude: "7"; latitude: "93"; height: "139"; }
+ ListElement{ longitude: "7"; latitude: "94"; height: "138"; }
+ ListElement{ longitude: "7"; latitude: "95"; height: "138"; }
+ ListElement{ longitude: "7"; latitude: "96"; height: "141"; }
+ ListElement{ longitude: "7"; latitude: "97"; height: "143"; }
+ ListElement{ longitude: "7"; latitude: "98"; height: "147"; }
+ ListElement{ longitude: "7"; latitude: "99"; height: "130"; }
+ ListElement{ longitude: "8"; latitude: "0"; height: "119"; }
+ ListElement{ longitude: "8"; latitude: "1"; height: "113"; }
+ ListElement{ longitude: "8"; latitude: "2"; height: "114"; }
+ ListElement{ longitude: "8"; latitude: "3"; height: "115"; }
+ ListElement{ longitude: "8"; latitude: "4"; height: "121"; }
+ ListElement{ longitude: "8"; latitude: "5"; height: "127"; }
+ ListElement{ longitude: "8"; latitude: "6"; height: "132"; }
+ ListElement{ longitude: "8"; latitude: "7"; height: "132"; }
+ ListElement{ longitude: "8"; latitude: "8"; height: "134"; }
+ ListElement{ longitude: "8"; latitude: "9"; height: "135"; }
+ ListElement{ longitude: "8"; latitude: "10"; height: "133"; }
+ ListElement{ longitude: "8"; latitude: "11"; height: "135"; }
+ ListElement{ longitude: "8"; latitude: "12"; height: "138"; }
+ ListElement{ longitude: "8"; latitude: "13"; height: "137"; }
+ ListElement{ longitude: "8"; latitude: "14"; height: "137"; }
+ ListElement{ longitude: "8"; latitude: "15"; height: "138"; }
+ ListElement{ longitude: "8"; latitude: "16"; height: "138"; }
+ ListElement{ longitude: "8"; latitude: "17"; height: "133"; }
+ ListElement{ longitude: "8"; latitude: "18"; height: "126"; }
+ ListElement{ longitude: "8"; latitude: "19"; height: "118"; }
+ ListElement{ longitude: "8"; latitude: "20"; height: "114"; }
+ ListElement{ longitude: "8"; latitude: "21"; height: "114"; }
+ ListElement{ longitude: "8"; latitude: "22"; height: "115"; }
+ ListElement{ longitude: "8"; latitude: "23"; height: "120"; }
+ ListElement{ longitude: "8"; latitude: "24"; height: "123"; }
+ ListElement{ longitude: "8"; latitude: "25"; height: "124"; }
+ ListElement{ longitude: "8"; latitude: "26"; height: "129"; }
+ ListElement{ longitude: "8"; latitude: "27"; height: "130"; }
+ ListElement{ longitude: "8"; latitude: "28"; height: "127"; }
+ ListElement{ longitude: "8"; latitude: "29"; height: "123"; }
+ ListElement{ longitude: "8"; latitude: "30"; height: "121"; }
+ ListElement{ longitude: "8"; latitude: "31"; height: "116"; }
+ ListElement{ longitude: "8"; latitude: "32"; height: "115"; }
+ ListElement{ longitude: "8"; latitude: "33"; height: "113"; }
+ ListElement{ longitude: "8"; latitude: "34"; height: "114"; }
+ ListElement{ longitude: "8"; latitude: "35"; height: "119"; }
+ ListElement{ longitude: "8"; latitude: "36"; height: "117"; }
+ ListElement{ longitude: "8"; latitude: "37"; height: "117"; }
+ ListElement{ longitude: "8"; latitude: "38"; height: "118"; }
+ ListElement{ longitude: "8"; latitude: "39"; height: "116"; }
+ ListElement{ longitude: "8"; latitude: "40"; height: "118"; }
+ ListElement{ longitude: "8"; latitude: "41"; height: "121"; }
+ ListElement{ longitude: "8"; latitude: "42"; height: "126"; }
+ ListElement{ longitude: "8"; latitude: "43"; height: "131"; }
+ ListElement{ longitude: "8"; latitude: "44"; height: "130"; }
+ ListElement{ longitude: "8"; latitude: "45"; height: "133"; }
+ ListElement{ longitude: "8"; latitude: "46"; height: "132"; }
+ ListElement{ longitude: "8"; latitude: "47"; height: "133"; }
+ ListElement{ longitude: "8"; latitude: "48"; height: "136"; }
+ ListElement{ longitude: "8"; latitude: "49"; height: "136"; }
+ ListElement{ longitude: "8"; latitude: "50"; height: "136"; }
+ ListElement{ longitude: "8"; latitude: "51"; height: "132"; }
+ ListElement{ longitude: "8"; latitude: "52"; height: "129"; }
+ ListElement{ longitude: "8"; latitude: "53"; height: "126"; }
+ ListElement{ longitude: "8"; latitude: "54"; height: "124"; }
+ ListElement{ longitude: "8"; latitude: "55"; height: "125"; }
+ ListElement{ longitude: "8"; latitude: "56"; height: "124"; }
+ ListElement{ longitude: "8"; latitude: "57"; height: "126"; }
+ ListElement{ longitude: "8"; latitude: "58"; height: "127"; }
+ ListElement{ longitude: "8"; latitude: "59"; height: "127"; }
+ ListElement{ longitude: "8"; latitude: "60"; height: "127"; }
+ ListElement{ longitude: "8"; latitude: "61"; height: "127"; }
+ ListElement{ longitude: "8"; latitude: "62"; height: "116"; }
+ ListElement{ longitude: "8"; latitude: "63"; height: "126"; }
+ ListElement{ longitude: "8"; latitude: "64"; height: "128"; }
+ ListElement{ longitude: "8"; latitude: "65"; height: "129"; }
+ ListElement{ longitude: "8"; latitude: "66"; height: "110"; }
+ ListElement{ longitude: "8"; latitude: "67"; height: "107"; }
+ ListElement{ longitude: "8"; latitude: "68"; height: "124"; }
+ ListElement{ longitude: "8"; latitude: "69"; height: "131"; }
+ ListElement{ longitude: "8"; latitude: "70"; height: "130"; }
+ ListElement{ longitude: "8"; latitude: "71"; height: "134"; }
+ ListElement{ longitude: "8"; latitude: "72"; height: "138"; }
+ ListElement{ longitude: "8"; latitude: "73"; height: "136"; }
+ ListElement{ longitude: "8"; latitude: "74"; height: "127"; }
+ ListElement{ longitude: "8"; latitude: "75"; height: "117"; }
+ ListElement{ longitude: "8"; latitude: "76"; height: "115"; }
+ ListElement{ longitude: "8"; latitude: "77"; height: "111"; }
+ ListElement{ longitude: "8"; latitude: "78"; height: "100"; }
+ ListElement{ longitude: "8"; latitude: "79"; height: "99"; }
+ ListElement{ longitude: "8"; latitude: "80"; height: "99"; }
+ ListElement{ longitude: "8"; latitude: "81"; height: "102"; }
+ ListElement{ longitude: "8"; latitude: "82"; height: "101"; }
+ ListElement{ longitude: "8"; latitude: "83"; height: "105"; }
+ ListElement{ longitude: "8"; latitude: "84"; height: "107"; }
+ ListElement{ longitude: "8"; latitude: "85"; height: "103"; }
+ ListElement{ longitude: "8"; latitude: "86"; height: "110"; }
+ ListElement{ longitude: "8"; latitude: "87"; height: "119"; }
+ ListElement{ longitude: "8"; latitude: "88"; height: "126"; }
+ ListElement{ longitude: "8"; latitude: "89"; height: "134"; }
+ ListElement{ longitude: "8"; latitude: "90"; height: "136"; }
+ ListElement{ longitude: "8"; latitude: "91"; height: "138"; }
+ ListElement{ longitude: "8"; latitude: "92"; height: "136"; }
+ ListElement{ longitude: "8"; latitude: "93"; height: "137"; }
+ ListElement{ longitude: "8"; latitude: "94"; height: "136"; }
+ ListElement{ longitude: "8"; latitude: "95"; height: "134"; }
+ ListElement{ longitude: "8"; latitude: "96"; height: "135"; }
+ ListElement{ longitude: "8"; latitude: "97"; height: "137"; }
+ ListElement{ longitude: "8"; latitude: "98"; height: "143"; }
+ ListElement{ longitude: "8"; latitude: "99"; height: "137"; }
+ ListElement{ longitude: "9"; latitude: "0"; height: "120"; }
+ ListElement{ longitude: "9"; latitude: "1"; height: "118"; }
+ ListElement{ longitude: "9"; latitude: "2"; height: "118"; }
+ ListElement{ longitude: "9"; latitude: "3"; height: "120"; }
+ ListElement{ longitude: "9"; latitude: "4"; height: "126"; }
+ ListElement{ longitude: "9"; latitude: "5"; height: "129"; }
+ ListElement{ longitude: "9"; latitude: "6"; height: "133"; }
+ ListElement{ longitude: "9"; latitude: "7"; height: "132"; }
+ ListElement{ longitude: "9"; latitude: "8"; height: "133"; }
+ ListElement{ longitude: "9"; latitude: "9"; height: "134"; }
+ ListElement{ longitude: "9"; latitude: "10"; height: "134"; }
+ ListElement{ longitude: "9"; latitude: "11"; height: "134"; }
+ ListElement{ longitude: "9"; latitude: "12"; height: "131"; }
+ ListElement{ longitude: "9"; latitude: "13"; height: "134"; }
+ ListElement{ longitude: "9"; latitude: "14"; height: "136"; }
+ ListElement{ longitude: "9"; latitude: "15"; height: "137"; }
+ ListElement{ longitude: "9"; latitude: "16"; height: "131"; }
+ ListElement{ longitude: "9"; latitude: "17"; height: "119"; }
+ ListElement{ longitude: "9"; latitude: "18"; height: "126"; }
+ ListElement{ longitude: "9"; latitude: "19"; height: "121"; }
+ ListElement{ longitude: "9"; latitude: "20"; height: "120"; }
+ ListElement{ longitude: "9"; latitude: "21"; height: "117"; }
+ ListElement{ longitude: "9"; latitude: "22"; height: "116"; }
+ ListElement{ longitude: "9"; latitude: "23"; height: "119"; }
+ ListElement{ longitude: "9"; latitude: "24"; height: "122"; }
+ ListElement{ longitude: "9"; latitude: "25"; height: "122"; }
+ ListElement{ longitude: "9"; latitude: "26"; height: "120"; }
+ ListElement{ longitude: "9"; latitude: "27"; height: "121"; }
+ ListElement{ longitude: "9"; latitude: "28"; height: "121"; }
+ ListElement{ longitude: "9"; latitude: "29"; height: "120"; }
+ ListElement{ longitude: "9"; latitude: "30"; height: "120"; }
+ ListElement{ longitude: "9"; latitude: "31"; height: "117"; }
+ ListElement{ longitude: "9"; latitude: "32"; height: "116"; }
+ ListElement{ longitude: "9"; latitude: "33"; height: "118"; }
+ ListElement{ longitude: "9"; latitude: "34"; height: "120"; }
+ ListElement{ longitude: "9"; latitude: "35"; height: "123"; }
+ ListElement{ longitude: "9"; latitude: "36"; height: "122"; }
+ ListElement{ longitude: "9"; latitude: "37"; height: "122"; }
+ ListElement{ longitude: "9"; latitude: "38"; height: "121"; }
+ ListElement{ longitude: "9"; latitude: "39"; height: "119"; }
+ ListElement{ longitude: "9"; latitude: "40"; height: "120"; }
+ ListElement{ longitude: "9"; latitude: "41"; height: "121"; }
+ ListElement{ longitude: "9"; latitude: "42"; height: "128"; }
+ ListElement{ longitude: "9"; latitude: "43"; height: "132"; }
+ ListElement{ longitude: "9"; latitude: "44"; height: "134"; }
+ ListElement{ longitude: "9"; latitude: "45"; height: "135"; }
+ ListElement{ longitude: "9"; latitude: "46"; height: "135"; }
+ ListElement{ longitude: "9"; latitude: "47"; height: "133"; }
+ ListElement{ longitude: "9"; latitude: "48"; height: "136"; }
+ ListElement{ longitude: "9"; latitude: "49"; height: "136"; }
+ ListElement{ longitude: "9"; latitude: "50"; height: "136"; }
+ ListElement{ longitude: "9"; latitude: "51"; height: "132"; }
+ ListElement{ longitude: "9"; latitude: "52"; height: "131"; }
+ ListElement{ longitude: "9"; latitude: "53"; height: "126"; }
+ ListElement{ longitude: "9"; latitude: "54"; height: "124"; }
+ ListElement{ longitude: "9"; latitude: "55"; height: "125"; }
+ ListElement{ longitude: "9"; latitude: "56"; height: "123"; }
+ ListElement{ longitude: "9"; latitude: "57"; height: "125"; }
+ ListElement{ longitude: "9"; latitude: "58"; height: "126"; }
+ ListElement{ longitude: "9"; latitude: "59"; height: "125"; }
+ ListElement{ longitude: "9"; latitude: "60"; height: "127"; }
+ ListElement{ longitude: "9"; latitude: "61"; height: "129"; }
+ ListElement{ longitude: "9"; latitude: "62"; height: "129"; }
+ ListElement{ longitude: "9"; latitude: "63"; height: "127"; }
+ ListElement{ longitude: "9"; latitude: "64"; height: "131"; }
+ ListElement{ longitude: "9"; latitude: "65"; height: "122"; }
+ ListElement{ longitude: "9"; latitude: "66"; height: "107"; }
+ ListElement{ longitude: "9"; latitude: "67"; height: "103"; }
+ ListElement{ longitude: "9"; latitude: "68"; height: "105"; }
+ ListElement{ longitude: "9"; latitude: "69"; height: "112"; }
+ ListElement{ longitude: "9"; latitude: "70"; height: "130"; }
+ ListElement{ longitude: "9"; latitude: "71"; height: "134"; }
+ ListElement{ longitude: "9"; latitude: "72"; height: "140"; }
+ ListElement{ longitude: "9"; latitude: "73"; height: "134"; }
+ ListElement{ longitude: "9"; latitude: "74"; height: "129"; }
+ ListElement{ longitude: "9"; latitude: "75"; height: "120"; }
+ ListElement{ longitude: "9"; latitude: "76"; height: "117"; }
+ ListElement{ longitude: "9"; latitude: "77"; height: "113"; }
+ ListElement{ longitude: "9"; latitude: "78"; height: "102"; }
+ ListElement{ longitude: "9"; latitude: "79"; height: "99"; }
+ ListElement{ longitude: "9"; latitude: "80"; height: "101"; }
+ ListElement{ longitude: "9"; latitude: "81"; height: "101"; }
+ ListElement{ longitude: "9"; latitude: "82"; height: "101"; }
+ ListElement{ longitude: "9"; latitude: "83"; height: "101"; }
+ ListElement{ longitude: "9"; latitude: "84"; height: "96"; }
+ ListElement{ longitude: "9"; latitude: "85"; height: "98"; }
+ ListElement{ longitude: "9"; latitude: "86"; height: "106"; }
+ ListElement{ longitude: "9"; latitude: "87"; height: "112"; }
+ ListElement{ longitude: "9"; latitude: "88"; height: "119"; }
+ ListElement{ longitude: "9"; latitude: "89"; height: "126"; }
+ ListElement{ longitude: "9"; latitude: "90"; height: "128"; }
+ ListElement{ longitude: "9"; latitude: "91"; height: "132"; }
+ ListElement{ longitude: "9"; latitude: "92"; height: "134"; }
+ ListElement{ longitude: "9"; latitude: "93"; height: "134"; }
+ ListElement{ longitude: "9"; latitude: "94"; height: "131"; }
+ ListElement{ longitude: "9"; latitude: "95"; height: "131"; }
+ ListElement{ longitude: "9"; latitude: "96"; height: "131"; }
+ ListElement{ longitude: "9"; latitude: "97"; height: "137"; }
+ ListElement{ longitude: "9"; latitude: "98"; height: "141"; }
+ ListElement{ longitude: "9"; latitude: "99"; height: "139"; }
+ ListElement{ longitude: "10"; latitude: "0"; height: "122"; }
+ ListElement{ longitude: "10"; latitude: "1"; height: "121"; }
+ ListElement{ longitude: "10"; latitude: "2"; height: "122"; }
+ ListElement{ longitude: "10"; latitude: "3"; height: "124"; }
+ ListElement{ longitude: "10"; latitude: "4"; height: "129"; }
+ ListElement{ longitude: "10"; latitude: "5"; height: "131"; }
+ ListElement{ longitude: "10"; latitude: "6"; height: "132"; }
+ ListElement{ longitude: "10"; latitude: "7"; height: "130"; }
+ ListElement{ longitude: "10"; latitude: "8"; height: "130"; }
+ ListElement{ longitude: "10"; latitude: "9"; height: "130"; }
+ ListElement{ longitude: "10"; latitude: "10"; height: "133"; }
+ ListElement{ longitude: "10"; latitude: "11"; height: "135"; }
+ ListElement{ longitude: "10"; latitude: "12"; height: "130"; }
+ ListElement{ longitude: "10"; latitude: "13"; height: "134"; }
+ ListElement{ longitude: "10"; latitude: "14"; height: "135"; }
+ ListElement{ longitude: "10"; latitude: "15"; height: "133"; }
+ ListElement{ longitude: "10"; latitude: "16"; height: "129"; }
+ ListElement{ longitude: "10"; latitude: "17"; height: "105"; }
+ ListElement{ longitude: "10"; latitude: "18"; height: "127"; }
+ ListElement{ longitude: "10"; latitude: "19"; height: "124"; }
+ ListElement{ longitude: "10"; latitude: "20"; height: "115"; }
+ ListElement{ longitude: "10"; latitude: "21"; height: "101"; }
+ ListElement{ longitude: "10"; latitude: "22"; height: "103"; }
+ ListElement{ longitude: "10"; latitude: "23"; height: "113"; }
+ ListElement{ longitude: "10"; latitude: "24"; height: "120"; }
+ ListElement{ longitude: "10"; latitude: "25"; height: "120"; }
+ ListElement{ longitude: "10"; latitude: "26"; height: "118"; }
+ ListElement{ longitude: "10"; latitude: "27"; height: "118"; }
+ ListElement{ longitude: "10"; latitude: "28"; height: "120"; }
+ ListElement{ longitude: "10"; latitude: "29"; height: "120"; }
+ ListElement{ longitude: "10"; latitude: "30"; height: "120"; }
+ ListElement{ longitude: "10"; latitude: "31"; height: "119"; }
+ ListElement{ longitude: "10"; latitude: "32"; height: "119"; }
+ ListElement{ longitude: "10"; latitude: "33"; height: "119"; }
+ ListElement{ longitude: "10"; latitude: "34"; height: "123"; }
+ ListElement{ longitude: "10"; latitude: "35"; height: "124"; }
+ ListElement{ longitude: "10"; latitude: "36"; height: "125"; }
+ ListElement{ longitude: "10"; latitude: "37"; height: "125"; }
+ ListElement{ longitude: "10"; latitude: "38"; height: "122"; }
+ ListElement{ longitude: "10"; latitude: "39"; height: "121"; }
+ ListElement{ longitude: "10"; latitude: "40"; height: "122"; }
+ ListElement{ longitude: "10"; latitude: "41"; height: "125"; }
+ ListElement{ longitude: "10"; latitude: "42"; height: "130"; }
+ ListElement{ longitude: "10"; latitude: "43"; height: "135"; }
+ ListElement{ longitude: "10"; latitude: "44"; height: "135"; }
+ ListElement{ longitude: "10"; latitude: "45"; height: "138"; }
+ ListElement{ longitude: "10"; latitude: "46"; height: "136"; }
+ ListElement{ longitude: "10"; latitude: "47"; height: "136"; }
+ ListElement{ longitude: "10"; latitude: "48"; height: "136"; }
+ ListElement{ longitude: "10"; latitude: "49"; height: "136"; }
+ ListElement{ longitude: "10"; latitude: "50"; height: "136"; }
+ ListElement{ longitude: "10"; latitude: "51"; height: "134"; }
+ ListElement{ longitude: "10"; latitude: "52"; height: "131"; }
+ ListElement{ longitude: "10"; latitude: "53"; height: "127"; }
+ ListElement{ longitude: "10"; latitude: "54"; height: "124"; }
+ ListElement{ longitude: "10"; latitude: "55"; height: "122"; }
+ ListElement{ longitude: "10"; latitude: "56"; height: "122"; }
+ ListElement{ longitude: "10"; latitude: "57"; height: "124"; }
+ ListElement{ longitude: "10"; latitude: "58"; height: "125"; }
+ ListElement{ longitude: "10"; latitude: "59"; height: "126"; }
+ ListElement{ longitude: "10"; latitude: "60"; height: "127"; }
+ ListElement{ longitude: "10"; latitude: "61"; height: "128"; }
+ ListElement{ longitude: "10"; latitude: "62"; height: "128"; }
+ ListElement{ longitude: "10"; latitude: "63"; height: "115"; }
+ ListElement{ longitude: "10"; latitude: "64"; height: "133"; }
+ ListElement{ longitude: "10"; latitude: "65"; height: "126"; }
+ ListElement{ longitude: "10"; latitude: "66"; height: "115"; }
+ ListElement{ longitude: "10"; latitude: "67"; height: "105"; }
+ ListElement{ longitude: "10"; latitude: "68"; height: "98"; }
+ ListElement{ longitude: "10"; latitude: "69"; height: "106"; }
+ ListElement{ longitude: "10"; latitude: "70"; height: "132"; }
+ ListElement{ longitude: "10"; latitude: "71"; height: "134"; }
+ ListElement{ longitude: "10"; latitude: "72"; height: "139"; }
+ ListElement{ longitude: "10"; latitude: "73"; height: "137"; }
+ ListElement{ longitude: "10"; latitude: "74"; height: "130"; }
+ ListElement{ longitude: "10"; latitude: "75"; height: "122"; }
+ ListElement{ longitude: "10"; latitude: "76"; height: "116"; }
+ ListElement{ longitude: "10"; latitude: "77"; height: "107"; }
+ ListElement{ longitude: "10"; latitude: "78"; height: "104"; }
+ ListElement{ longitude: "10"; latitude: "79"; height: "104"; }
+ ListElement{ longitude: "10"; latitude: "80"; height: "104"; }
+ ListElement{ longitude: "10"; latitude: "81"; height: "105"; }
+ ListElement{ longitude: "10"; latitude: "82"; height: "102"; }
+ ListElement{ longitude: "10"; latitude: "83"; height: "100"; }
+ ListElement{ longitude: "10"; latitude: "84"; height: "99"; }
+ ListElement{ longitude: "10"; latitude: "85"; height: "102"; }
+ ListElement{ longitude: "10"; latitude: "86"; height: "101"; }
+ ListElement{ longitude: "10"; latitude: "87"; height: "110"; }
+ ListElement{ longitude: "10"; latitude: "88"; height: "114"; }
+ ListElement{ longitude: "10"; latitude: "89"; height: "121"; }
+ ListElement{ longitude: "10"; latitude: "90"; height: "125"; }
+ ListElement{ longitude: "10"; latitude: "91"; height: "128"; }
+ ListElement{ longitude: "10"; latitude: "92"; height: "128"; }
+ ListElement{ longitude: "10"; latitude: "93"; height: "130"; }
+ ListElement{ longitude: "10"; latitude: "94"; height: "129"; }
+ ListElement{ longitude: "10"; latitude: "95"; height: "131"; }
+ ListElement{ longitude: "10"; latitude: "96"; height: "131"; }
+ ListElement{ longitude: "10"; latitude: "97"; height: "132"; }
+ ListElement{ longitude: "10"; latitude: "98"; height: "139"; }
+ ListElement{ longitude: "10"; latitude: "99"; height: "140"; }
+ ListElement{ longitude: "11"; latitude: "0"; height: "122"; }
+ ListElement{ longitude: "11"; latitude: "1"; height: "128"; }
+ ListElement{ longitude: "11"; latitude: "2"; height: "127"; }
+ ListElement{ longitude: "11"; latitude: "3"; height: "129"; }
+ ListElement{ longitude: "11"; latitude: "4"; height: "131"; }
+ ListElement{ longitude: "11"; latitude: "5"; height: "132"; }
+ ListElement{ longitude: "11"; latitude: "6"; height: "132"; }
+ ListElement{ longitude: "11"; latitude: "7"; height: "130"; }
+ ListElement{ longitude: "11"; latitude: "8"; height: "131"; }
+ ListElement{ longitude: "11"; latitude: "9"; height: "130"; }
+ ListElement{ longitude: "11"; latitude: "10"; height: "130"; }
+ ListElement{ longitude: "11"; latitude: "11"; height: "133"; }
+ ListElement{ longitude: "11"; latitude: "12"; height: "131"; }
+ ListElement{ longitude: "11"; latitude: "13"; height: "134"; }
+ ListElement{ longitude: "11"; latitude: "14"; height: "135"; }
+ ListElement{ longitude: "11"; latitude: "15"; height: "130"; }
+ ListElement{ longitude: "11"; latitude: "16"; height: "130"; }
+ ListElement{ longitude: "11"; latitude: "17"; height: "130"; }
+ ListElement{ longitude: "11"; latitude: "18"; height: "127"; }
+ ListElement{ longitude: "11"; latitude: "19"; height: "124"; }
+ ListElement{ longitude: "11"; latitude: "20"; height: "100"; }
+ ListElement{ longitude: "11"; latitude: "21"; height: "86"; }
+ ListElement{ longitude: "11"; latitude: "22"; height: "90"; }
+ ListElement{ longitude: "11"; latitude: "23"; height: "104"; }
+ ListElement{ longitude: "11"; latitude: "24"; height: "117"; }
+ ListElement{ longitude: "11"; latitude: "25"; height: "120"; }
+ ListElement{ longitude: "11"; latitude: "26"; height: "115"; }
+ ListElement{ longitude: "11"; latitude: "27"; height: "115"; }
+ ListElement{ longitude: "11"; latitude: "28"; height: "117"; }
+ ListElement{ longitude: "11"; latitude: "29"; height: "118"; }
+ ListElement{ longitude: "11"; latitude: "30"; height: "116"; }
+ ListElement{ longitude: "11"; latitude: "31"; height: "117"; }
+ ListElement{ longitude: "11"; latitude: "32"; height: "118"; }
+ ListElement{ longitude: "11"; latitude: "33"; height: "120"; }
+ ListElement{ longitude: "11"; latitude: "34"; height: "126"; }
+ ListElement{ longitude: "11"; latitude: "35"; height: "126"; }
+ ListElement{ longitude: "11"; latitude: "36"; height: "127"; }
+ ListElement{ longitude: "11"; latitude: "37"; height: "127"; }
+ ListElement{ longitude: "11"; latitude: "38"; height: "126"; }
+ ListElement{ longitude: "11"; latitude: "39"; height: "124"; }
+ ListElement{ longitude: "11"; latitude: "40"; height: "126"; }
+ ListElement{ longitude: "11"; latitude: "41"; height: "128"; }
+ ListElement{ longitude: "11"; latitude: "42"; height: "131"; }
+ ListElement{ longitude: "11"; latitude: "43"; height: "135"; }
+ ListElement{ longitude: "11"; latitude: "44"; height: "135"; }
+ ListElement{ longitude: "11"; latitude: "45"; height: "138"; }
+ ListElement{ longitude: "11"; latitude: "46"; height: "135"; }
+ ListElement{ longitude: "11"; latitude: "47"; height: "136"; }
+ ListElement{ longitude: "11"; latitude: "48"; height: "136"; }
+ ListElement{ longitude: "11"; latitude: "49"; height: "136"; }
+ ListElement{ longitude: "11"; latitude: "50"; height: "136"; }
+ ListElement{ longitude: "11"; latitude: "51"; height: "134"; }
+ ListElement{ longitude: "11"; latitude: "52"; height: "132"; }
+ ListElement{ longitude: "11"; latitude: "53"; height: "129"; }
+ ListElement{ longitude: "11"; latitude: "54"; height: "124"; }
+ ListElement{ longitude: "11"; latitude: "55"; height: "122"; }
+ ListElement{ longitude: "11"; latitude: "56"; height: "121"; }
+ ListElement{ longitude: "11"; latitude: "57"; height: "123"; }
+ ListElement{ longitude: "11"; latitude: "58"; height: "122"; }
+ ListElement{ longitude: "11"; latitude: "59"; height: "125"; }
+ ListElement{ longitude: "11"; latitude: "60"; height: "127"; }
+ ListElement{ longitude: "11"; latitude: "61"; height: "128"; }
+ ListElement{ longitude: "11"; latitude: "62"; height: "128"; }
+ ListElement{ longitude: "11"; latitude: "63"; height: "130"; }
+ ListElement{ longitude: "11"; latitude: "64"; height: "131"; }
+ ListElement{ longitude: "11"; latitude: "65"; height: "127"; }
+ ListElement{ longitude: "11"; latitude: "66"; height: "103"; }
+ ListElement{ longitude: "11"; latitude: "67"; height: "110"; }
+ ListElement{ longitude: "11"; latitude: "68"; height: "102"; }
+ ListElement{ longitude: "11"; latitude: "69"; height: "114"; }
+ ListElement{ longitude: "11"; latitude: "70"; height: "130"; }
+ ListElement{ longitude: "11"; latitude: "71"; height: "134"; }
+ ListElement{ longitude: "11"; latitude: "72"; height: "137"; }
+ ListElement{ longitude: "11"; latitude: "73"; height: "133"; }
+ ListElement{ longitude: "11"; latitude: "74"; height: "122"; }
+ ListElement{ longitude: "11"; latitude: "75"; height: "120"; }
+ ListElement{ longitude: "11"; latitude: "76"; height: "114"; }
+ ListElement{ longitude: "11"; latitude: "77"; height: "110"; }
+ ListElement{ longitude: "11"; latitude: "78"; height: "109"; }
+ ListElement{ longitude: "11"; latitude: "79"; height: "111"; }
+ ListElement{ longitude: "11"; latitude: "80"; height: "111"; }
+ ListElement{ longitude: "11"; latitude: "81"; height: "111"; }
+ ListElement{ longitude: "11"; latitude: "82"; height: "103"; }
+ ListElement{ longitude: "11"; latitude: "83"; height: "102"; }
+ ListElement{ longitude: "11"; latitude: "84"; height: "98"; }
+ ListElement{ longitude: "11"; latitude: "85"; height: "100"; }
+ ListElement{ longitude: "11"; latitude: "86"; height: "102"; }
+ ListElement{ longitude: "11"; latitude: "87"; height: "104"; }
+ ListElement{ longitude: "11"; latitude: "88"; height: "110"; }
+ ListElement{ longitude: "11"; latitude: "89"; height: "115"; }
+ ListElement{ longitude: "11"; latitude: "90"; height: "119"; }
+ ListElement{ longitude: "11"; latitude: "91"; height: "122"; }
+ ListElement{ longitude: "11"; latitude: "92"; height: "126"; }
+ ListElement{ longitude: "11"; latitude: "93"; height: "126"; }
+ ListElement{ longitude: "11"; latitude: "94"; height: "127"; }
+ ListElement{ longitude: "11"; latitude: "95"; height: "128"; }
+ ListElement{ longitude: "11"; latitude: "96"; height: "130"; }
+ ListElement{ longitude: "11"; latitude: "97"; height: "133"; }
+ ListElement{ longitude: "11"; latitude: "98"; height: "141"; }
+ ListElement{ longitude: "11"; latitude: "99"; height: "142"; }
+ ListElement{ longitude: "12"; latitude: "0"; height: "120"; }
+ ListElement{ longitude: "12"; latitude: "1"; height: "122"; }
+ ListElement{ longitude: "12"; latitude: "2"; height: "130"; }
+ ListElement{ longitude: "12"; latitude: "3"; height: "134"; }
+ ListElement{ longitude: "12"; latitude: "4"; height: "136"; }
+ ListElement{ longitude: "12"; latitude: "5"; height: "134"; }
+ ListElement{ longitude: "12"; latitude: "6"; height: "131"; }
+ ListElement{ longitude: "12"; latitude: "7"; height: "131"; }
+ ListElement{ longitude: "12"; latitude: "8"; height: "131"; }
+ ListElement{ longitude: "12"; latitude: "9"; height: "131"; }
+ ListElement{ longitude: "12"; latitude: "10"; height: "129"; }
+ ListElement{ longitude: "12"; latitude: "11"; height: "130"; }
+ ListElement{ longitude: "12"; latitude: "12"; height: "133"; }
+ ListElement{ longitude: "12"; latitude: "13"; height: "133"; }
+ ListElement{ longitude: "12"; latitude: "14"; height: "132"; }
+ ListElement{ longitude: "12"; latitude: "15"; height: "129"; }
+ ListElement{ longitude: "12"; latitude: "16"; height: "129"; }
+ ListElement{ longitude: "12"; latitude: "17"; height: "125"; }
+ ListElement{ longitude: "12"; latitude: "18"; height: "126"; }
+ ListElement{ longitude: "12"; latitude: "19"; height: "119"; }
+ ListElement{ longitude: "12"; latitude: "20"; height: "98"; }
+ ListElement{ longitude: "12"; latitude: "21"; height: "84"; }
+ ListElement{ longitude: "12"; latitude: "22"; height: "87"; }
+ ListElement{ longitude: "12"; latitude: "23"; height: "103"; }
+ ListElement{ longitude: "12"; latitude: "24"; height: "119"; }
+ ListElement{ longitude: "12"; latitude: "25"; height: "117"; }
+ ListElement{ longitude: "12"; latitude: "26"; height: "113"; }
+ ListElement{ longitude: "12"; latitude: "27"; height: "112"; }
+ ListElement{ longitude: "12"; latitude: "28"; height: "113"; }
+ ListElement{ longitude: "12"; latitude: "29"; height: "114"; }
+ ListElement{ longitude: "12"; latitude: "30"; height: "115"; }
+ ListElement{ longitude: "12"; latitude: "31"; height: "118"; }
+ ListElement{ longitude: "12"; latitude: "32"; height: "118"; }
+ ListElement{ longitude: "12"; latitude: "33"; height: "121"; }
+ ListElement{ longitude: "12"; latitude: "34"; height: "124"; }
+ ListElement{ longitude: "12"; latitude: "35"; height: "126"; }
+ ListElement{ longitude: "12"; latitude: "36"; height: "127"; }
+ ListElement{ longitude: "12"; latitude: "37"; height: "127"; }
+ ListElement{ longitude: "12"; latitude: "38"; height: "127"; }
+ ListElement{ longitude: "12"; latitude: "39"; height: "127"; }
+ ListElement{ longitude: "12"; latitude: "40"; height: "126"; }
+ ListElement{ longitude: "12"; latitude: "41"; height: "129"; }
+ ListElement{ longitude: "12"; latitude: "42"; height: "129"; }
+ ListElement{ longitude: "12"; latitude: "43"; height: "133"; }
+ ListElement{ longitude: "12"; latitude: "44"; height: "134"; }
+ ListElement{ longitude: "12"; latitude: "45"; height: "137"; }
+ ListElement{ longitude: "12"; latitude: "46"; height: "136"; }
+ ListElement{ longitude: "12"; latitude: "47"; height: "135"; }
+ ListElement{ longitude: "12"; latitude: "48"; height: "135"; }
+ ListElement{ longitude: "12"; latitude: "49"; height: "135"; }
+ ListElement{ longitude: "12"; latitude: "50"; height: "135"; }
+ ListElement{ longitude: "12"; latitude: "51"; height: "135"; }
+ ListElement{ longitude: "12"; latitude: "52"; height: "133"; }
+ ListElement{ longitude: "12"; latitude: "53"; height: "130"; }
+ ListElement{ longitude: "12"; latitude: "54"; height: "127"; }
+ ListElement{ longitude: "12"; latitude: "55"; height: "122"; }
+ ListElement{ longitude: "12"; latitude: "56"; height: "121"; }
+ ListElement{ longitude: "12"; latitude: "57"; height: "121"; }
+ ListElement{ longitude: "12"; latitude: "58"; height: "121"; }
+ ListElement{ longitude: "12"; latitude: "59"; height: "123"; }
+ ListElement{ longitude: "12"; latitude: "60"; height: "126"; }
+ ListElement{ longitude: "12"; latitude: "61"; height: "128"; }
+ ListElement{ longitude: "12"; latitude: "62"; height: "128"; }
+ ListElement{ longitude: "12"; latitude: "63"; height: "129"; }
+ ListElement{ longitude: "12"; latitude: "64"; height: "117"; }
+ ListElement{ longitude: "12"; latitude: "65"; height: "127"; }
+ ListElement{ longitude: "12"; latitude: "66"; height: "119"; }
+ ListElement{ longitude: "12"; latitude: "67"; height: "118"; }
+ ListElement{ longitude: "12"; latitude: "68"; height: "117"; }
+ ListElement{ longitude: "12"; latitude: "69"; height: "123"; }
+ ListElement{ longitude: "12"; latitude: "70"; height: "128"; }
+ ListElement{ longitude: "12"; latitude: "71"; height: "130"; }
+ ListElement{ longitude: "12"; latitude: "72"; height: "132"; }
+ ListElement{ longitude: "12"; latitude: "73"; height: "119"; }
+ ListElement{ longitude: "12"; latitude: "74"; height: "111"; }
+ ListElement{ longitude: "12"; latitude: "75"; height: "117"; }
+ ListElement{ longitude: "12"; latitude: "76"; height: "113"; }
+ ListElement{ longitude: "12"; latitude: "77"; height: "112"; }
+ ListElement{ longitude: "12"; latitude: "78"; height: "114"; }
+ ListElement{ longitude: "12"; latitude: "79"; height: "117"; }
+ ListElement{ longitude: "12"; latitude: "80"; height: "117"; }
+ ListElement{ longitude: "12"; latitude: "81"; height: "115"; }
+ ListElement{ longitude: "12"; latitude: "82"; height: "110"; }
+ ListElement{ longitude: "12"; latitude: "83"; height: "105"; }
+ ListElement{ longitude: "12"; latitude: "84"; height: "102"; }
+ ListElement{ longitude: "12"; latitude: "85"; height: "101"; }
+ ListElement{ longitude: "12"; latitude: "86"; height: "102"; }
+ ListElement{ longitude: "12"; latitude: "87"; height: "105"; }
+ ListElement{ longitude: "12"; latitude: "88"; height: "108"; }
+ ListElement{ longitude: "12"; latitude: "89"; height: "111"; }
+ ListElement{ longitude: "12"; latitude: "90"; height: "116"; }
+ ListElement{ longitude: "12"; latitude: "91"; height: "121"; }
+ ListElement{ longitude: "12"; latitude: "92"; height: "124"; }
+ ListElement{ longitude: "12"; latitude: "93"; height: "126"; }
+ ListElement{ longitude: "12"; latitude: "94"; height: "126"; }
+ ListElement{ longitude: "12"; latitude: "95"; height: "129"; }
+ ListElement{ longitude: "12"; latitude: "96"; height: "131"; }
+ ListElement{ longitude: "12"; latitude: "97"; height: "131"; }
+ ListElement{ longitude: "12"; latitude: "98"; height: "140"; }
+ ListElement{ longitude: "12"; latitude: "99"; height: "142"; }
+ ListElement{ longitude: "13"; latitude: "0"; height: "108"; }
+ ListElement{ longitude: "13"; latitude: "1"; height: "113"; }
+ ListElement{ longitude: "13"; latitude: "2"; height: "131"; }
+ ListElement{ longitude: "13"; latitude: "3"; height: "136"; }
+ ListElement{ longitude: "13"; latitude: "4"; height: "137"; }
+ ListElement{ longitude: "13"; latitude: "5"; height: "136"; }
+ ListElement{ longitude: "13"; latitude: "6"; height: "130"; }
+ ListElement{ longitude: "13"; latitude: "7"; height: "131"; }
+ ListElement{ longitude: "13"; latitude: "8"; height: "128"; }
+ ListElement{ longitude: "13"; latitude: "9"; height: "129"; }
+ ListElement{ longitude: "13"; latitude: "10"; height: "128"; }
+ ListElement{ longitude: "13"; latitude: "11"; height: "130"; }
+ ListElement{ longitude: "13"; latitude: "12"; height: "132"; }
+ ListElement{ longitude: "13"; latitude: "13"; height: "132"; }
+ ListElement{ longitude: "13"; latitude: "14"; height: "132"; }
+ ListElement{ longitude: "13"; latitude: "15"; height: "129"; }
+ ListElement{ longitude: "13"; latitude: "16"; height: "127"; }
+ ListElement{ longitude: "13"; latitude: "17"; height: "127"; }
+ ListElement{ longitude: "13"; latitude: "18"; height: "124"; }
+ ListElement{ longitude: "13"; latitude: "19"; height: "122"; }
+ ListElement{ longitude: "13"; latitude: "20"; height: "106"; }
+ ListElement{ longitude: "13"; latitude: "21"; height: "95"; }
+ ListElement{ longitude: "13"; latitude: "22"; height: "98"; }
+ ListElement{ longitude: "13"; latitude: "23"; height: "111"; }
+ ListElement{ longitude: "13"; latitude: "24"; height: "120"; }
+ ListElement{ longitude: "13"; latitude: "25"; height: "116"; }
+ ListElement{ longitude: "13"; latitude: "26"; height: "112"; }
+ ListElement{ longitude: "13"; latitude: "27"; height: "111"; }
+ ListElement{ longitude: "13"; latitude: "28"; height: "111"; }
+ ListElement{ longitude: "13"; latitude: "29"; height: "113"; }
+ ListElement{ longitude: "13"; latitude: "30"; height: "116"; }
+ ListElement{ longitude: "13"; latitude: "31"; height: "118"; }
+ ListElement{ longitude: "13"; latitude: "32"; height: "119"; }
+ ListElement{ longitude: "13"; latitude: "33"; height: "118"; }
+ ListElement{ longitude: "13"; latitude: "34"; height: "122"; }
+ ListElement{ longitude: "13"; latitude: "35"; height: "124"; }
+ ListElement{ longitude: "13"; latitude: "36"; height: "126"; }
+ ListElement{ longitude: "13"; latitude: "37"; height: "127"; }
+ ListElement{ longitude: "13"; latitude: "38"; height: "129"; }
+ ListElement{ longitude: "13"; latitude: "39"; height: "127"; }
+ ListElement{ longitude: "13"; latitude: "40"; height: "126"; }
+ ListElement{ longitude: "13"; latitude: "41"; height: "127"; }
+ ListElement{ longitude: "13"; latitude: "42"; height: "130"; }
+ ListElement{ longitude: "13"; latitude: "43"; height: "131"; }
+ ListElement{ longitude: "13"; latitude: "44"; height: "131"; }
+ ListElement{ longitude: "13"; latitude: "45"; height: "133"; }
+ ListElement{ longitude: "13"; latitude: "46"; height: "134"; }
+ ListElement{ longitude: "13"; latitude: "47"; height: "132"; }
+ ListElement{ longitude: "13"; latitude: "48"; height: "133"; }
+ ListElement{ longitude: "13"; latitude: "49"; height: "133"; }
+ ListElement{ longitude: "13"; latitude: "50"; height: "134"; }
+ ListElement{ longitude: "13"; latitude: "51"; height: "136"; }
+ ListElement{ longitude: "13"; latitude: "52"; height: "135"; }
+ ListElement{ longitude: "13"; latitude: "53"; height: "131"; }
+ ListElement{ longitude: "13"; latitude: "54"; height: "127"; }
+ ListElement{ longitude: "13"; latitude: "55"; height: "124"; }
+ ListElement{ longitude: "13"; latitude: "56"; height: "121"; }
+ ListElement{ longitude: "13"; latitude: "57"; height: "120"; }
+ ListElement{ longitude: "13"; latitude: "58"; height: "122"; }
+ ListElement{ longitude: "13"; latitude: "59"; height: "123"; }
+ ListElement{ longitude: "13"; latitude: "60"; height: "125"; }
+ ListElement{ longitude: "13"; latitude: "61"; height: "128"; }
+ ListElement{ longitude: "13"; latitude: "62"; height: "128"; }
+ ListElement{ longitude: "13"; latitude: "63"; height: "126"; }
+ ListElement{ longitude: "13"; latitude: "64"; height: "128"; }
+ ListElement{ longitude: "13"; latitude: "65"; height: "118"; }
+ ListElement{ longitude: "13"; latitude: "66"; height: "121"; }
+ ListElement{ longitude: "13"; latitude: "67"; height: "122"; }
+ ListElement{ longitude: "13"; latitude: "68"; height: "120"; }
+ ListElement{ longitude: "13"; latitude: "69"; height: "121"; }
+ ListElement{ longitude: "13"; latitude: "70"; height: "124"; }
+ ListElement{ longitude: "13"; latitude: "71"; height: "128"; }
+ ListElement{ longitude: "13"; latitude: "72"; height: "130"; }
+ ListElement{ longitude: "13"; latitude: "73"; height: "126"; }
+ ListElement{ longitude: "13"; latitude: "74"; height: "114"; }
+ ListElement{ longitude: "13"; latitude: "75"; height: "116"; }
+ ListElement{ longitude: "13"; latitude: "76"; height: "114"; }
+ ListElement{ longitude: "13"; latitude: "77"; height: "114"; }
+ ListElement{ longitude: "13"; latitude: "78"; height: "117"; }
+ ListElement{ longitude: "13"; latitude: "79"; height: "119"; }
+ ListElement{ longitude: "13"; latitude: "80"; height: "118"; }
+ ListElement{ longitude: "13"; latitude: "81"; height: "119"; }
+ ListElement{ longitude: "13"; latitude: "82"; height: "114"; }
+ ListElement{ longitude: "13"; latitude: "83"; height: "110"; }
+ ListElement{ longitude: "13"; latitude: "84"; height: "103"; }
+ ListElement{ longitude: "13"; latitude: "85"; height: "103"; }
+ ListElement{ longitude: "13"; latitude: "86"; height: "105"; }
+ ListElement{ longitude: "13"; latitude: "87"; height: "104"; }
+ ListElement{ longitude: "13"; latitude: "88"; height: "106"; }
+ ListElement{ longitude: "13"; latitude: "89"; height: "109"; }
+ ListElement{ longitude: "13"; latitude: "90"; height: "116"; }
+ ListElement{ longitude: "13"; latitude: "91"; height: "119"; }
+ ListElement{ longitude: "13"; latitude: "92"; height: "124"; }
+ ListElement{ longitude: "13"; latitude: "93"; height: "127"; }
+ ListElement{ longitude: "13"; latitude: "94"; height: "125"; }
+ ListElement{ longitude: "13"; latitude: "95"; height: "127"; }
+ ListElement{ longitude: "13"; latitude: "96"; height: "129"; }
+ ListElement{ longitude: "13"; latitude: "97"; height: "132"; }
+ ListElement{ longitude: "13"; latitude: "98"; height: "137"; }
+ ListElement{ longitude: "13"; latitude: "99"; height: "140"; }
+ ListElement{ longitude: "14"; latitude: "0"; height: "103"; }
+ ListElement{ longitude: "14"; latitude: "1"; height: "99"; }
+ ListElement{ longitude: "14"; latitude: "2"; height: "120"; }
+ ListElement{ longitude: "14"; latitude: "3"; height: "137"; }
+ ListElement{ longitude: "14"; latitude: "4"; height: "134"; }
+ ListElement{ longitude: "14"; latitude: "5"; height: "131"; }
+ ListElement{ longitude: "14"; latitude: "6"; height: "130"; }
+ ListElement{ longitude: "14"; latitude: "7"; height: "128"; }
+ ListElement{ longitude: "14"; latitude: "8"; height: "125"; }
+ ListElement{ longitude: "14"; latitude: "9"; height: "126"; }
+ ListElement{ longitude: "14"; latitude: "10"; height: "126"; }
+ ListElement{ longitude: "14"; latitude: "11"; height: "127"; }
+ ListElement{ longitude: "14"; latitude: "12"; height: "129"; }
+ ListElement{ longitude: "14"; latitude: "13"; height: "132"; }
+ ListElement{ longitude: "14"; latitude: "14"; height: "132"; }
+ ListElement{ longitude: "14"; latitude: "15"; height: "129"; }
+ ListElement{ longitude: "14"; latitude: "16"; height: "129"; }
+ ListElement{ longitude: "14"; latitude: "17"; height: "127"; }
+ ListElement{ longitude: "14"; latitude: "18"; height: "123"; }
+ ListElement{ longitude: "14"; latitude: "19"; height: "123"; }
+ ListElement{ longitude: "14"; latitude: "20"; height: "116"; }
+ ListElement{ longitude: "14"; latitude: "21"; height: "115"; }
+ ListElement{ longitude: "14"; latitude: "22"; height: "116"; }
+ ListElement{ longitude: "14"; latitude: "23"; height: "123"; }
+ ListElement{ longitude: "14"; latitude: "24"; height: "118"; }
+ ListElement{ longitude: "14"; latitude: "25"; height: "114"; }
+ ListElement{ longitude: "14"; latitude: "26"; height: "108"; }
+ ListElement{ longitude: "14"; latitude: "27"; height: "111"; }
+ ListElement{ longitude: "14"; latitude: "28"; height: "111"; }
+ ListElement{ longitude: "14"; latitude: "29"; height: "114"; }
+ ListElement{ longitude: "14"; latitude: "30"; height: "114"; }
+ ListElement{ longitude: "14"; latitude: "31"; height: "115"; }
+ ListElement{ longitude: "14"; latitude: "32"; height: "118"; }
+ ListElement{ longitude: "14"; latitude: "33"; height: "117"; }
+ ListElement{ longitude: "14"; latitude: "34"; height: "116"; }
+ ListElement{ longitude: "14"; latitude: "35"; height: "119"; }
+ ListElement{ longitude: "14"; latitude: "36"; height: "123"; }
+ ListElement{ longitude: "14"; latitude: "37"; height: "125"; }
+ ListElement{ longitude: "14"; latitude: "38"; height: "125"; }
+ ListElement{ longitude: "14"; latitude: "39"; height: "127"; }
+ ListElement{ longitude: "14"; latitude: "40"; height: "126"; }
+ ListElement{ longitude: "14"; latitude: "41"; height: "128"; }
+ ListElement{ longitude: "14"; latitude: "42"; height: "129"; }
+ ListElement{ longitude: "14"; latitude: "43"; height: "130"; }
+ ListElement{ longitude: "14"; latitude: "44"; height: "129"; }
+ ListElement{ longitude: "14"; latitude: "45"; height: "129"; }
+ ListElement{ longitude: "14"; latitude: "46"; height: "130"; }
+ ListElement{ longitude: "14"; latitude: "47"; height: "131"; }
+ ListElement{ longitude: "14"; latitude: "48"; height: "129"; }
+ ListElement{ longitude: "14"; latitude: "49"; height: "131"; }
+ ListElement{ longitude: "14"; latitude: "50"; height: "130"; }
+ ListElement{ longitude: "14"; latitude: "51"; height: "131"; }
+ ListElement{ longitude: "14"; latitude: "52"; height: "133"; }
+ ListElement{ longitude: "14"; latitude: "53"; height: "132"; }
+ ListElement{ longitude: "14"; latitude: "54"; height: "130"; }
+ ListElement{ longitude: "14"; latitude: "55"; height: "127"; }
+ ListElement{ longitude: "14"; latitude: "56"; height: "122"; }
+ ListElement{ longitude: "14"; latitude: "57"; height: "120"; }
+ ListElement{ longitude: "14"; latitude: "58"; height: "120"; }
+ ListElement{ longitude: "14"; latitude: "59"; height: "118"; }
+ ListElement{ longitude: "14"; latitude: "60"; height: "121"; }
+ ListElement{ longitude: "14"; latitude: "61"; height: "122"; }
+ ListElement{ longitude: "14"; latitude: "62"; height: "122"; }
+ ListElement{ longitude: "14"; latitude: "63"; height: "122"; }
+ ListElement{ longitude: "14"; latitude: "64"; height: "123"; }
+ ListElement{ longitude: "14"; latitude: "65"; height: "123"; }
+ ListElement{ longitude: "14"; latitude: "66"; height: "122"; }
+ ListElement{ longitude: "14"; latitude: "67"; height: "121"; }
+ ListElement{ longitude: "14"; latitude: "68"; height: "117"; }
+ ListElement{ longitude: "14"; latitude: "69"; height: "117"; }
+ ListElement{ longitude: "14"; latitude: "70"; height: "118"; }
+ ListElement{ longitude: "14"; latitude: "71"; height: "122"; }
+ ListElement{ longitude: "14"; latitude: "72"; height: "122"; }
+ ListElement{ longitude: "14"; latitude: "73"; height: "120"; }
+ ListElement{ longitude: "14"; latitude: "74"; height: "117"; }
+ ListElement{ longitude: "14"; latitude: "75"; height: "112"; }
+ ListElement{ longitude: "14"; latitude: "76"; height: "113"; }
+ ListElement{ longitude: "14"; latitude: "77"; height: "111"; }
+ ListElement{ longitude: "14"; latitude: "78"; height: "113"; }
+ ListElement{ longitude: "14"; latitude: "79"; height: "117"; }
+ ListElement{ longitude: "14"; latitude: "80"; height: "121"; }
+ ListElement{ longitude: "14"; latitude: "81"; height: "121"; }
+ ListElement{ longitude: "14"; latitude: "82"; height: "119"; }
+ ListElement{ longitude: "14"; latitude: "83"; height: "112"; }
+ ListElement{ longitude: "14"; latitude: "84"; height: "108"; }
+ ListElement{ longitude: "14"; latitude: "85"; height: "107"; }
+ ListElement{ longitude: "14"; latitude: "86"; height: "104"; }
+ ListElement{ longitude: "14"; latitude: "87"; height: "103"; }
+ ListElement{ longitude: "14"; latitude: "88"; height: "105"; }
+ ListElement{ longitude: "14"; latitude: "89"; height: "108"; }
+ ListElement{ longitude: "14"; latitude: "90"; height: "114"; }
+ ListElement{ longitude: "14"; latitude: "91"; height: "117"; }
+ ListElement{ longitude: "14"; latitude: "92"; height: "108"; }
+ ListElement{ longitude: "14"; latitude: "93"; height: "125"; }
+ ListElement{ longitude: "14"; latitude: "94"; height: "126"; }
+ ListElement{ longitude: "14"; latitude: "95"; height: "126"; }
+ ListElement{ longitude: "14"; latitude: "96"; height: "128"; }
+ ListElement{ longitude: "14"; latitude: "97"; height: "133"; }
+ ListElement{ longitude: "14"; latitude: "98"; height: "137"; }
+ ListElement{ longitude: "14"; latitude: "99"; height: "136"; }
+ ListElement{ longitude: "15"; latitude: "0"; height: "96"; }
+ ListElement{ longitude: "15"; latitude: "1"; height: "98"; }
+ ListElement{ longitude: "15"; latitude: "2"; height: "120"; }
+ ListElement{ longitude: "15"; latitude: "3"; height: "138"; }
+ ListElement{ longitude: "15"; latitude: "4"; height: "128"; }
+ ListElement{ longitude: "15"; latitude: "5"; height: "131"; }
+ ListElement{ longitude: "15"; latitude: "6"; height: "132"; }
+ ListElement{ longitude: "15"; latitude: "7"; height: "128"; }
+ ListElement{ longitude: "15"; latitude: "8"; height: "128"; }
+ ListElement{ longitude: "15"; latitude: "9"; height: "125"; }
+ ListElement{ longitude: "15"; latitude: "10"; height: "125"; }
+ ListElement{ longitude: "15"; latitude: "11"; height: "126"; }
+ ListElement{ longitude: "15"; latitude: "12"; height: "129"; }
+ ListElement{ longitude: "15"; latitude: "13"; height: "131"; }
+ ListElement{ longitude: "15"; latitude: "14"; height: "133"; }
+ ListElement{ longitude: "15"; latitude: "15"; height: "132"; }
+ ListElement{ longitude: "15"; latitude: "16"; height: "129"; }
+ ListElement{ longitude: "15"; latitude: "17"; height: "127"; }
+ ListElement{ longitude: "15"; latitude: "18"; height: "124"; }
+ ListElement{ longitude: "15"; latitude: "19"; height: "122"; }
+ ListElement{ longitude: "15"; latitude: "20"; height: "120"; }
+ ListElement{ longitude: "15"; latitude: "21"; height: "121"; }
+ ListElement{ longitude: "15"; latitude: "22"; height: "119"; }
+ ListElement{ longitude: "15"; latitude: "23"; height: "122"; }
+ ListElement{ longitude: "15"; latitude: "24"; height: "117"; }
+ ListElement{ longitude: "15"; latitude: "25"; height: "116"; }
+ ListElement{ longitude: "15"; latitude: "26"; height: "112"; }
+ ListElement{ longitude: "15"; latitude: "27"; height: "111"; }
+ ListElement{ longitude: "15"; latitude: "28"; height: "112"; }
+ ListElement{ longitude: "15"; latitude: "29"; height: "113"; }
+ ListElement{ longitude: "15"; latitude: "30"; height: "115"; }
+ ListElement{ longitude: "15"; latitude: "31"; height: "118"; }
+ ListElement{ longitude: "15"; latitude: "32"; height: "118"; }
+ ListElement{ longitude: "15"; latitude: "33"; height: "116"; }
+ ListElement{ longitude: "15"; latitude: "34"; height: "116"; }
+ ListElement{ longitude: "15"; latitude: "35"; height: "117"; }
+ ListElement{ longitude: "15"; latitude: "36"; height: "117"; }
+ ListElement{ longitude: "15"; latitude: "37"; height: "123"; }
+ ListElement{ longitude: "15"; latitude: "38"; height: "125"; }
+ ListElement{ longitude: "15"; latitude: "39"; height: "128"; }
+ ListElement{ longitude: "15"; latitude: "40"; height: "127"; }
+ ListElement{ longitude: "15"; latitude: "41"; height: "128"; }
+ ListElement{ longitude: "15"; latitude: "42"; height: "127"; }
+ ListElement{ longitude: "15"; latitude: "43"; height: "128"; }
+ ListElement{ longitude: "15"; latitude: "44"; height: "130"; }
+ ListElement{ longitude: "15"; latitude: "45"; height: "130"; }
+ ListElement{ longitude: "15"; latitude: "46"; height: "130"; }
+ ListElement{ longitude: "15"; latitude: "47"; height: "128"; }
+ ListElement{ longitude: "15"; latitude: "48"; height: "127"; }
+ ListElement{ longitude: "15"; latitude: "49"; height: "127"; }
+ ListElement{ longitude: "15"; latitude: "50"; height: "129"; }
+ ListElement{ longitude: "15"; latitude: "51"; height: "130"; }
+ ListElement{ longitude: "15"; latitude: "52"; height: "131"; }
+ ListElement{ longitude: "15"; latitude: "53"; height: "132"; }
+ ListElement{ longitude: "15"; latitude: "54"; height: "129"; }
+ ListElement{ longitude: "15"; latitude: "55"; height: "129"; }
+ ListElement{ longitude: "15"; latitude: "56"; height: "124"; }
+ ListElement{ longitude: "15"; latitude: "57"; height: "121"; }
+ ListElement{ longitude: "15"; latitude: "58"; height: "122"; }
+ ListElement{ longitude: "15"; latitude: "59"; height: "119"; }
+ ListElement{ longitude: "15"; latitude: "60"; height: "119"; }
+ ListElement{ longitude: "15"; latitude: "61"; height: "121"; }
+ ListElement{ longitude: "15"; latitude: "62"; height: "120"; }
+ ListElement{ longitude: "15"; latitude: "63"; height: "119"; }
+ ListElement{ longitude: "15"; latitude: "64"; height: "119"; }
+ ListElement{ longitude: "15"; latitude: "65"; height: "119"; }
+ ListElement{ longitude: "15"; latitude: "66"; height: "112"; }
+ ListElement{ longitude: "15"; latitude: "67"; height: "117"; }
+ ListElement{ longitude: "15"; latitude: "68"; height: "115"; }
+ ListElement{ longitude: "15"; latitude: "69"; height: "114"; }
+ ListElement{ longitude: "15"; latitude: "70"; height: "116"; }
+ ListElement{ longitude: "15"; latitude: "71"; height: "117"; }
+ ListElement{ longitude: "15"; latitude: "72"; height: "118"; }
+ ListElement{ longitude: "15"; latitude: "73"; height: "115"; }
+ ListElement{ longitude: "15"; latitude: "74"; height: "113"; }
+ ListElement{ longitude: "15"; latitude: "75"; height: "111"; }
+ ListElement{ longitude: "15"; latitude: "76"; height: "110"; }
+ ListElement{ longitude: "15"; latitude: "77"; height: "111"; }
+ ListElement{ longitude: "15"; latitude: "78"; height: "113"; }
+ ListElement{ longitude: "15"; latitude: "79"; height: "113"; }
+ ListElement{ longitude: "15"; latitude: "80"; height: "121"; }
+ ListElement{ longitude: "15"; latitude: "81"; height: "123"; }
+ ListElement{ longitude: "15"; latitude: "82"; height: "120"; }
+ ListElement{ longitude: "15"; latitude: "83"; height: "121"; }
+ ListElement{ longitude: "15"; latitude: "84"; height: "112"; }
+ ListElement{ longitude: "15"; latitude: "85"; height: "107"; }
+ ListElement{ longitude: "15"; latitude: "86"; height: "105"; }
+ ListElement{ longitude: "15"; latitude: "87"; height: "104"; }
+ ListElement{ longitude: "15"; latitude: "88"; height: "101"; }
+ ListElement{ longitude: "15"; latitude: "89"; height: "108"; }
+ ListElement{ longitude: "15"; latitude: "90"; height: "112"; }
+ ListElement{ longitude: "15"; latitude: "91"; height: "119"; }
+ ListElement{ longitude: "15"; latitude: "92"; height: "120"; }
+ ListElement{ longitude: "15"; latitude: "93"; height: "118"; }
+ ListElement{ longitude: "15"; latitude: "94"; height: "123"; }
+ ListElement{ longitude: "15"; latitude: "95"; height: "126"; }
+ ListElement{ longitude: "15"; latitude: "96"; height: "129"; }
+ ListElement{ longitude: "15"; latitude: "97"; height: "132"; }
+ ListElement{ longitude: "15"; latitude: "98"; height: "133"; }
+ ListElement{ longitude: "15"; latitude: "99"; height: "132"; }
+ ListElement{ longitude: "16"; latitude: "0"; height: "99"; }
+ ListElement{ longitude: "16"; latitude: "1"; height: "105"; }
+ ListElement{ longitude: "16"; latitude: "2"; height: "120"; }
+ ListElement{ longitude: "16"; latitude: "3"; height: "135"; }
+ ListElement{ longitude: "16"; latitude: "4"; height: "139"; }
+ ListElement{ longitude: "16"; latitude: "5"; height: "138"; }
+ ListElement{ longitude: "16"; latitude: "6"; height: "133"; }
+ ListElement{ longitude: "16"; latitude: "7"; height: "129"; }
+ ListElement{ longitude: "16"; latitude: "8"; height: "128"; }
+ ListElement{ longitude: "16"; latitude: "9"; height: "125"; }
+ ListElement{ longitude: "16"; latitude: "10"; height: "126"; }
+ ListElement{ longitude: "16"; latitude: "11"; height: "123"; }
+ ListElement{ longitude: "16"; latitude: "12"; height: "126"; }
+ ListElement{ longitude: "16"; latitude: "13"; height: "130"; }
+ ListElement{ longitude: "16"; latitude: "14"; height: "130"; }
+ ListElement{ longitude: "16"; latitude: "15"; height: "129"; }
+ ListElement{ longitude: "16"; latitude: "16"; height: "127"; }
+ ListElement{ longitude: "16"; latitude: "17"; height: "125"; }
+ ListElement{ longitude: "16"; latitude: "18"; height: "123"; }
+ ListElement{ longitude: "16"; latitude: "19"; height: "123"; }
+ ListElement{ longitude: "16"; latitude: "20"; height: "120"; }
+ ListElement{ longitude: "16"; latitude: "21"; height: "120"; }
+ ListElement{ longitude: "16"; latitude: "22"; height: "120"; }
+ ListElement{ longitude: "16"; latitude: "23"; height: "120"; }
+ ListElement{ longitude: "16"; latitude: "24"; height: "119"; }
+ ListElement{ longitude: "16"; latitude: "25"; height: "117"; }
+ ListElement{ longitude: "16"; latitude: "26"; height: "112"; }
+ ListElement{ longitude: "16"; latitude: "27"; height: "113"; }
+ ListElement{ longitude: "16"; latitude: "28"; height: "114"; }
+ ListElement{ longitude: "16"; latitude: "29"; height: "116"; }
+ ListElement{ longitude: "16"; latitude: "30"; height: "117"; }
+ ListElement{ longitude: "16"; latitude: "31"; height: "117"; }
+ ListElement{ longitude: "16"; latitude: "32"; height: "117"; }
+ ListElement{ longitude: "16"; latitude: "33"; height: "116"; }
+ ListElement{ longitude: "16"; latitude: "34"; height: "114"; }
+ ListElement{ longitude: "16"; latitude: "35"; height: "116"; }
+ ListElement{ longitude: "16"; latitude: "36"; height: "118"; }
+ ListElement{ longitude: "16"; latitude: "37"; height: "120"; }
+ ListElement{ longitude: "16"; latitude: "38"; height: "120"; }
+ ListElement{ longitude: "16"; latitude: "39"; height: "124"; }
+ ListElement{ longitude: "16"; latitude: "40"; height: "127"; }
+ ListElement{ longitude: "16"; latitude: "41"; height: "126"; }
+ ListElement{ longitude: "16"; latitude: "42"; height: "127"; }
+ ListElement{ longitude: "16"; latitude: "43"; height: "128"; }
+ ListElement{ longitude: "16"; latitude: "44"; height: "130"; }
+ ListElement{ longitude: "16"; latitude: "45"; height: "130"; }
+ ListElement{ longitude: "16"; latitude: "46"; height: "129"; }
+ ListElement{ longitude: "16"; latitude: "47"; height: "128"; }
+ ListElement{ longitude: "16"; latitude: "48"; height: "125"; }
+ ListElement{ longitude: "16"; latitude: "49"; height: "124"; }
+ ListElement{ longitude: "16"; latitude: "50"; height: "124"; }
+ ListElement{ longitude: "16"; latitude: "51"; height: "126"; }
+ ListElement{ longitude: "16"; latitude: "52"; height: "130"; }
+ ListElement{ longitude: "16"; latitude: "53"; height: "131"; }
+ ListElement{ longitude: "16"; latitude: "54"; height: "133"; }
+ ListElement{ longitude: "16"; latitude: "55"; height: "130"; }
+ ListElement{ longitude: "16"; latitude: "56"; height: "127"; }
+ ListElement{ longitude: "16"; latitude: "57"; height: "123"; }
+ ListElement{ longitude: "16"; latitude: "58"; height: "121"; }
+ ListElement{ longitude: "16"; latitude: "59"; height: "119"; }
+ ListElement{ longitude: "16"; latitude: "60"; height: "117"; }
+ ListElement{ longitude: "16"; latitude: "61"; height: "120"; }
+ ListElement{ longitude: "16"; latitude: "62"; height: "119"; }
+ ListElement{ longitude: "16"; latitude: "63"; height: "121"; }
+ ListElement{ longitude: "16"; latitude: "64"; height: "119"; }
+ ListElement{ longitude: "16"; latitude: "65"; height: "117"; }
+ ListElement{ longitude: "16"; latitude: "66"; height: "114"; }
+ ListElement{ longitude: "16"; latitude: "67"; height: "117"; }
+ ListElement{ longitude: "16"; latitude: "68"; height: "116"; }
+ ListElement{ longitude: "16"; latitude: "69"; height: "111"; }
+ ListElement{ longitude: "16"; latitude: "70"; height: "111"; }
+ ListElement{ longitude: "16"; latitude: "71"; height: "112"; }
+ ListElement{ longitude: "16"; latitude: "72"; height: "114"; }
+ ListElement{ longitude: "16"; latitude: "73"; height: "112"; }
+ ListElement{ longitude: "16"; latitude: "74"; height: "112"; }
+ ListElement{ longitude: "16"; latitude: "75"; height: "109"; }
+ ListElement{ longitude: "16"; latitude: "76"; height: "109"; }
+ ListElement{ longitude: "16"; latitude: "77"; height: "110"; }
+ ListElement{ longitude: "16"; latitude: "78"; height: "98"; }
+ ListElement{ longitude: "16"; latitude: "79"; height: "91"; }
+ ListElement{ longitude: "16"; latitude: "80"; height: "119"; }
+ ListElement{ longitude: "16"; latitude: "81"; height: "122"; }
+ ListElement{ longitude: "16"; latitude: "82"; height: "109"; }
+ ListElement{ longitude: "16"; latitude: "83"; height: "112"; }
+ ListElement{ longitude: "16"; latitude: "84"; height: "118"; }
+ ListElement{ longitude: "16"; latitude: "85"; height: "109"; }
+ ListElement{ longitude: "16"; latitude: "86"; height: "105"; }
+ ListElement{ longitude: "16"; latitude: "87"; height: "105"; }
+ ListElement{ longitude: "16"; latitude: "88"; height: "90"; }
+ ListElement{ longitude: "16"; latitude: "89"; height: "106"; }
+ ListElement{ longitude: "16"; latitude: "90"; height: "110"; }
+ ListElement{ longitude: "16"; latitude: "91"; height: "113"; }
+ ListElement{ longitude: "16"; latitude: "92"; height: "118"; }
+ ListElement{ longitude: "16"; latitude: "93"; height: "116"; }
+ ListElement{ longitude: "16"; latitude: "94"; height: "119"; }
+ ListElement{ longitude: "16"; latitude: "95"; height: "124"; }
+ ListElement{ longitude: "16"; latitude: "96"; height: "127"; }
+ ListElement{ longitude: "16"; latitude: "97"; height: "130"; }
+ ListElement{ longitude: "16"; latitude: "98"; height: "132"; }
+ ListElement{ longitude: "16"; latitude: "99"; height: "128"; }
+ ListElement{ longitude: "17"; latitude: "0"; height: "110"; }
+ ListElement{ longitude: "17"; latitude: "1"; height: "117"; }
+ ListElement{ longitude: "17"; latitude: "2"; height: "130"; }
+ ListElement{ longitude: "17"; latitude: "3"; height: "136"; }
+ ListElement{ longitude: "17"; latitude: "4"; height: "138"; }
+ ListElement{ longitude: "17"; latitude: "5"; height: "132"; }
+ ListElement{ longitude: "17"; latitude: "6"; height: "134"; }
+ ListElement{ longitude: "17"; latitude: "7"; height: "129"; }
+ ListElement{ longitude: "17"; latitude: "8"; height: "127"; }
+ ListElement{ longitude: "17"; latitude: "9"; height: "125"; }
+ ListElement{ longitude: "17"; latitude: "10"; height: "126"; }
+ ListElement{ longitude: "17"; latitude: "11"; height: "126"; }
+ ListElement{ longitude: "17"; latitude: "12"; height: "127"; }
+ ListElement{ longitude: "17"; latitude: "13"; height: "129"; }
+ ListElement{ longitude: "17"; latitude: "14"; height: "128"; }
+ ListElement{ longitude: "17"; latitude: "15"; height: "125"; }
+ ListElement{ longitude: "17"; latitude: "16"; height: "124"; }
+ ListElement{ longitude: "17"; latitude: "17"; height: "117"; }
+ ListElement{ longitude: "17"; latitude: "18"; height: "118"; }
+ ListElement{ longitude: "17"; latitude: "19"; height: "120"; }
+ ListElement{ longitude: "17"; latitude: "20"; height: "116"; }
+ ListElement{ longitude: "17"; latitude: "21"; height: "117"; }
+ ListElement{ longitude: "17"; latitude: "22"; height: "117"; }
+ ListElement{ longitude: "17"; latitude: "23"; height: "117"; }
+ ListElement{ longitude: "17"; latitude: "24"; height: "119"; }
+ ListElement{ longitude: "17"; latitude: "25"; height: "118"; }
+ ListElement{ longitude: "17"; latitude: "26"; height: "115"; }
+ ListElement{ longitude: "17"; latitude: "27"; height: "117"; }
+ ListElement{ longitude: "17"; latitude: "28"; height: "119"; }
+ ListElement{ longitude: "17"; latitude: "29"; height: "122"; }
+ ListElement{ longitude: "17"; latitude: "30"; height: "121"; }
+ ListElement{ longitude: "17"; latitude: "31"; height: "121"; }
+ ListElement{ longitude: "17"; latitude: "32"; height: "119"; }
+ ListElement{ longitude: "17"; latitude: "33"; height: "118"; }
+ ListElement{ longitude: "17"; latitude: "34"; height: "115"; }
+ ListElement{ longitude: "17"; latitude: "35"; height: "117"; }
+ ListElement{ longitude: "17"; latitude: "36"; height: "117"; }
+ ListElement{ longitude: "17"; latitude: "37"; height: "122"; }
+ ListElement{ longitude: "17"; latitude: "38"; height: "122"; }
+ ListElement{ longitude: "17"; latitude: "39"; height: "126"; }
+ ListElement{ longitude: "17"; latitude: "40"; height: "128"; }
+ ListElement{ longitude: "17"; latitude: "41"; height: "127"; }
+ ListElement{ longitude: "17"; latitude: "42"; height: "129"; }
+ ListElement{ longitude: "17"; latitude: "43"; height: "128"; }
+ ListElement{ longitude: "17"; latitude: "44"; height: "130"; }
+ ListElement{ longitude: "17"; latitude: "45"; height: "130"; }
+ ListElement{ longitude: "17"; latitude: "46"; height: "129"; }
+ ListElement{ longitude: "17"; latitude: "47"; height: "125"; }
+ ListElement{ longitude: "17"; latitude: "48"; height: "123"; }
+ ListElement{ longitude: "17"; latitude: "49"; height: "120"; }
+ ListElement{ longitude: "17"; latitude: "50"; height: "122"; }
+ ListElement{ longitude: "17"; latitude: "51"; height: "124"; }
+ ListElement{ longitude: "17"; latitude: "52"; height: "128"; }
+ ListElement{ longitude: "17"; latitude: "53"; height: "130"; }
+ ListElement{ longitude: "17"; latitude: "54"; height: "134"; }
+ ListElement{ longitude: "17"; latitude: "55"; height: "131"; }
+ ListElement{ longitude: "17"; latitude: "56"; height: "129"; }
+ ListElement{ longitude: "17"; latitude: "57"; height: "126"; }
+ ListElement{ longitude: "17"; latitude: "58"; height: "122"; }
+ ListElement{ longitude: "17"; latitude: "59"; height: "122"; }
+ ListElement{ longitude: "17"; latitude: "60"; height: "121"; }
+ ListElement{ longitude: "17"; latitude: "61"; height: "118"; }
+ ListElement{ longitude: "17"; latitude: "62"; height: "107"; }
+ ListElement{ longitude: "17"; latitude: "63"; height: "118"; }
+ ListElement{ longitude: "17"; latitude: "64"; height: "113"; }
+ ListElement{ longitude: "17"; latitude: "65"; height: "117"; }
+ ListElement{ longitude: "17"; latitude: "66"; height: "112"; }
+ ListElement{ longitude: "17"; latitude: "67"; height: "111"; }
+ ListElement{ longitude: "17"; latitude: "68"; height: "110"; }
+ ListElement{ longitude: "17"; latitude: "69"; height: "109"; }
+ ListElement{ longitude: "17"; latitude: "70"; height: "109"; }
+ ListElement{ longitude: "17"; latitude: "71"; height: "110"; }
+ ListElement{ longitude: "17"; latitude: "72"; height: "110"; }
+ ListElement{ longitude: "17"; latitude: "73"; height: "110"; }
+ ListElement{ longitude: "17"; latitude: "74"; height: "109"; }
+ ListElement{ longitude: "17"; latitude: "75"; height: "109"; }
+ ListElement{ longitude: "17"; latitude: "76"; height: "110"; }
+ ListElement{ longitude: "17"; latitude: "77"; height: "111"; }
+ ListElement{ longitude: "17"; latitude: "78"; height: "106"; }
+ ListElement{ longitude: "17"; latitude: "79"; height: "101"; }
+ ListElement{ longitude: "17"; latitude: "80"; height: "115"; }
+ ListElement{ longitude: "17"; latitude: "81"; height: "119"; }
+ ListElement{ longitude: "17"; latitude: "82"; height: "108"; }
+ ListElement{ longitude: "17"; latitude: "83"; height: "116"; }
+ ListElement{ longitude: "17"; latitude: "84"; height: "119"; }
+ ListElement{ longitude: "17"; latitude: "85"; height: "112"; }
+ ListElement{ longitude: "17"; latitude: "86"; height: "108"; }
+ ListElement{ longitude: "17"; latitude: "87"; height: "105"; }
+ ListElement{ longitude: "17"; latitude: "88"; height: "104"; }
+ ListElement{ longitude: "17"; latitude: "89"; height: "105"; }
+ ListElement{ longitude: "17"; latitude: "90"; height: "106"; }
+ ListElement{ longitude: "17"; latitude: "91"; height: "110"; }
+ ListElement{ longitude: "17"; latitude: "92"; height: "111"; }
+ ListElement{ longitude: "17"; latitude: "93"; height: "113"; }
+ ListElement{ longitude: "17"; latitude: "94"; height: "116"; }
+ ListElement{ longitude: "17"; latitude: "95"; height: "121"; }
+ ListElement{ longitude: "17"; latitude: "96"; height: "125"; }
+ ListElement{ longitude: "17"; latitude: "97"; height: "128"; }
+ ListElement{ longitude: "17"; latitude: "98"; height: "131"; }
+ ListElement{ longitude: "17"; latitude: "99"; height: "124"; }
+ ListElement{ longitude: "18"; latitude: "0"; height: "118"; }
+ ListElement{ longitude: "18"; latitude: "1"; height: "124"; }
+ ListElement{ longitude: "18"; latitude: "2"; height: "131"; }
+ ListElement{ longitude: "18"; latitude: "3"; height: "133"; }
+ ListElement{ longitude: "18"; latitude: "4"; height: "135"; }
+ ListElement{ longitude: "18"; latitude: "5"; height: "124"; }
+ ListElement{ longitude: "18"; latitude: "6"; height: "133"; }
+ ListElement{ longitude: "18"; latitude: "7"; height: "130"; }
+ ListElement{ longitude: "18"; latitude: "8"; height: "128"; }
+ ListElement{ longitude: "18"; latitude: "9"; height: "127"; }
+ ListElement{ longitude: "18"; latitude: "10"; height: "126"; }
+ ListElement{ longitude: "18"; latitude: "11"; height: "125"; }
+ ListElement{ longitude: "18"; latitude: "12"; height: "125"; }
+ ListElement{ longitude: "18"; latitude: "13"; height: "122"; }
+ ListElement{ longitude: "18"; latitude: "14"; height: "120"; }
+ ListElement{ longitude: "18"; latitude: "15"; height: "118"; }
+ ListElement{ longitude: "18"; latitude: "16"; height: "112"; }
+ ListElement{ longitude: "18"; latitude: "17"; height: "111"; }
+ ListElement{ longitude: "18"; latitude: "18"; height: "116"; }
+ ListElement{ longitude: "18"; latitude: "19"; height: "119"; }
+ ListElement{ longitude: "18"; latitude: "20"; height: "119"; }
+ ListElement{ longitude: "18"; latitude: "21"; height: "117"; }
+ ListElement{ longitude: "18"; latitude: "22"; height: "118"; }
+ ListElement{ longitude: "18"; latitude: "23"; height: "118"; }
+ ListElement{ longitude: "18"; latitude: "24"; height: "118"; }
+ ListElement{ longitude: "18"; latitude: "25"; height: "116"; }
+ ListElement{ longitude: "18"; latitude: "26"; height: "116"; }
+ ListElement{ longitude: "18"; latitude: "27"; height: "118"; }
+ ListElement{ longitude: "18"; latitude: "28"; height: "120"; }
+ ListElement{ longitude: "18"; latitude: "29"; height: "122"; }
+ ListElement{ longitude: "18"; latitude: "30"; height: "125"; }
+ ListElement{ longitude: "18"; latitude: "31"; height: "127"; }
+ ListElement{ longitude: "18"; latitude: "32"; height: "123"; }
+ ListElement{ longitude: "18"; latitude: "33"; height: "123"; }
+ ListElement{ longitude: "18"; latitude: "34"; height: "122"; }
+ ListElement{ longitude: "18"; latitude: "35"; height: "120"; }
+ ListElement{ longitude: "18"; latitude: "36"; height: "121"; }
+ ListElement{ longitude: "18"; latitude: "37"; height: "124"; }
+ ListElement{ longitude: "18"; latitude: "38"; height: "124"; }
+ ListElement{ longitude: "18"; latitude: "39"; height: "128"; }
+ ListElement{ longitude: "18"; latitude: "40"; height: "129"; }
+ ListElement{ longitude: "18"; latitude: "41"; height: "129"; }
+ ListElement{ longitude: "18"; latitude: "42"; height: "129"; }
+ ListElement{ longitude: "18"; latitude: "43"; height: "128"; }
+ ListElement{ longitude: "18"; latitude: "44"; height: "128"; }
+ ListElement{ longitude: "18"; latitude: "45"; height: "129"; }
+ ListElement{ longitude: "18"; latitude: "46"; height: "128"; }
+ ListElement{ longitude: "18"; latitude: "47"; height: "126"; }
+ ListElement{ longitude: "18"; latitude: "48"; height: "124"; }
+ ListElement{ longitude: "18"; latitude: "49"; height: "121"; }
+ ListElement{ longitude: "18"; latitude: "50"; height: "119"; }
+ ListElement{ longitude: "18"; latitude: "51"; height: "122"; }
+ ListElement{ longitude: "18"; latitude: "52"; height: "126"; }
+ ListElement{ longitude: "18"; latitude: "53"; height: "129"; }
+ ListElement{ longitude: "18"; latitude: "54"; height: "131"; }
+ ListElement{ longitude: "18"; latitude: "55"; height: "131"; }
+ ListElement{ longitude: "18"; latitude: "56"; height: "130"; }
+ ListElement{ longitude: "18"; latitude: "57"; height: "127"; }
+ ListElement{ longitude: "18"; latitude: "58"; height: "123"; }
+ ListElement{ longitude: "18"; latitude: "59"; height: "122"; }
+ ListElement{ longitude: "18"; latitude: "60"; height: "122"; }
+ ListElement{ longitude: "18"; latitude: "61"; height: "124"; }
+ ListElement{ longitude: "18"; latitude: "62"; height: "119"; }
+ ListElement{ longitude: "18"; latitude: "63"; height: "119"; }
+ ListElement{ longitude: "18"; latitude: "64"; height: "111"; }
+ ListElement{ longitude: "18"; latitude: "65"; height: "111"; }
+ ListElement{ longitude: "18"; latitude: "66"; height: "114"; }
+ ListElement{ longitude: "18"; latitude: "67"; height: "107"; }
+ ListElement{ longitude: "18"; latitude: "68"; height: "108"; }
+ ListElement{ longitude: "18"; latitude: "69"; height: "109"; }
+ ListElement{ longitude: "18"; latitude: "70"; height: "108"; }
+ ListElement{ longitude: "18"; latitude: "71"; height: "109"; }
+ ListElement{ longitude: "18"; latitude: "72"; height: "111"; }
+ ListElement{ longitude: "18"; latitude: "73"; height: "110"; }
+ ListElement{ longitude: "18"; latitude: "74"; height: "111"; }
+ ListElement{ longitude: "18"; latitude: "75"; height: "109"; }
+ ListElement{ longitude: "18"; latitude: "76"; height: "109"; }
+ ListElement{ longitude: "18"; latitude: "77"; height: "110"; }
+ ListElement{ longitude: "18"; latitude: "78"; height: "110"; }
+ ListElement{ longitude: "18"; latitude: "79"; height: "91"; }
+ ListElement{ longitude: "18"; latitude: "80"; height: "106"; }
+ ListElement{ longitude: "18"; latitude: "81"; height: "115"; }
+ ListElement{ longitude: "18"; latitude: "82"; height: "120"; }
+ ListElement{ longitude: "18"; latitude: "83"; height: "123"; }
+ ListElement{ longitude: "18"; latitude: "84"; height: "117"; }
+ ListElement{ longitude: "18"; latitude: "85"; height: "110"; }
+ ListElement{ longitude: "18"; latitude: "86"; height: "104"; }
+ ListElement{ longitude: "18"; latitude: "87"; height: "101"; }
+ ListElement{ longitude: "18"; latitude: "88"; height: "102"; }
+ ListElement{ longitude: "18"; latitude: "89"; height: "103"; }
+ ListElement{ longitude: "18"; latitude: "90"; height: "104"; }
+ ListElement{ longitude: "18"; latitude: "91"; height: "107"; }
+ ListElement{ longitude: "18"; latitude: "92"; height: "109"; }
+ ListElement{ longitude: "18"; latitude: "93"; height: "109"; }
+ ListElement{ longitude: "18"; latitude: "94"; height: "113"; }
+ ListElement{ longitude: "18"; latitude: "95"; height: "119"; }
+ ListElement{ longitude: "18"; latitude: "96"; height: "122"; }
+ ListElement{ longitude: "18"; latitude: "97"; height: "123"; }
+ ListElement{ longitude: "18"; latitude: "98"; height: "130"; }
+ ListElement{ longitude: "18"; latitude: "99"; height: "118"; }
+ ListElement{ longitude: "19"; latitude: "0"; height: "118"; }
+ ListElement{ longitude: "19"; latitude: "1"; height: "120"; }
+ ListElement{ longitude: "19"; latitude: "2"; height: "125"; }
+ ListElement{ longitude: "19"; latitude: "3"; height: "128"; }
+ ListElement{ longitude: "19"; latitude: "4"; height: "134"; }
+ ListElement{ longitude: "19"; latitude: "5"; height: "134"; }
+ ListElement{ longitude: "19"; latitude: "6"; height: "131"; }
+ ListElement{ longitude: "19"; latitude: "7"; height: "128"; }
+ ListElement{ longitude: "19"; latitude: "8"; height: "125"; }
+ ListElement{ longitude: "19"; latitude: "9"; height: "124"; }
+ ListElement{ longitude: "19"; latitude: "10"; height: "123"; }
+ ListElement{ longitude: "19"; latitude: "11"; height: "120"; }
+ ListElement{ longitude: "19"; latitude: "12"; height: "121"; }
+ ListElement{ longitude: "19"; latitude: "13"; height: "118"; }
+ ListElement{ longitude: "19"; latitude: "14"; height: "118"; }
+ ListElement{ longitude: "19"; latitude: "15"; height: "113"; }
+ ListElement{ longitude: "19"; latitude: "16"; height: "111"; }
+ ListElement{ longitude: "19"; latitude: "17"; height: "113"; }
+ ListElement{ longitude: "19"; latitude: "18"; height: "115"; }
+ ListElement{ longitude: "19"; latitude: "19"; height: "119"; }
+ ListElement{ longitude: "19"; latitude: "20"; height: "120"; }
+ ListElement{ longitude: "19"; latitude: "21"; height: "119"; }
+ ListElement{ longitude: "19"; latitude: "22"; height: "117"; }
+ ListElement{ longitude: "19"; latitude: "23"; height: "116"; }
+ ListElement{ longitude: "19"; latitude: "24"; height: "116"; }
+ ListElement{ longitude: "19"; latitude: "25"; height: "116"; }
+ ListElement{ longitude: "19"; latitude: "26"; height: "116"; }
+ ListElement{ longitude: "19"; latitude: "27"; height: "117"; }
+ ListElement{ longitude: "19"; latitude: "28"; height: "118"; }
+ ListElement{ longitude: "19"; latitude: "29"; height: "121"; }
+ ListElement{ longitude: "19"; latitude: "30"; height: "121"; }
+ ListElement{ longitude: "19"; latitude: "31"; height: "124"; }
+ ListElement{ longitude: "19"; latitude: "32"; height: "125"; }
+ ListElement{ longitude: "19"; latitude: "33"; height: "125"; }
+ ListElement{ longitude: "19"; latitude: "34"; height: "124"; }
+ ListElement{ longitude: "19"; latitude: "35"; height: "124"; }
+ ListElement{ longitude: "19"; latitude: "36"; height: "125"; }
+ ListElement{ longitude: "19"; latitude: "37"; height: "128"; }
+ ListElement{ longitude: "19"; latitude: "38"; height: "125"; }
+ ListElement{ longitude: "19"; latitude: "39"; height: "130"; }
+ ListElement{ longitude: "19"; latitude: "40"; height: "129"; }
+ ListElement{ longitude: "19"; latitude: "41"; height: "129"; }
+ ListElement{ longitude: "19"; latitude: "42"; height: "129"; }
+ ListElement{ longitude: "19"; latitude: "43"; height: "129"; }
+ ListElement{ longitude: "19"; latitude: "44"; height: "129"; }
+ ListElement{ longitude: "19"; latitude: "45"; height: "128"; }
+ ListElement{ longitude: "19"; latitude: "46"; height: "127"; }
+ ListElement{ longitude: "19"; latitude: "47"; height: "124"; }
+ ListElement{ longitude: "19"; latitude: "48"; height: "122"; }
+ ListElement{ longitude: "19"; latitude: "49"; height: "121"; }
+ ListElement{ longitude: "19"; latitude: "50"; height: "120"; }
+ ListElement{ longitude: "19"; latitude: "51"; height: "121"; }
+ ListElement{ longitude: "19"; latitude: "52"; height: "123"; }
+ ListElement{ longitude: "19"; latitude: "53"; height: "127"; }
+ ListElement{ longitude: "19"; latitude: "54"; height: "129"; }
+ ListElement{ longitude: "19"; latitude: "55"; height: "131"; }
+ ListElement{ longitude: "19"; latitude: "56"; height: "128"; }
+ ListElement{ longitude: "19"; latitude: "57"; height: "122"; }
+ ListElement{ longitude: "19"; latitude: "58"; height: "118"; }
+ ListElement{ longitude: "19"; latitude: "59"; height: "121"; }
+ ListElement{ longitude: "19"; latitude: "60"; height: "122"; }
+ ListElement{ longitude: "19"; latitude: "61"; height: "120"; }
+ ListElement{ longitude: "19"; latitude: "62"; height: "113"; }
+ ListElement{ longitude: "19"; latitude: "63"; height: "119"; }
+ ListElement{ longitude: "19"; latitude: "64"; height: "108"; }
+ ListElement{ longitude: "19"; latitude: "65"; height: "105"; }
+ ListElement{ longitude: "19"; latitude: "66"; height: "109"; }
+ ListElement{ longitude: "19"; latitude: "67"; height: "108"; }
+ ListElement{ longitude: "19"; latitude: "68"; height: "105"; }
+ ListElement{ longitude: "19"; latitude: "69"; height: "107"; }
+ ListElement{ longitude: "19"; latitude: "70"; height: "107"; }
+ ListElement{ longitude: "19"; latitude: "71"; height: "110"; }
+ ListElement{ longitude: "19"; latitude: "72"; height: "112"; }
+ ListElement{ longitude: "19"; latitude: "73"; height: "112"; }
+ ListElement{ longitude: "19"; latitude: "74"; height: "110"; }
+ ListElement{ longitude: "19"; latitude: "75"; height: "111"; }
+ ListElement{ longitude: "19"; latitude: "76"; height: "111"; }
+ ListElement{ longitude: "19"; latitude: "77"; height: "111"; }
+ ListElement{ longitude: "19"; latitude: "78"; height: "111"; }
+ ListElement{ longitude: "19"; latitude: "79"; height: "110"; }
+ ListElement{ longitude: "19"; latitude: "80"; height: "109"; }
+ ListElement{ longitude: "19"; latitude: "81"; height: "110"; }
+ ListElement{ longitude: "19"; latitude: "82"; height: "113"; }
+ ListElement{ longitude: "19"; latitude: "83"; height: "116"; }
+ ListElement{ longitude: "19"; latitude: "84"; height: "116"; }
+ ListElement{ longitude: "19"; latitude: "85"; height: "112"; }
+ ListElement{ longitude: "19"; latitude: "86"; height: "105"; }
+ ListElement{ longitude: "19"; latitude: "87"; height: "102"; }
+ ListElement{ longitude: "19"; latitude: "88"; height: "101"; }
+ ListElement{ longitude: "19"; latitude: "89"; height: "102"; }
+ ListElement{ longitude: "19"; latitude: "90"; height: "105"; }
+ ListElement{ longitude: "19"; latitude: "91"; height: "99"; }
+ ListElement{ longitude: "19"; latitude: "92"; height: "103"; }
+ ListElement{ longitude: "19"; latitude: "93"; height: "104"; }
+ ListElement{ longitude: "19"; latitude: "94"; height: "110"; }
+ ListElement{ longitude: "19"; latitude: "95"; height: "114"; }
+ ListElement{ longitude: "19"; latitude: "96"; height: "120"; }
+ ListElement{ longitude: "19"; latitude: "97"; height: "123"; }
+ ListElement{ longitude: "19"; latitude: "98"; height: "127"; }
+ ListElement{ longitude: "19"; latitude: "99"; height: "114"; }
+ ListElement{ longitude: "20"; latitude: "0"; height: "117"; }
+ ListElement{ longitude: "20"; latitude: "1"; height: "120"; }
+ ListElement{ longitude: "20"; latitude: "2"; height: "121"; }
+ ListElement{ longitude: "20"; latitude: "3"; height: "123"; }
+ ListElement{ longitude: "20"; latitude: "4"; height: "125"; }
+ ListElement{ longitude: "20"; latitude: "5"; height: "127"; }
+ ListElement{ longitude: "20"; latitude: "6"; height: "124"; }
+ ListElement{ longitude: "20"; latitude: "7"; height: "123"; }
+ ListElement{ longitude: "20"; latitude: "8"; height: "125"; }
+ ListElement{ longitude: "20"; latitude: "9"; height: "125"; }
+ ListElement{ longitude: "20"; latitude: "10"; height: "123"; }
+ ListElement{ longitude: "20"; latitude: "11"; height: "122"; }
+ ListElement{ longitude: "20"; latitude: "12"; height: "123"; }
+ ListElement{ longitude: "20"; latitude: "13"; height: "122"; }
+ ListElement{ longitude: "20"; latitude: "14"; height: "120"; }
+ ListElement{ longitude: "20"; latitude: "15"; height: "114"; }
+ ListElement{ longitude: "20"; latitude: "16"; height: "112"; }
+ ListElement{ longitude: "20"; latitude: "17"; height: "113"; }
+ ListElement{ longitude: "20"; latitude: "18"; height: "118"; }
+ ListElement{ longitude: "20"; latitude: "19"; height: "120"; }
+ ListElement{ longitude: "20"; latitude: "20"; height: "120"; }
+ ListElement{ longitude: "20"; latitude: "21"; height: "118"; }
+ ListElement{ longitude: "20"; latitude: "22"; height: "119"; }
+ ListElement{ longitude: "20"; latitude: "23"; height: "118"; }
+ ListElement{ longitude: "20"; latitude: "24"; height: "116"; }
+ ListElement{ longitude: "20"; latitude: "25"; height: "117"; }
+ ListElement{ longitude: "20"; latitude: "26"; height: "116"; }
+ ListElement{ longitude: "20"; latitude: "27"; height: "118"; }
+ ListElement{ longitude: "20"; latitude: "28"; height: "118"; }
+ ListElement{ longitude: "20"; latitude: "29"; height: "121"; }
+ ListElement{ longitude: "20"; latitude: "30"; height: "119"; }
+ ListElement{ longitude: "20"; latitude: "31"; height: "121"; }
+ ListElement{ longitude: "20"; latitude: "32"; height: "124"; }
+ ListElement{ longitude: "20"; latitude: "33"; height: "125"; }
+ ListElement{ longitude: "20"; latitude: "34"; height: "125"; }
+ ListElement{ longitude: "20"; latitude: "35"; height: "125"; }
+ ListElement{ longitude: "20"; latitude: "36"; height: "124"; }
+ ListElement{ longitude: "20"; latitude: "37"; height: "127"; }
+ ListElement{ longitude: "20"; latitude: "38"; height: "124"; }
+ ListElement{ longitude: "20"; latitude: "39"; height: "128"; }
+ ListElement{ longitude: "20"; latitude: "40"; height: "127"; }
+ ListElement{ longitude: "20"; latitude: "41"; height: "129"; }
+ ListElement{ longitude: "20"; latitude: "42"; height: "129"; }
+ ListElement{ longitude: "20"; latitude: "43"; height: "129"; }
+ ListElement{ longitude: "20"; latitude: "44"; height: "128"; }
+ ListElement{ longitude: "20"; latitude: "45"; height: "126"; }
+ ListElement{ longitude: "20"; latitude: "46"; height: "127"; }
+ ListElement{ longitude: "20"; latitude: "47"; height: "125"; }
+ ListElement{ longitude: "20"; latitude: "48"; height: "122"; }
+ ListElement{ longitude: "20"; latitude: "49"; height: "121"; }
+ ListElement{ longitude: "20"; latitude: "50"; height: "120"; }
+ ListElement{ longitude: "20"; latitude: "51"; height: "120"; }
+ ListElement{ longitude: "20"; latitude: "52"; height: "121"; }
+ ListElement{ longitude: "20"; latitude: "53"; height: "123"; }
+ ListElement{ longitude: "20"; latitude: "54"; height: "125"; }
+ ListElement{ longitude: "20"; latitude: "55"; height: "129"; }
+ ListElement{ longitude: "20"; latitude: "56"; height: "124"; }
+ ListElement{ longitude: "20"; latitude: "57"; height: "111"; }
+ ListElement{ longitude: "20"; latitude: "58"; height: "108"; }
+ ListElement{ longitude: "20"; latitude: "59"; height: "118"; }
+ ListElement{ longitude: "20"; latitude: "60"; height: "125"; }
+ ListElement{ longitude: "20"; latitude: "61"; height: "124"; }
+ ListElement{ longitude: "20"; latitude: "62"; height: "121"; }
+ ListElement{ longitude: "20"; latitude: "63"; height: "125"; }
+ ListElement{ longitude: "20"; latitude: "64"; height: "122"; }
+ ListElement{ longitude: "20"; latitude: "65"; height: "116"; }
+ ListElement{ longitude: "20"; latitude: "66"; height: "110"; }
+ ListElement{ longitude: "20"; latitude: "67"; height: "108"; }
+ ListElement{ longitude: "20"; latitude: "68"; height: "105"; }
+ ListElement{ longitude: "20"; latitude: "69"; height: "107"; }
+ ListElement{ longitude: "20"; latitude: "70"; height: "106"; }
+ ListElement{ longitude: "20"; latitude: "71"; height: "109"; }
+ ListElement{ longitude: "20"; latitude: "72"; height: "112"; }
+ ListElement{ longitude: "20"; latitude: "73"; height: "112"; }
+ ListElement{ longitude: "20"; latitude: "74"; height: "112"; }
+ ListElement{ longitude: "20"; latitude: "75"; height: "110"; }
+ ListElement{ longitude: "20"; latitude: "76"; height: "111"; }
+ ListElement{ longitude: "20"; latitude: "77"; height: "111"; }
+ ListElement{ longitude: "20"; latitude: "78"; height: "110"; }
+ ListElement{ longitude: "20"; latitude: "79"; height: "107"; }
+ ListElement{ longitude: "20"; latitude: "80"; height: "107"; }
+ ListElement{ longitude: "20"; latitude: "81"; height: "109"; }
+ ListElement{ longitude: "20"; latitude: "82"; height: "113"; }
+ ListElement{ longitude: "20"; latitude: "83"; height: "116"; }
+ ListElement{ longitude: "20"; latitude: "84"; height: "109"; }
+ ListElement{ longitude: "20"; latitude: "85"; height: "102"; }
+ ListElement{ longitude: "20"; latitude: "86"; height: "107"; }
+ ListElement{ longitude: "20"; latitude: "87"; height: "103"; }
+ ListElement{ longitude: "20"; latitude: "88"; height: "102"; }
+ ListElement{ longitude: "20"; latitude: "89"; height: "102"; }
+ ListElement{ longitude: "20"; latitude: "90"; height: "104"; }
+ ListElement{ longitude: "20"; latitude: "91"; height: "101"; }
+ ListElement{ longitude: "20"; latitude: "92"; height: "110"; }
+ ListElement{ longitude: "20"; latitude: "93"; height: "110"; }
+ ListElement{ longitude: "20"; latitude: "94"; height: "111"; }
+ ListElement{ longitude: "20"; latitude: "95"; height: "111"; }
+ ListElement{ longitude: "20"; latitude: "96"; height: "117"; }
+ ListElement{ longitude: "20"; latitude: "97"; height: "121"; }
+ ListElement{ longitude: "20"; latitude: "98"; height: "122"; }
+ ListElement{ longitude: "20"; latitude: "99"; height: "112"; }
+ ListElement{ longitude: "21"; latitude: "0"; height: "116"; }
+ ListElement{ longitude: "21"; latitude: "1"; height: "118"; }
+ ListElement{ longitude: "21"; latitude: "2"; height: "119"; }
+ ListElement{ longitude: "21"; latitude: "3"; height: "120"; }
+ ListElement{ longitude: "21"; latitude: "4"; height: "121"; }
+ ListElement{ longitude: "21"; latitude: "5"; height: "123"; }
+ ListElement{ longitude: "21"; latitude: "6"; height: "119"; }
+ ListElement{ longitude: "21"; latitude: "7"; height: "119"; }
+ ListElement{ longitude: "21"; latitude: "8"; height: "122"; }
+ ListElement{ longitude: "21"; latitude: "9"; height: "123"; }
+ ListElement{ longitude: "21"; latitude: "10"; height: "125"; }
+ ListElement{ longitude: "21"; latitude: "11"; height: "125"; }
+ ListElement{ longitude: "21"; latitude: "12"; height: "124"; }
+ ListElement{ longitude: "21"; latitude: "13"; height: "122"; }
+ ListElement{ longitude: "21"; latitude: "14"; height: "124"; }
+ ListElement{ longitude: "21"; latitude: "15"; height: "120"; }
+ ListElement{ longitude: "21"; latitude: "16"; height: "119"; }
+ ListElement{ longitude: "21"; latitude: "17"; height: "118"; }
+ ListElement{ longitude: "21"; latitude: "18"; height: "119"; }
+ ListElement{ longitude: "21"; latitude: "19"; height: "121"; }
+ ListElement{ longitude: "21"; latitude: "20"; height: "121"; }
+ ListElement{ longitude: "21"; latitude: "21"; height: "119"; }
+ ListElement{ longitude: "21"; latitude: "22"; height: "120"; }
+ ListElement{ longitude: "21"; latitude: "23"; height: "117"; }
+ ListElement{ longitude: "21"; latitude: "24"; height: "116"; }
+ ListElement{ longitude: "21"; latitude: "25"; height: "116"; }
+ ListElement{ longitude: "21"; latitude: "26"; height: "116"; }
+ ListElement{ longitude: "21"; latitude: "27"; height: "115"; }
+ ListElement{ longitude: "21"; latitude: "28"; height: "121"; }
+ ListElement{ longitude: "21"; latitude: "29"; height: "120"; }
+ ListElement{ longitude: "21"; latitude: "30"; height: "119"; }
+ ListElement{ longitude: "21"; latitude: "31"; height: "119"; }
+ ListElement{ longitude: "21"; latitude: "32"; height: "121"; }
+ ListElement{ longitude: "21"; latitude: "33"; height: "122"; }
+ ListElement{ longitude: "21"; latitude: "34"; height: "125"; }
+ ListElement{ longitude: "21"; latitude: "35"; height: "125"; }
+ ListElement{ longitude: "21"; latitude: "36"; height: "124"; }
+ ListElement{ longitude: "21"; latitude: "37"; height: "127"; }
+ ListElement{ longitude: "21"; latitude: "38"; height: "126"; }
+ ListElement{ longitude: "21"; latitude: "39"; height: "128"; }
+ ListElement{ longitude: "21"; latitude: "40"; height: "127"; }
+ ListElement{ longitude: "21"; latitude: "41"; height: "127"; }
+ ListElement{ longitude: "21"; latitude: "42"; height: "127"; }
+ ListElement{ longitude: "21"; latitude: "43"; height: "127"; }
+ ListElement{ longitude: "21"; latitude: "44"; height: "128"; }
+ ListElement{ longitude: "21"; latitude: "45"; height: "125"; }
+ ListElement{ longitude: "21"; latitude: "46"; height: "126"; }
+ ListElement{ longitude: "21"; latitude: "47"; height: "124"; }
+ ListElement{ longitude: "21"; latitude: "48"; height: "124"; }
+ ListElement{ longitude: "21"; latitude: "49"; height: "121"; }
+ ListElement{ longitude: "21"; latitude: "50"; height: "120"; }
+ ListElement{ longitude: "21"; latitude: "51"; height: "120"; }
+ ListElement{ longitude: "21"; latitude: "52"; height: "122"; }
+ ListElement{ longitude: "21"; latitude: "53"; height: "121"; }
+ ListElement{ longitude: "21"; latitude: "54"; height: "122"; }
+ ListElement{ longitude: "21"; latitude: "55"; height: "127"; }
+ ListElement{ longitude: "21"; latitude: "56"; height: "123"; }
+ ListElement{ longitude: "21"; latitude: "57"; height: "114"; }
+ ListElement{ longitude: "21"; latitude: "58"; height: "111"; }
+ ListElement{ longitude: "21"; latitude: "59"; height: "120"; }
+ ListElement{ longitude: "21"; latitude: "60"; height: "127"; }
+ ListElement{ longitude: "21"; latitude: "61"; height: "128"; }
+ ListElement{ longitude: "21"; latitude: "62"; height: "125"; }
+ ListElement{ longitude: "21"; latitude: "63"; height: "123"; }
+ ListElement{ longitude: "21"; latitude: "64"; height: "118"; }
+ ListElement{ longitude: "21"; latitude: "65"; height: "113"; }
+ ListElement{ longitude: "21"; latitude: "66"; height: "112"; }
+ ListElement{ longitude: "21"; latitude: "67"; height: "109"; }
+ ListElement{ longitude: "21"; latitude: "68"; height: "108"; }
+ ListElement{ longitude: "21"; latitude: "69"; height: "109"; }
+ ListElement{ longitude: "21"; latitude: "70"; height: "110"; }
+ ListElement{ longitude: "21"; latitude: "71"; height: "110"; }
+ ListElement{ longitude: "21"; latitude: "72"; height: "110"; }
+ ListElement{ longitude: "21"; latitude: "73"; height: "110"; }
+ ListElement{ longitude: "21"; latitude: "74"; height: "112"; }
+ ListElement{ longitude: "21"; latitude: "75"; height: "112"; }
+ ListElement{ longitude: "21"; latitude: "76"; height: "111"; }
+ ListElement{ longitude: "21"; latitude: "77"; height: "110"; }
+ ListElement{ longitude: "21"; latitude: "78"; height: "109"; }
+ ListElement{ longitude: "21"; latitude: "79"; height: "106"; }
+ ListElement{ longitude: "21"; latitude: "80"; height: "106"; }
+ ListElement{ longitude: "21"; latitude: "81"; height: "107"; }
+ ListElement{ longitude: "21"; latitude: "82"; height: "110"; }
+ ListElement{ longitude: "21"; latitude: "83"; height: "118"; }
+ ListElement{ longitude: "21"; latitude: "84"; height: "109"; }
+ ListElement{ longitude: "21"; latitude: "85"; height: "107"; }
+ ListElement{ longitude: "21"; latitude: "86"; height: "113"; }
+ ListElement{ longitude: "21"; latitude: "87"; height: "103"; }
+ ListElement{ longitude: "21"; latitude: "88"; height: "103"; }
+ ListElement{ longitude: "21"; latitude: "89"; height: "105"; }
+ ListElement{ longitude: "21"; latitude: "90"; height: "104"; }
+ ListElement{ longitude: "21"; latitude: "91"; height: "102"; }
+ ListElement{ longitude: "21"; latitude: "92"; height: "102"; }
+ ListElement{ longitude: "21"; latitude: "93"; height: "104"; }
+ ListElement{ longitude: "21"; latitude: "94"; height: "105"; }
+ ListElement{ longitude: "21"; latitude: "95"; height: "113"; }
+ ListElement{ longitude: "21"; latitude: "96"; height: "117"; }
+ ListElement{ longitude: "21"; latitude: "97"; height: "122"; }
+ ListElement{ longitude: "21"; latitude: "98"; height: "123"; }
+ ListElement{ longitude: "21"; latitude: "99"; height: "114"; }
+ ListElement{ longitude: "22"; latitude: "0"; height: "119"; }
+ ListElement{ longitude: "22"; latitude: "1"; height: "120"; }
+ ListElement{ longitude: "22"; latitude: "2"; height: "119"; }
+ ListElement{ longitude: "22"; latitude: "3"; height: "119"; }
+ ListElement{ longitude: "22"; latitude: "4"; height: "119"; }
+ ListElement{ longitude: "22"; latitude: "5"; height: "121"; }
+ ListElement{ longitude: "22"; latitude: "6"; height: "120"; }
+ ListElement{ longitude: "22"; latitude: "7"; height: "120"; }
+ ListElement{ longitude: "22"; latitude: "8"; height: "121"; }
+ ListElement{ longitude: "22"; latitude: "9"; height: "124"; }
+ ListElement{ longitude: "22"; latitude: "10"; height: "125"; }
+ ListElement{ longitude: "22"; latitude: "11"; height: "125"; }
+ ListElement{ longitude: "22"; latitude: "12"; height: "127"; }
+ ListElement{ longitude: "22"; latitude: "13"; height: "126"; }
+ ListElement{ longitude: "22"; latitude: "14"; height: "123"; }
+ ListElement{ longitude: "22"; latitude: "15"; height: "124"; }
+ ListElement{ longitude: "22"; latitude: "16"; height: "122"; }
+ ListElement{ longitude: "22"; latitude: "17"; height: "122"; }
+ ListElement{ longitude: "22"; latitude: "18"; height: "124"; }
+ ListElement{ longitude: "22"; latitude: "19"; height: "123"; }
+ ListElement{ longitude: "22"; latitude: "20"; height: "124"; }
+ ListElement{ longitude: "22"; latitude: "21"; height: "121"; }
+ ListElement{ longitude: "22"; latitude: "22"; height: "120"; }
+ ListElement{ longitude: "22"; latitude: "23"; height: "116"; }
+ ListElement{ longitude: "22"; latitude: "24"; height: "118"; }
+ ListElement{ longitude: "22"; latitude: "25"; height: "120"; }
+ ListElement{ longitude: "22"; latitude: "26"; height: "120"; }
+ ListElement{ longitude: "22"; latitude: "27"; height: "119"; }
+ ListElement{ longitude: "22"; latitude: "28"; height: "117"; }
+ ListElement{ longitude: "22"; latitude: "29"; height: "117"; }
+ ListElement{ longitude: "22"; latitude: "30"; height: "118"; }
+ ListElement{ longitude: "22"; latitude: "31"; height: "121"; }
+ ListElement{ longitude: "22"; latitude: "32"; height: "122"; }
+ ListElement{ longitude: "22"; latitude: "33"; height: "121"; }
+ ListElement{ longitude: "22"; latitude: "34"; height: "124"; }
+ ListElement{ longitude: "22"; latitude: "35"; height: "125"; }
+ ListElement{ longitude: "22"; latitude: "36"; height: "124"; }
+ ListElement{ longitude: "22"; latitude: "37"; height: "127"; }
+ ListElement{ longitude: "22"; latitude: "38"; height: "126"; }
+ ListElement{ longitude: "22"; latitude: "39"; height: "128"; }
+ ListElement{ longitude: "22"; latitude: "40"; height: "128"; }
+ ListElement{ longitude: "22"; latitude: "41"; height: "128"; }
+ ListElement{ longitude: "22"; latitude: "42"; height: "128"; }
+ ListElement{ longitude: "22"; latitude: "43"; height: "128"; }
+ ListElement{ longitude: "22"; latitude: "44"; height: "128"; }
+ ListElement{ longitude: "22"; latitude: "45"; height: "125"; }
+ ListElement{ longitude: "22"; latitude: "46"; height: "125"; }
+ ListElement{ longitude: "22"; latitude: "47"; height: "126"; }
+ ListElement{ longitude: "22"; latitude: "48"; height: "125"; }
+ ListElement{ longitude: "22"; latitude: "49"; height: "124"; }
+ ListElement{ longitude: "22"; latitude: "50"; height: "121"; }
+ ListElement{ longitude: "22"; latitude: "51"; height: "120"; }
+ ListElement{ longitude: "22"; latitude: "52"; height: "119"; }
+ ListElement{ longitude: "22"; latitude: "53"; height: "119"; }
+ ListElement{ longitude: "22"; latitude: "54"; height: "122"; }
+ ListElement{ longitude: "22"; latitude: "55"; height: "123"; }
+ ListElement{ longitude: "22"; latitude: "56"; height: "126"; }
+ ListElement{ longitude: "22"; latitude: "57"; height: "123"; }
+ ListElement{ longitude: "22"; latitude: "58"; height: "123"; }
+ ListElement{ longitude: "22"; latitude: "59"; height: "127"; }
+ ListElement{ longitude: "22"; latitude: "60"; height: "128"; }
+ ListElement{ longitude: "22"; latitude: "61"; height: "129"; }
+ ListElement{ longitude: "22"; latitude: "62"; height: "128"; }
+ ListElement{ longitude: "22"; latitude: "63"; height: "123"; }
+ ListElement{ longitude: "22"; latitude: "64"; height: "120"; }
+ ListElement{ longitude: "22"; latitude: "65"; height: "118"; }
+ ListElement{ longitude: "22"; latitude: "66"; height: "116"; }
+ ListElement{ longitude: "22"; latitude: "67"; height: "115"; }
+ ListElement{ longitude: "22"; latitude: "68"; height: "116"; }
+ ListElement{ longitude: "22"; latitude: "69"; height: "114"; }
+ ListElement{ longitude: "22"; latitude: "70"; height: "113"; }
+ ListElement{ longitude: "22"; latitude: "71"; height: "112"; }
+ ListElement{ longitude: "22"; latitude: "72"; height: "113"; }
+ ListElement{ longitude: "22"; latitude: "73"; height: "113"; }
+ ListElement{ longitude: "22"; latitude: "74"; height: "112"; }
+ ListElement{ longitude: "22"; latitude: "75"; height: "110"; }
+ ListElement{ longitude: "22"; latitude: "76"; height: "110"; }
+ ListElement{ longitude: "22"; latitude: "77"; height: "107"; }
+ ListElement{ longitude: "22"; latitude: "78"; height: "105"; }
+ ListElement{ longitude: "22"; latitude: "79"; height: "102"; }
+ ListElement{ longitude: "22"; latitude: "80"; height: "104"; }
+ ListElement{ longitude: "22"; latitude: "81"; height: "108"; }
+ ListElement{ longitude: "22"; latitude: "82"; height: "110"; }
+ ListElement{ longitude: "22"; latitude: "83"; height: "114"; }
+ ListElement{ longitude: "22"; latitude: "84"; height: "118"; }
+ ListElement{ longitude: "22"; latitude: "85"; height: "117"; }
+ ListElement{ longitude: "22"; latitude: "86"; height: "111"; }
+ ListElement{ longitude: "22"; latitude: "87"; height: "107"; }
+ ListElement{ longitude: "22"; latitude: "88"; height: "107"; }
+ ListElement{ longitude: "22"; latitude: "89"; height: "107"; }
+ ListElement{ longitude: "22"; latitude: "90"; height: "103"; }
+ ListElement{ longitude: "22"; latitude: "91"; height: "102"; }
+ ListElement{ longitude: "22"; latitude: "92"; height: "101"; }
+ ListElement{ longitude: "22"; latitude: "93"; height: "108"; }
+ ListElement{ longitude: "22"; latitude: "94"; height: "115"; }
+ ListElement{ longitude: "22"; latitude: "95"; height: "117"; }
+ ListElement{ longitude: "22"; latitude: "96"; height: "120"; }
+ ListElement{ longitude: "22"; latitude: "97"; height: "125"; }
+ ListElement{ longitude: "22"; latitude: "98"; height: "128"; }
+ ListElement{ longitude: "22"; latitude: "99"; height: "118"; }
+ ListElement{ longitude: "23"; latitude: "0"; height: "120"; }
+ ListElement{ longitude: "23"; latitude: "1"; height: "123"; }
+ ListElement{ longitude: "23"; latitude: "2"; height: "120"; }
+ ListElement{ longitude: "23"; latitude: "3"; height: "121"; }
+ ListElement{ longitude: "23"; latitude: "4"; height: "119"; }
+ ListElement{ longitude: "23"; latitude: "5"; height: "119"; }
+ ListElement{ longitude: "23"; latitude: "6"; height: "120"; }
+ ListElement{ longitude: "23"; latitude: "7"; height: "122"; }
+ ListElement{ longitude: "23"; latitude: "8"; height: "121"; }
+ ListElement{ longitude: "23"; latitude: "9"; height: "124"; }
+ ListElement{ longitude: "23"; latitude: "10"; height: "124"; }
+ ListElement{ longitude: "23"; latitude: "11"; height: "122"; }
+ ListElement{ longitude: "23"; latitude: "12"; height: "124"; }
+ ListElement{ longitude: "23"; latitude: "13"; height: "124"; }
+ ListElement{ longitude: "23"; latitude: "14"; height: "121"; }
+ ListElement{ longitude: "23"; latitude: "15"; height: "121"; }
+ ListElement{ longitude: "23"; latitude: "16"; height: "122"; }
+ ListElement{ longitude: "23"; latitude: "17"; height: "122"; }
+ ListElement{ longitude: "23"; latitude: "18"; height: "123"; }
+ ListElement{ longitude: "23"; latitude: "19"; height: "121"; }
+ ListElement{ longitude: "23"; latitude: "20"; height: "122"; }
+ ListElement{ longitude: "23"; latitude: "21"; height: "120"; }
+ ListElement{ longitude: "23"; latitude: "22"; height: "121"; }
+ ListElement{ longitude: "23"; latitude: "23"; height: "121"; }
+ ListElement{ longitude: "23"; latitude: "24"; height: "121"; }
+ ListElement{ longitude: "23"; latitude: "25"; height: "120"; }
+ ListElement{ longitude: "23"; latitude: "26"; height: "121"; }
+ ListElement{ longitude: "23"; latitude: "27"; height: "120"; }
+ ListElement{ longitude: "23"; latitude: "28"; height: "116"; }
+ ListElement{ longitude: "23"; latitude: "29"; height: "116"; }
+ ListElement{ longitude: "23"; latitude: "30"; height: "118"; }
+ ListElement{ longitude: "23"; latitude: "31"; height: "119"; }
+ ListElement{ longitude: "23"; latitude: "32"; height: "122"; }
+ ListElement{ longitude: "23"; latitude: "33"; height: "119"; }
+ ListElement{ longitude: "23"; latitude: "34"; height: "123"; }
+ ListElement{ longitude: "23"; latitude: "35"; height: "124"; }
+ ListElement{ longitude: "23"; latitude: "36"; height: "125"; }
+ ListElement{ longitude: "23"; latitude: "37"; height: "128"; }
+ ListElement{ longitude: "23"; latitude: "38"; height: "127"; }
+ ListElement{ longitude: "23"; latitude: "39"; height: "127"; }
+ ListElement{ longitude: "23"; latitude: "40"; height: "126"; }
+ ListElement{ longitude: "23"; latitude: "41"; height: "128"; }
+ ListElement{ longitude: "23"; latitude: "42"; height: "127"; }
+ ListElement{ longitude: "23"; latitude: "43"; height: "127"; }
+ ListElement{ longitude: "23"; latitude: "44"; height: "127"; }
+ ListElement{ longitude: "23"; latitude: "45"; height: "128"; }
+ ListElement{ longitude: "23"; latitude: "46"; height: "126"; }
+ ListElement{ longitude: "23"; latitude: "47"; height: "127"; }
+ ListElement{ longitude: "23"; latitude: "48"; height: "124"; }
+ ListElement{ longitude: "23"; latitude: "49"; height: "124"; }
+ ListElement{ longitude: "23"; latitude: "50"; height: "123"; }
+ ListElement{ longitude: "23"; latitude: "51"; height: "120"; }
+ ListElement{ longitude: "23"; latitude: "52"; height: "119"; }
+ ListElement{ longitude: "23"; latitude: "53"; height: "118"; }
+ ListElement{ longitude: "23"; latitude: "54"; height: "119"; }
+ ListElement{ longitude: "23"; latitude: "55"; height: "120"; }
+ ListElement{ longitude: "23"; latitude: "56"; height: "122"; }
+ ListElement{ longitude: "23"; latitude: "57"; height: "125"; }
+ ListElement{ longitude: "23"; latitude: "58"; height: "127"; }
+ ListElement{ longitude: "23"; latitude: "59"; height: "128"; }
+ ListElement{ longitude: "23"; latitude: "60"; height: "130"; }
+ ListElement{ longitude: "23"; latitude: "61"; height: "133"; }
+ ListElement{ longitude: "23"; latitude: "62"; height: "130"; }
+ ListElement{ longitude: "23"; latitude: "63"; height: "128"; }
+ ListElement{ longitude: "23"; latitude: "64"; height: "123"; }
+ ListElement{ longitude: "23"; latitude: "65"; height: "121"; }
+ ListElement{ longitude: "23"; latitude: "66"; height: "122"; }
+ ListElement{ longitude: "23"; latitude: "67"; height: "122"; }
+ ListElement{ longitude: "23"; latitude: "68"; height: "122"; }
+ ListElement{ longitude: "23"; latitude: "69"; height: "121"; }
+ ListElement{ longitude: "23"; latitude: "70"; height: "119"; }
+ ListElement{ longitude: "23"; latitude: "71"; height: "115"; }
+ ListElement{ longitude: "23"; latitude: "72"; height: "114"; }
+ ListElement{ longitude: "23"; latitude: "73"; height: "112"; }
+ ListElement{ longitude: "23"; latitude: "74"; height: "111"; }
+ ListElement{ longitude: "23"; latitude: "75"; height: "111"; }
+ ListElement{ longitude: "23"; latitude: "76"; height: "108"; }
+ ListElement{ longitude: "23"; latitude: "77"; height: "107"; }
+ ListElement{ longitude: "23"; latitude: "78"; height: "103"; }
+ ListElement{ longitude: "23"; latitude: "79"; height: "102"; }
+ ListElement{ longitude: "23"; latitude: "80"; height: "101"; }
+ ListElement{ longitude: "23"; latitude: "81"; height: "106"; }
+ ListElement{ longitude: "23"; latitude: "82"; height: "113"; }
+ ListElement{ longitude: "23"; latitude: "83"; height: "112"; }
+ ListElement{ longitude: "23"; latitude: "84"; height: "115"; }
+ ListElement{ longitude: "23"; latitude: "85"; height: "111"; }
+ ListElement{ longitude: "23"; latitude: "86"; height: "111"; }
+ ListElement{ longitude: "23"; latitude: "87"; height: "109"; }
+ ListElement{ longitude: "23"; latitude: "88"; height: "108"; }
+ ListElement{ longitude: "23"; latitude: "89"; height: "108"; }
+ ListElement{ longitude: "23"; latitude: "90"; height: "106"; }
+ ListElement{ longitude: "23"; latitude: "91"; height: "103"; }
+ ListElement{ longitude: "23"; latitude: "92"; height: "102"; }
+ ListElement{ longitude: "23"; latitude: "93"; height: "108"; }
+ ListElement{ longitude: "23"; latitude: "94"; height: "115"; }
+ ListElement{ longitude: "23"; latitude: "95"; height: "119"; }
+ ListElement{ longitude: "23"; latitude: "96"; height: "125"; }
+ ListElement{ longitude: "23"; latitude: "97"; height: "128"; }
+ ListElement{ longitude: "23"; latitude: "98"; height: "135"; }
+ ListElement{ longitude: "23"; latitude: "99"; height: "120"; }
+ ListElement{ longitude: "24"; latitude: "0"; height: "122"; }
+ ListElement{ longitude: "24"; latitude: "1"; height: "122"; }
+ ListElement{ longitude: "24"; latitude: "2"; height: "122"; }
+ ListElement{ longitude: "24"; latitude: "3"; height: "123"; }
+ ListElement{ longitude: "24"; latitude: "4"; height: "118"; }
+ ListElement{ longitude: "24"; latitude: "5"; height: "122"; }
+ ListElement{ longitude: "24"; latitude: "6"; height: "121"; }
+ ListElement{ longitude: "24"; latitude: "7"; height: "122"; }
+ ListElement{ longitude: "24"; latitude: "8"; height: "122"; }
+ ListElement{ longitude: "24"; latitude: "9"; height: "122"; }
+ ListElement{ longitude: "24"; latitude: "10"; height: "124"; }
+ ListElement{ longitude: "24"; latitude: "11"; height: "122"; }
+ ListElement{ longitude: "24"; latitude: "12"; height: "122"; }
+ ListElement{ longitude: "24"; latitude: "13"; height: "120"; }
+ ListElement{ longitude: "24"; latitude: "14"; height: "123"; }
+ ListElement{ longitude: "24"; latitude: "15"; height: "121"; }
+ ListElement{ longitude: "24"; latitude: "16"; height: "118"; }
+ ListElement{ longitude: "24"; latitude: "17"; height: "120"; }
+ ListElement{ longitude: "24"; latitude: "18"; height: "122"; }
+ ListElement{ longitude: "24"; latitude: "19"; height: "120"; }
+ ListElement{ longitude: "24"; latitude: "20"; height: "120"; }
+ ListElement{ longitude: "24"; latitude: "21"; height: "119"; }
+ ListElement{ longitude: "24"; latitude: "22"; height: "120"; }
+ ListElement{ longitude: "24"; latitude: "23"; height: "121"; }
+ ListElement{ longitude: "24"; latitude: "24"; height: "123"; }
+ ListElement{ longitude: "24"; latitude: "25"; height: "123"; }
+ ListElement{ longitude: "24"; latitude: "26"; height: "121"; }
+ ListElement{ longitude: "24"; latitude: "27"; height: "120"; }
+ ListElement{ longitude: "24"; latitude: "28"; height: "121"; }
+ ListElement{ longitude: "24"; latitude: "29"; height: "121"; }
+ ListElement{ longitude: "24"; latitude: "30"; height: "121"; }
+ ListElement{ longitude: "24"; latitude: "31"; height: "120"; }
+ ListElement{ longitude: "24"; latitude: "32"; height: "122"; }
+ ListElement{ longitude: "24"; latitude: "33"; height: "122"; }
+ ListElement{ longitude: "24"; latitude: "34"; height: "122"; }
+ ListElement{ longitude: "24"; latitude: "35"; height: "123"; }
+ ListElement{ longitude: "24"; latitude: "36"; height: "124"; }
+ ListElement{ longitude: "24"; latitude: "37"; height: "123"; }
+ ListElement{ longitude: "24"; latitude: "38"; height: "126"; }
+ ListElement{ longitude: "24"; latitude: "39"; height: "125"; }
+ ListElement{ longitude: "24"; latitude: "40"; height: "125"; }
+ ListElement{ longitude: "24"; latitude: "41"; height: "128"; }
+ ListElement{ longitude: "24"; latitude: "42"; height: "129"; }
+ ListElement{ longitude: "24"; latitude: "43"; height: "129"; }
+ ListElement{ longitude: "24"; latitude: "44"; height: "129"; }
+ ListElement{ longitude: "24"; latitude: "45"; height: "129"; }
+ ListElement{ longitude: "24"; latitude: "46"; height: "127"; }
+ ListElement{ longitude: "24"; latitude: "47"; height: "127"; }
+ ListElement{ longitude: "24"; latitude: "48"; height: "124"; }
+ ListElement{ longitude: "24"; latitude: "49"; height: "124"; }
+ ListElement{ longitude: "24"; latitude: "50"; height: "123"; }
+ ListElement{ longitude: "24"; latitude: "51"; height: "120"; }
+ ListElement{ longitude: "24"; latitude: "52"; height: "120"; }
+ ListElement{ longitude: "24"; latitude: "53"; height: "118"; }
+ ListElement{ longitude: "24"; latitude: "54"; height: "120"; }
+ ListElement{ longitude: "24"; latitude: "55"; height: "120"; }
+ ListElement{ longitude: "24"; latitude: "56"; height: "122"; }
+ ListElement{ longitude: "24"; latitude: "57"; height: "126"; }
+ ListElement{ longitude: "24"; latitude: "58"; height: "126"; }
+ ListElement{ longitude: "24"; latitude: "59"; height: "131"; }
+ ListElement{ longitude: "24"; latitude: "60"; height: "133"; }
+ ListElement{ longitude: "24"; latitude: "61"; height: "134"; }
+ ListElement{ longitude: "24"; latitude: "62"; height: "132"; }
+ ListElement{ longitude: "24"; latitude: "63"; height: "128"; }
+ ListElement{ longitude: "24"; latitude: "64"; height: "126"; }
+ ListElement{ longitude: "24"; latitude: "65"; height: "125"; }
+ ListElement{ longitude: "24"; latitude: "66"; height: "125"; }
+ ListElement{ longitude: "24"; latitude: "67"; height: "127"; }
+ ListElement{ longitude: "24"; latitude: "68"; height: "128"; }
+ ListElement{ longitude: "24"; latitude: "69"; height: "126"; }
+ ListElement{ longitude: "24"; latitude: "70"; height: "124"; }
+ ListElement{ longitude: "24"; latitude: "71"; height: "120"; }
+ ListElement{ longitude: "24"; latitude: "72"; height: "117"; }
+ ListElement{ longitude: "24"; latitude: "73"; height: "113"; }
+ ListElement{ longitude: "24"; latitude: "74"; height: "112"; }
+ ListElement{ longitude: "24"; latitude: "75"; height: "112"; }
+ ListElement{ longitude: "24"; latitude: "76"; height: "106"; }
+ ListElement{ longitude: "24"; latitude: "77"; height: "105"; }
+ ListElement{ longitude: "24"; latitude: "78"; height: "100"; }
+ ListElement{ longitude: "24"; latitude: "79"; height: "99"; }
+ ListElement{ longitude: "24"; latitude: "80"; height: "101"; }
+ ListElement{ longitude: "24"; latitude: "81"; height: "104"; }
+ ListElement{ longitude: "24"; latitude: "82"; height: "111"; }
+ ListElement{ longitude: "24"; latitude: "83"; height: "114"; }
+ ListElement{ longitude: "24"; latitude: "84"; height: "117"; }
+ ListElement{ longitude: "24"; latitude: "85"; height: "114"; }
+ ListElement{ longitude: "24"; latitude: "86"; height: "115"; }
+ ListElement{ longitude: "24"; latitude: "87"; height: "112"; }
+ ListElement{ longitude: "24"; latitude: "88"; height: "110"; }
+ ListElement{ longitude: "24"; latitude: "89"; height: "108"; }
+ ListElement{ longitude: "24"; latitude: "90"; height: "107"; }
+ ListElement{ longitude: "24"; latitude: "91"; height: "104"; }
+ ListElement{ longitude: "24"; latitude: "92"; height: "106"; }
+ ListElement{ longitude: "24"; latitude: "93"; height: "110"; }
+ ListElement{ longitude: "24"; latitude: "94"; height: "115"; }
+ ListElement{ longitude: "24"; latitude: "95"; height: "125"; }
+ ListElement{ longitude: "24"; latitude: "96"; height: "130"; }
+ ListElement{ longitude: "24"; latitude: "97"; height: "133"; }
+ ListElement{ longitude: "24"; latitude: "98"; height: "137"; }
+ ListElement{ longitude: "24"; latitude: "99"; height: "122"; }
+ ListElement{ longitude: "25"; latitude: "0"; height: "125"; }
+ ListElement{ longitude: "25"; latitude: "1"; height: "122"; }
+ ListElement{ longitude: "25"; latitude: "2"; height: "116"; }
+ ListElement{ longitude: "25"; latitude: "3"; height: "123"; }
+ ListElement{ longitude: "25"; latitude: "4"; height: "115"; }
+ ListElement{ longitude: "25"; latitude: "5"; height: "126"; }
+ ListElement{ longitude: "25"; latitude: "6"; height: "125"; }
+ ListElement{ longitude: "25"; latitude: "7"; height: "125"; }
+ ListElement{ longitude: "25"; latitude: "8"; height: "125"; }
+ ListElement{ longitude: "25"; latitude: "9"; height: "125"; }
+ ListElement{ longitude: "25"; latitude: "10"; height: "125"; }
+ ListElement{ longitude: "25"; latitude: "11"; height: "123"; }
+ ListElement{ longitude: "25"; latitude: "12"; height: "124"; }
+ ListElement{ longitude: "25"; latitude: "13"; height: "124"; }
+ ListElement{ longitude: "25"; latitude: "14"; height: "124"; }
+ ListElement{ longitude: "25"; latitude: "15"; height: "123"; }
+ ListElement{ longitude: "25"; latitude: "16"; height: "119"; }
+ ListElement{ longitude: "25"; latitude: "17"; height: "120"; }
+ ListElement{ longitude: "25"; latitude: "18"; height: "120"; }
+ ListElement{ longitude: "25"; latitude: "19"; height: "120"; }
+ ListElement{ longitude: "25"; latitude: "20"; height: "120"; }
+ ListElement{ longitude: "25"; latitude: "21"; height: "120"; }
+ ListElement{ longitude: "25"; latitude: "22"; height: "121"; }
+ ListElement{ longitude: "25"; latitude: "23"; height: "124"; }
+ ListElement{ longitude: "25"; latitude: "24"; height: "125"; }
+ ListElement{ longitude: "25"; latitude: "25"; height: "125"; }
+ ListElement{ longitude: "25"; latitude: "26"; height: "124"; }
+ ListElement{ longitude: "25"; latitude: "27"; height: "123"; }
+ ListElement{ longitude: "25"; latitude: "28"; height: "123"; }
+ ListElement{ longitude: "25"; latitude: "29"; height: "123"; }
+ ListElement{ longitude: "25"; latitude: "30"; height: "123"; }
+ ListElement{ longitude: "25"; latitude: "31"; height: "124"; }
+ ListElement{ longitude: "25"; latitude: "32"; height: "122"; }
+ ListElement{ longitude: "25"; latitude: "33"; height: "119"; }
+ ListElement{ longitude: "25"; latitude: "34"; height: "119"; }
+ ListElement{ longitude: "25"; latitude: "35"; height: "120"; }
+ ListElement{ longitude: "25"; latitude: "36"; height: "121"; }
+ ListElement{ longitude: "25"; latitude: "37"; height: "120"; }
+ ListElement{ longitude: "25"; latitude: "38"; height: "123"; }
+ ListElement{ longitude: "25"; latitude: "39"; height: "126"; }
+ ListElement{ longitude: "25"; latitude: "40"; height: "125"; }
+ ListElement{ longitude: "25"; latitude: "41"; height: "128"; }
+ ListElement{ longitude: "25"; latitude: "42"; height: "129"; }
+ ListElement{ longitude: "25"; latitude: "43"; height: "129"; }
+ ListElement{ longitude: "25"; latitude: "44"; height: "128"; }
+ ListElement{ longitude: "25"; latitude: "45"; height: "130"; }
+ ListElement{ longitude: "25"; latitude: "46"; height: "131"; }
+ ListElement{ longitude: "25"; latitude: "47"; height: "127"; }
+ ListElement{ longitude: "25"; latitude: "48"; height: "125"; }
+ ListElement{ longitude: "25"; latitude: "49"; height: "120"; }
+ ListElement{ longitude: "25"; latitude: "50"; height: "122"; }
+ ListElement{ longitude: "25"; latitude: "51"; height: "121"; }
+ ListElement{ longitude: "25"; latitude: "52"; height: "120"; }
+ ListElement{ longitude: "25"; latitude: "53"; height: "118"; }
+ ListElement{ longitude: "25"; latitude: "54"; height: "119"; }
+ ListElement{ longitude: "25"; latitude: "55"; height: "120"; }
+ ListElement{ longitude: "25"; latitude: "56"; height: "122"; }
+ ListElement{ longitude: "25"; latitude: "57"; height: "126"; }
+ ListElement{ longitude: "25"; latitude: "58"; height: "127"; }
+ ListElement{ longitude: "25"; latitude: "59"; height: "127"; }
+ ListElement{ longitude: "25"; latitude: "60"; height: "130"; }
+ ListElement{ longitude: "25"; latitude: "61"; height: "132"; }
+ ListElement{ longitude: "25"; latitude: "62"; height: "132"; }
+ ListElement{ longitude: "25"; latitude: "63"; height: "131"; }
+ ListElement{ longitude: "25"; latitude: "64"; height: "130"; }
+ ListElement{ longitude: "25"; latitude: "65"; height: "131"; }
+ ListElement{ longitude: "25"; latitude: "66"; height: "130"; }
+ ListElement{ longitude: "25"; latitude: "67"; height: "133"; }
+ ListElement{ longitude: "25"; latitude: "68"; height: "134"; }
+ ListElement{ longitude: "25"; latitude: "69"; height: "133"; }
+ ListElement{ longitude: "25"; latitude: "70"; height: "129"; }
+ ListElement{ longitude: "25"; latitude: "71"; height: "125"; }
+ ListElement{ longitude: "25"; latitude: "72"; height: "122"; }
+ ListElement{ longitude: "25"; latitude: "73"; height: "119"; }
+ ListElement{ longitude: "25"; latitude: "74"; height: "116"; }
+ ListElement{ longitude: "25"; latitude: "75"; height: "114"; }
+ ListElement{ longitude: "25"; latitude: "76"; height: "109"; }
+ ListElement{ longitude: "25"; latitude: "77"; height: "106"; }
+ ListElement{ longitude: "25"; latitude: "78"; height: "102"; }
+ ListElement{ longitude: "25"; latitude: "79"; height: "101"; }
+ ListElement{ longitude: "25"; latitude: "80"; height: "102"; }
+ ListElement{ longitude: "25"; latitude: "81"; height: "107"; }
+ ListElement{ longitude: "25"; latitude: "82"; height: "111"; }
+ ListElement{ longitude: "25"; latitude: "83"; height: "113"; }
+ ListElement{ longitude: "25"; latitude: "84"; height: "115"; }
+ ListElement{ longitude: "25"; latitude: "85"; height: "116"; }
+ ListElement{ longitude: "25"; latitude: "86"; height: "118"; }
+ ListElement{ longitude: "25"; latitude: "87"; height: "121"; }
+ ListElement{ longitude: "25"; latitude: "88"; height: "119"; }
+ ListElement{ longitude: "25"; latitude: "89"; height: "113"; }
+ ListElement{ longitude: "25"; latitude: "90"; height: "103"; }
+ ListElement{ longitude: "25"; latitude: "91"; height: "104"; }
+ ListElement{ longitude: "25"; latitude: "92"; height: "106"; }
+ ListElement{ longitude: "25"; latitude: "93"; height: "117"; }
+ ListElement{ longitude: "25"; latitude: "94"; height: "111"; }
+ ListElement{ longitude: "25"; latitude: "95"; height: "125"; }
+ ListElement{ longitude: "25"; latitude: "96"; height: "134"; }
+ ListElement{ longitude: "25"; latitude: "97"; height: "135"; }
+ ListElement{ longitude: "25"; latitude: "98"; height: "135"; }
+ ListElement{ longitude: "25"; latitude: "99"; height: "120"; }
+ ListElement{ longitude: "26"; latitude: "0"; height: "126"; }
+ ListElement{ longitude: "26"; latitude: "1"; height: "126"; }
+ ListElement{ longitude: "26"; latitude: "2"; height: "128"; }
+ ListElement{ longitude: "26"; latitude: "3"; height: "128"; }
+ ListElement{ longitude: "26"; latitude: "4"; height: "126"; }
+ ListElement{ longitude: "26"; latitude: "5"; height: "126"; }
+ ListElement{ longitude: "26"; latitude: "6"; height: "126"; }
+ ListElement{ longitude: "26"; latitude: "7"; height: "124"; }
+ ListElement{ longitude: "26"; latitude: "8"; height: "126"; }
+ ListElement{ longitude: "26"; latitude: "9"; height: "123"; }
+ ListElement{ longitude: "26"; latitude: "10"; height: "125"; }
+ ListElement{ longitude: "26"; latitude: "11"; height: "125"; }
+ ListElement{ longitude: "26"; latitude: "12"; height: "125"; }
+ ListElement{ longitude: "26"; latitude: "13"; height: "125"; }
+ ListElement{ longitude: "26"; latitude: "14"; height: "123"; }
+ ListElement{ longitude: "26"; latitude: "15"; height: "124"; }
+ ListElement{ longitude: "26"; latitude: "16"; height: "124"; }
+ ListElement{ longitude: "26"; latitude: "17"; height: "124"; }
+ ListElement{ longitude: "26"; latitude: "18"; height: "123"; }
+ ListElement{ longitude: "26"; latitude: "19"; height: "121"; }
+ ListElement{ longitude: "26"; latitude: "20"; height: "121"; }
+ ListElement{ longitude: "26"; latitude: "21"; height: "126"; }
+ ListElement{ longitude: "26"; latitude: "22"; height: "122"; }
+ ListElement{ longitude: "26"; latitude: "23"; height: "125"; }
+ ListElement{ longitude: "26"; latitude: "24"; height: "125"; }
+ ListElement{ longitude: "26"; latitude: "25"; height: "125"; }
+ ListElement{ longitude: "26"; latitude: "26"; height: "125"; }
+ ListElement{ longitude: "26"; latitude: "27"; height: "124"; }
+ ListElement{ longitude: "26"; latitude: "28"; height: "122"; }
+ ListElement{ longitude: "26"; latitude: "29"; height: "123"; }
+ ListElement{ longitude: "26"; latitude: "30"; height: "121"; }
+ ListElement{ longitude: "26"; latitude: "31"; height: "122"; }
+ ListElement{ longitude: "26"; latitude: "32"; height: "120"; }
+ ListElement{ longitude: "26"; latitude: "33"; height: "119"; }
+ ListElement{ longitude: "26"; latitude: "34"; height: "119"; }
+ ListElement{ longitude: "26"; latitude: "35"; height: "120"; }
+ ListElement{ longitude: "26"; latitude: "36"; height: "122"; }
+ ListElement{ longitude: "26"; latitude: "37"; height: "121"; }
+ ListElement{ longitude: "26"; latitude: "38"; height: "124"; }
+ ListElement{ longitude: "26"; latitude: "39"; height: "124"; }
+ ListElement{ longitude: "26"; latitude: "40"; height: "127"; }
+ ListElement{ longitude: "26"; latitude: "41"; height: "128"; }
+ ListElement{ longitude: "26"; latitude: "42"; height: "129"; }
+ ListElement{ longitude: "26"; latitude: "43"; height: "129"; }
+ ListElement{ longitude: "26"; latitude: "44"; height: "128"; }
+ ListElement{ longitude: "26"; latitude: "45"; height: "128"; }
+ ListElement{ longitude: "26"; latitude: "46"; height: "129"; }
+ ListElement{ longitude: "26"; latitude: "47"; height: "127"; }
+ ListElement{ longitude: "26"; latitude: "48"; height: "123"; }
+ ListElement{ longitude: "26"; latitude: "49"; height: "121"; }
+ ListElement{ longitude: "26"; latitude: "50"; height: "122"; }
+ ListElement{ longitude: "26"; latitude: "51"; height: "119"; }
+ ListElement{ longitude: "26"; latitude: "52"; height: "120"; }
+ ListElement{ longitude: "26"; latitude: "53"; height: "120"; }
+ ListElement{ longitude: "26"; latitude: "54"; height: "119"; }
+ ListElement{ longitude: "26"; latitude: "55"; height: "120"; }
+ ListElement{ longitude: "26"; latitude: "56"; height: "123"; }
+ ListElement{ longitude: "26"; latitude: "57"; height: "123"; }
+ ListElement{ longitude: "26"; latitude: "58"; height: "126"; }
+ ListElement{ longitude: "26"; latitude: "59"; height: "125"; }
+ ListElement{ longitude: "26"; latitude: "60"; height: "128"; }
+ ListElement{ longitude: "26"; latitude: "61"; height: "130"; }
+ ListElement{ longitude: "26"; latitude: "62"; height: "130"; }
+ ListElement{ longitude: "26"; latitude: "63"; height: "130"; }
+ ListElement{ longitude: "26"; latitude: "64"; height: "130"; }
+ ListElement{ longitude: "26"; latitude: "65"; height: "130"; }
+ ListElement{ longitude: "26"; latitude: "66"; height: "131"; }
+ ListElement{ longitude: "26"; latitude: "67"; height: "133"; }
+ ListElement{ longitude: "26"; latitude: "68"; height: "136"; }
+ ListElement{ longitude: "26"; latitude: "69"; height: "134"; }
+ ListElement{ longitude: "26"; latitude: "70"; height: "133"; }
+ ListElement{ longitude: "26"; latitude: "71"; height: "132"; }
+ ListElement{ longitude: "26"; latitude: "72"; height: "128"; }
+ ListElement{ longitude: "26"; latitude: "73"; height: "126"; }
+ ListElement{ longitude: "26"; latitude: "74"; height: "121"; }
+ ListElement{ longitude: "26"; latitude: "75"; height: "116"; }
+ ListElement{ longitude: "26"; latitude: "76"; height: "112"; }
+ ListElement{ longitude: "26"; latitude: "77"; height: "109"; }
+ ListElement{ longitude: "26"; latitude: "78"; height: "105"; }
+ ListElement{ longitude: "26"; latitude: "79"; height: "106"; }
+ ListElement{ longitude: "26"; latitude: "80"; height: "107"; }
+ ListElement{ longitude: "26"; latitude: "81"; height: "114"; }
+ ListElement{ longitude: "26"; latitude: "82"; height: "117"; }
+ ListElement{ longitude: "26"; latitude: "83"; height: "117"; }
+ ListElement{ longitude: "26"; latitude: "84"; height: "118"; }
+ ListElement{ longitude: "26"; latitude: "85"; height: "119"; }
+ ListElement{ longitude: "26"; latitude: "86"; height: "120"; }
+ ListElement{ longitude: "26"; latitude: "87"; height: "119"; }
+ ListElement{ longitude: "26"; latitude: "88"; height: "119"; }
+ ListElement{ longitude: "26"; latitude: "89"; height: "113"; }
+ ListElement{ longitude: "26"; latitude: "90"; height: "100"; }
+ ListElement{ longitude: "26"; latitude: "91"; height: "103"; }
+ ListElement{ longitude: "26"; latitude: "92"; height: "105"; }
+ ListElement{ longitude: "26"; latitude: "93"; height: "119"; }
+ ListElement{ longitude: "26"; latitude: "94"; height: "128"; }
+ ListElement{ longitude: "26"; latitude: "95"; height: "134"; }
+ ListElement{ longitude: "26"; latitude: "96"; height: "137"; }
+ ListElement{ longitude: "26"; latitude: "97"; height: "133"; }
+ ListElement{ longitude: "26"; latitude: "98"; height: "131"; }
+ ListElement{ longitude: "26"; latitude: "99"; height: "116"; }
+ ListElement{ longitude: "27"; latitude: "0"; height: "126"; }
+ ListElement{ longitude: "27"; latitude: "1"; height: "126"; }
+ ListElement{ longitude: "27"; latitude: "2"; height: "130"; }
+ ListElement{ longitude: "27"; latitude: "3"; height: "130"; }
+ ListElement{ longitude: "27"; latitude: "4"; height: "126"; }
+ ListElement{ longitude: "27"; latitude: "5"; height: "127"; }
+ ListElement{ longitude: "27"; latitude: "6"; height: "124"; }
+ ListElement{ longitude: "27"; latitude: "7"; height: "126"; }
+ ListElement{ longitude: "27"; latitude: "8"; height: "124"; }
+ ListElement{ longitude: "27"; latitude: "9"; height: "125"; }
+ ListElement{ longitude: "27"; latitude: "10"; height: "124"; }
+ ListElement{ longitude: "27"; latitude: "11"; height: "126"; }
+ ListElement{ longitude: "27"; latitude: "12"; height: "123"; }
+ ListElement{ longitude: "27"; latitude: "13"; height: "125"; }
+ ListElement{ longitude: "27"; latitude: "14"; height: "125"; }
+ ListElement{ longitude: "27"; latitude: "15"; height: "125"; }
+ ListElement{ longitude: "27"; latitude: "16"; height: "125"; }
+ ListElement{ longitude: "27"; latitude: "17"; height: "125"; }
+ ListElement{ longitude: "27"; latitude: "18"; height: "125"; }
+ ListElement{ longitude: "27"; latitude: "19"; height: "122"; }
+ ListElement{ longitude: "27"; latitude: "20"; height: "122"; }
+ ListElement{ longitude: "27"; latitude: "21"; height: "125"; }
+ ListElement{ longitude: "27"; latitude: "22"; height: "123"; }
+ ListElement{ longitude: "27"; latitude: "23"; height: "123"; }
+ ListElement{ longitude: "27"; latitude: "24"; height: "123"; }
+ ListElement{ longitude: "27"; latitude: "25"; height: "125"; }
+ ListElement{ longitude: "27"; latitude: "26"; height: "125"; }
+ ListElement{ longitude: "27"; latitude: "27"; height: "125"; }
+ ListElement{ longitude: "27"; latitude: "28"; height: "123"; }
+ ListElement{ longitude: "27"; latitude: "29"; height: "122"; }
+ ListElement{ longitude: "27"; latitude: "30"; height: "121"; }
+ ListElement{ longitude: "27"; latitude: "31"; height: "122"; }
+ ListElement{ longitude: "27"; latitude: "32"; height: "119"; }
+ ListElement{ longitude: "27"; latitude: "33"; height: "119"; }
+ ListElement{ longitude: "27"; latitude: "34"; height: "121"; }
+ ListElement{ longitude: "27"; latitude: "35"; height: "122"; }
+ ListElement{ longitude: "27"; latitude: "36"; height: "122"; }
+ ListElement{ longitude: "27"; latitude: "37"; height: "121"; }
+ ListElement{ longitude: "27"; latitude: "38"; height: "124"; }
+ ListElement{ longitude: "27"; latitude: "39"; height: "125"; }
+ ListElement{ longitude: "27"; latitude: "40"; height: "127"; }
+ ListElement{ longitude: "27"; latitude: "41"; height: "128"; }
+ ListElement{ longitude: "27"; latitude: "42"; height: "129"; }
+ ListElement{ longitude: "27"; latitude: "43"; height: "129"; }
+ ListElement{ longitude: "27"; latitude: "44"; height: "129"; }
+ ListElement{ longitude: "27"; latitude: "45"; height: "129"; }
+ ListElement{ longitude: "27"; latitude: "46"; height: "128"; }
+ ListElement{ longitude: "27"; latitude: "47"; height: "126"; }
+ ListElement{ longitude: "27"; latitude: "48"; height: "124"; }
+ ListElement{ longitude: "27"; latitude: "49"; height: "120"; }
+ ListElement{ longitude: "27"; latitude: "50"; height: "121"; }
+ ListElement{ longitude: "27"; latitude: "51"; height: "118"; }
+ ListElement{ longitude: "27"; latitude: "52"; height: "118"; }
+ ListElement{ longitude: "27"; latitude: "53"; height: "118"; }
+ ListElement{ longitude: "27"; latitude: "54"; height: "121"; }
+ ListElement{ longitude: "27"; latitude: "55"; height: "120"; }
+ ListElement{ longitude: "27"; latitude: "56"; height: "123"; }
+ ListElement{ longitude: "27"; latitude: "57"; height: "122"; }
+ ListElement{ longitude: "27"; latitude: "58"; height: "125"; }
+ ListElement{ longitude: "27"; latitude: "59"; height: "124"; }
+ ListElement{ longitude: "27"; latitude: "60"; height: "126"; }
+ ListElement{ longitude: "27"; latitude: "61"; height: "126"; }
+ ListElement{ longitude: "27"; latitude: "62"; height: "128"; }
+ ListElement{ longitude: "27"; latitude: "63"; height: "127"; }
+ ListElement{ longitude: "27"; latitude: "64"; height: "129"; }
+ ListElement{ longitude: "27"; latitude: "65"; height: "129"; }
+ ListElement{ longitude: "27"; latitude: "66"; height: "130"; }
+ ListElement{ longitude: "27"; latitude: "67"; height: "130"; }
+ ListElement{ longitude: "27"; latitude: "68"; height: "134"; }
+ ListElement{ longitude: "27"; latitude: "69"; height: "135"; }
+ ListElement{ longitude: "27"; latitude: "70"; height: "136"; }
+ ListElement{ longitude: "27"; latitude: "71"; height: "137"; }
+ ListElement{ longitude: "27"; latitude: "72"; height: "136"; }
+ ListElement{ longitude: "27"; latitude: "73"; height: "133"; }
+ ListElement{ longitude: "27"; latitude: "74"; height: "128"; }
+ ListElement{ longitude: "27"; latitude: "75"; height: "121"; }
+ ListElement{ longitude: "27"; latitude: "76"; height: "117"; }
+ ListElement{ longitude: "27"; latitude: "77"; height: "113"; }
+ ListElement{ longitude: "27"; latitude: "78"; height: "111"; }
+ ListElement{ longitude: "27"; latitude: "79"; height: "109"; }
+ ListElement{ longitude: "27"; latitude: "80"; height: "110"; }
+ ListElement{ longitude: "27"; latitude: "81"; height: "113"; }
+ ListElement{ longitude: "27"; latitude: "82"; height: "117"; }
+ ListElement{ longitude: "27"; latitude: "83"; height: "115"; }
+ ListElement{ longitude: "27"; latitude: "84"; height: "120"; }
+ ListElement{ longitude: "27"; latitude: "85"; height: "119"; }
+ ListElement{ longitude: "27"; latitude: "86"; height: "121"; }
+ ListElement{ longitude: "27"; latitude: "87"; height: "118"; }
+ ListElement{ longitude: "27"; latitude: "88"; height: "117"; }
+ ListElement{ longitude: "27"; latitude: "89"; height: "114"; }
+ ListElement{ longitude: "27"; latitude: "90"; height: "107"; }
+ ListElement{ longitude: "27"; latitude: "91"; height: "106"; }
+ ListElement{ longitude: "27"; latitude: "92"; height: "109"; }
+ ListElement{ longitude: "27"; latitude: "93"; height: "119"; }
+ ListElement{ longitude: "27"; latitude: "94"; height: "127"; }
+ ListElement{ longitude: "27"; latitude: "95"; height: "136"; }
+ ListElement{ longitude: "27"; latitude: "96"; height: "136"; }
+ ListElement{ longitude: "27"; latitude: "97"; height: "133"; }
+ ListElement{ longitude: "27"; latitude: "98"; height: "128"; }
+ ListElement{ longitude: "27"; latitude: "99"; height: "111"; }
+ ListElement{ longitude: "28"; latitude: "0"; height: "127"; }
+ ListElement{ longitude: "28"; latitude: "1"; height: "128"; }
+ ListElement{ longitude: "28"; latitude: "2"; height: "129"; }
+ ListElement{ longitude: "28"; latitude: "3"; height: "129"; }
+ ListElement{ longitude: "28"; latitude: "4"; height: "128"; }
+ ListElement{ longitude: "28"; latitude: "5"; height: "127"; }
+ ListElement{ longitude: "28"; latitude: "6"; height: "124"; }
+ ListElement{ longitude: "28"; latitude: "7"; height: "126"; }
+ ListElement{ longitude: "28"; latitude: "8"; height: "124"; }
+ ListElement{ longitude: "28"; latitude: "9"; height: "124"; }
+ ListElement{ longitude: "28"; latitude: "10"; height: "124"; }
+ ListElement{ longitude: "28"; latitude: "11"; height: "126"; }
+ ListElement{ longitude: "28"; latitude: "12"; height: "122"; }
+ ListElement{ longitude: "28"; latitude: "13"; height: "123"; }
+ ListElement{ longitude: "28"; latitude: "14"; height: "123"; }
+ ListElement{ longitude: "28"; latitude: "15"; height: "124"; }
+ ListElement{ longitude: "28"; latitude: "16"; height: "124"; }
+ ListElement{ longitude: "28"; latitude: "17"; height: "124"; }
+ ListElement{ longitude: "28"; latitude: "18"; height: "124"; }
+ ListElement{ longitude: "28"; latitude: "19"; height: "124"; }
+ ListElement{ longitude: "28"; latitude: "20"; height: "124"; }
+ ListElement{ longitude: "28"; latitude: "21"; height: "126"; }
+ ListElement{ longitude: "28"; latitude: "22"; height: "126"; }
+ ListElement{ longitude: "28"; latitude: "23"; height: "126"; }
+ ListElement{ longitude: "28"; latitude: "24"; height: "126"; }
+ ListElement{ longitude: "28"; latitude: "25"; height: "124"; }
+ ListElement{ longitude: "28"; latitude: "26"; height: "124"; }
+ ListElement{ longitude: "28"; latitude: "27"; height: "124"; }
+ ListElement{ longitude: "28"; latitude: "28"; height: "124"; }
+ ListElement{ longitude: "28"; latitude: "29"; height: "125"; }
+ ListElement{ longitude: "28"; latitude: "30"; height: "118"; }
+ ListElement{ longitude: "28"; latitude: "31"; height: "122"; }
+ ListElement{ longitude: "28"; latitude: "32"; height: "115"; }
+ ListElement{ longitude: "28"; latitude: "33"; height: "119"; }
+ ListElement{ longitude: "28"; latitude: "34"; height: "122"; }
+ ListElement{ longitude: "28"; latitude: "35"; height: "121"; }
+ ListElement{ longitude: "28"; latitude: "36"; height: "121"; }
+ ListElement{ longitude: "28"; latitude: "37"; height: "121"; }
+ ListElement{ longitude: "28"; latitude: "38"; height: "121"; }
+ ListElement{ longitude: "28"; latitude: "39"; height: "121"; }
+ ListElement{ longitude: "28"; latitude: "40"; height: "127"; }
+ ListElement{ longitude: "28"; latitude: "41"; height: "128"; }
+ ListElement{ longitude: "28"; latitude: "42"; height: "129"; }
+ ListElement{ longitude: "28"; latitude: "43"; height: "130"; }
+ ListElement{ longitude: "28"; latitude: "44"; height: "127"; }
+ ListElement{ longitude: "28"; latitude: "45"; height: "128"; }
+ ListElement{ longitude: "28"; latitude: "46"; height: "126"; }
+ ListElement{ longitude: "28"; latitude: "47"; height: "123"; }
+ ListElement{ longitude: "28"; latitude: "48"; height: "121"; }
+ ListElement{ longitude: "28"; latitude: "49"; height: "119"; }
+ ListElement{ longitude: "28"; latitude: "50"; height: "118"; }
+ ListElement{ longitude: "28"; latitude: "51"; height: "117"; }
+ ListElement{ longitude: "28"; latitude: "52"; height: "119"; }
+ ListElement{ longitude: "28"; latitude: "53"; height: "118"; }
+ ListElement{ longitude: "28"; latitude: "54"; height: "121"; }
+ ListElement{ longitude: "28"; latitude: "55"; height: "120"; }
+ ListElement{ longitude: "28"; latitude: "56"; height: "123"; }
+ ListElement{ longitude: "28"; latitude: "57"; height: "122"; }
+ ListElement{ longitude: "28"; latitude: "58"; height: "122"; }
+ ListElement{ longitude: "28"; latitude: "59"; height: "122"; }
+ ListElement{ longitude: "28"; latitude: "60"; height: "123"; }
+ ListElement{ longitude: "28"; latitude: "61"; height: "124"; }
+ ListElement{ longitude: "28"; latitude: "62"; height: "128"; }
+ ListElement{ longitude: "28"; latitude: "63"; height: "125"; }
+ ListElement{ longitude: "28"; latitude: "64"; height: "127"; }
+ ListElement{ longitude: "28"; latitude: "65"; height: "126"; }
+ ListElement{ longitude: "28"; latitude: "66"; height: "127"; }
+ ListElement{ longitude: "28"; latitude: "67"; height: "127"; }
+ ListElement{ longitude: "28"; latitude: "68"; height: "131"; }
+ ListElement{ longitude: "28"; latitude: "69"; height: "136"; }
+ ListElement{ longitude: "28"; latitude: "70"; height: "137"; }
+ ListElement{ longitude: "28"; latitude: "71"; height: "141"; }
+ ListElement{ longitude: "28"; latitude: "72"; height: "143"; }
+ ListElement{ longitude: "28"; latitude: "73"; height: "139"; }
+ ListElement{ longitude: "28"; latitude: "74"; height: "136"; }
+ ListElement{ longitude: "28"; latitude: "75"; height: "129"; }
+ ListElement{ longitude: "28"; latitude: "76"; height: "122"; }
+ ListElement{ longitude: "28"; latitude: "77"; height: "118"; }
+ ListElement{ longitude: "28"; latitude: "78"; height: "117"; }
+ ListElement{ longitude: "28"; latitude: "79"; height: "111"; }
+ ListElement{ longitude: "28"; latitude: "80"; height: "114"; }
+ ListElement{ longitude: "28"; latitude: "81"; height: "117"; }
+ ListElement{ longitude: "28"; latitude: "82"; height: "120"; }
+ ListElement{ longitude: "28"; latitude: "83"; height: "119"; }
+ ListElement{ longitude: "28"; latitude: "84"; height: "122"; }
+ ListElement{ longitude: "28"; latitude: "85"; height: "121"; }
+ ListElement{ longitude: "28"; latitude: "86"; height: "121"; }
+ ListElement{ longitude: "28"; latitude: "87"; height: "120"; }
+ ListElement{ longitude: "28"; latitude: "88"; height: "116"; }
+ ListElement{ longitude: "28"; latitude: "89"; height: "114"; }
+ ListElement{ longitude: "28"; latitude: "90"; height: "120"; }
+ ListElement{ longitude: "28"; latitude: "91"; height: "111"; }
+ ListElement{ longitude: "28"; latitude: "92"; height: "113"; }
+ ListElement{ longitude: "28"; latitude: "93"; height: "121"; }
+ ListElement{ longitude: "28"; latitude: "94"; height: "125"; }
+ ListElement{ longitude: "28"; latitude: "95"; height: "133"; }
+ ListElement{ longitude: "28"; latitude: "96"; height: "134"; }
+ ListElement{ longitude: "28"; latitude: "97"; height: "132"; }
+ ListElement{ longitude: "28"; latitude: "98"; height: "126"; }
+ ListElement{ longitude: "28"; latitude: "99"; height: "109"; }
+ ListElement{ longitude: "29"; latitude: "0"; height: "128"; }
+ ListElement{ longitude: "29"; latitude: "1"; height: "128"; }
+ ListElement{ longitude: "29"; latitude: "2"; height: "128"; }
+ ListElement{ longitude: "29"; latitude: "3"; height: "128"; }
+ ListElement{ longitude: "29"; latitude: "4"; height: "127"; }
+ ListElement{ longitude: "29"; latitude: "5"; height: "125"; }
+ ListElement{ longitude: "29"; latitude: "6"; height: "126"; }
+ ListElement{ longitude: "29"; latitude: "7"; height: "126"; }
+ ListElement{ longitude: "29"; latitude: "8"; height: "126"; }
+ ListElement{ longitude: "29"; latitude: "9"; height: "126"; }
+ ListElement{ longitude: "29"; latitude: "10"; height: "126"; }
+ ListElement{ longitude: "29"; latitude: "11"; height: "126"; }
+ ListElement{ longitude: "29"; latitude: "12"; height: "126"; }
+ ListElement{ longitude: "29"; latitude: "13"; height: "126"; }
+ ListElement{ longitude: "29"; latitude: "14"; height: "126"; }
+ ListElement{ longitude: "29"; latitude: "15"; height: "126"; }
+ ListElement{ longitude: "29"; latitude: "16"; height: "126"; }
+ ListElement{ longitude: "29"; latitude: "17"; height: "126"; }
+ ListElement{ longitude: "29"; latitude: "18"; height: "126"; }
+ ListElement{ longitude: "29"; latitude: "19"; height: "127"; }
+ ListElement{ longitude: "29"; latitude: "20"; height: "127"; }
+ ListElement{ longitude: "29"; latitude: "21"; height: "127"; }
+ ListElement{ longitude: "29"; latitude: "22"; height: "127"; }
+ ListElement{ longitude: "29"; latitude: "23"; height: "127"; }
+ ListElement{ longitude: "29"; latitude: "24"; height: "127"; }
+ ListElement{ longitude: "29"; latitude: "25"; height: "127"; }
+ ListElement{ longitude: "29"; latitude: "26"; height: "127"; }
+ ListElement{ longitude: "29"; latitude: "27"; height: "127"; }
+ ListElement{ longitude: "29"; latitude: "28"; height: "125"; }
+ ListElement{ longitude: "29"; latitude: "29"; height: "126"; }
+ ListElement{ longitude: "29"; latitude: "30"; height: "125"; }
+ ListElement{ longitude: "29"; latitude: "31"; height: "124"; }
+ ListElement{ longitude: "29"; latitude: "32"; height: "120"; }
+ ListElement{ longitude: "29"; latitude: "33"; height: "122"; }
+ ListElement{ longitude: "29"; latitude: "34"; height: "121"; }
+ ListElement{ longitude: "29"; latitude: "35"; height: "123"; }
+ ListElement{ longitude: "29"; latitude: "36"; height: "122"; }
+ ListElement{ longitude: "29"; latitude: "37"; height: "124"; }
+ ListElement{ longitude: "29"; latitude: "38"; height: "120"; }
+ ListElement{ longitude: "29"; latitude: "39"; height: "121"; }
+ ListElement{ longitude: "29"; latitude: "40"; height: "127"; }
+ ListElement{ longitude: "29"; latitude: "41"; height: "128"; }
+ ListElement{ longitude: "29"; latitude: "42"; height: "129"; }
+ ListElement{ longitude: "29"; latitude: "43"; height: "126"; }
+ ListElement{ longitude: "29"; latitude: "44"; height: "116"; }
+ ListElement{ longitude: "29"; latitude: "45"; height: "120"; }
+ ListElement{ longitude: "29"; latitude: "46"; height: "125"; }
+ ListElement{ longitude: "29"; latitude: "47"; height: "121"; }
+ ListElement{ longitude: "29"; latitude: "48"; height: "122"; }
+ ListElement{ longitude: "29"; latitude: "49"; height: "119"; }
+ ListElement{ longitude: "29"; latitude: "50"; height: "120"; }
+ ListElement{ longitude: "29"; latitude: "51"; height: "117"; }
+ ListElement{ longitude: "29"; latitude: "52"; height: "117"; }
+ ListElement{ longitude: "29"; latitude: "53"; height: "117"; }
+ ListElement{ longitude: "29"; latitude: "54"; height: "120"; }
+ ListElement{ longitude: "29"; latitude: "55"; height: "120"; }
+ ListElement{ longitude: "29"; latitude: "56"; height: "123"; }
+ ListElement{ longitude: "29"; latitude: "57"; height: "123"; }
+ ListElement{ longitude: "29"; latitude: "58"; height: "123"; }
+ ListElement{ longitude: "29"; latitude: "59"; height: "122"; }
+ ListElement{ longitude: "29"; latitude: "60"; height: "122"; }
+ ListElement{ longitude: "29"; latitude: "61"; height: "122"; }
+ ListElement{ longitude: "29"; latitude: "62"; height: "122"; }
+ ListElement{ longitude: "29"; latitude: "63"; height: "123"; }
+ ListElement{ longitude: "29"; latitude: "64"; height: "125"; }
+ ListElement{ longitude: "29"; latitude: "65"; height: "126"; }
+ ListElement{ longitude: "29"; latitude: "66"; height: "126"; }
+ ListElement{ longitude: "29"; latitude: "67"; height: "128"; }
+ ListElement{ longitude: "29"; latitude: "68"; height: "131"; }
+ ListElement{ longitude: "29"; latitude: "69"; height: "134"; }
+ ListElement{ longitude: "29"; latitude: "70"; height: "140"; }
+ ListElement{ longitude: "29"; latitude: "71"; height: "146"; }
+ ListElement{ longitude: "29"; latitude: "72"; height: "147"; }
+ ListElement{ longitude: "29"; latitude: "73"; height: "144"; }
+ ListElement{ longitude: "29"; latitude: "74"; height: "140"; }
+ ListElement{ longitude: "29"; latitude: "75"; height: "134"; }
+ ListElement{ longitude: "29"; latitude: "76"; height: "126"; }
+ ListElement{ longitude: "29"; latitude: "77"; height: "123"; }
+ ListElement{ longitude: "29"; latitude: "78"; height: "120"; }
+ ListElement{ longitude: "29"; latitude: "79"; height: "117"; }
+ ListElement{ longitude: "29"; latitude: "80"; height: "120"; }
+ ListElement{ longitude: "29"; latitude: "81"; height: "119"; }
+ ListElement{ longitude: "29"; latitude: "82"; height: "119"; }
+ ListElement{ longitude: "29"; latitude: "83"; height: "117"; }
+ ListElement{ longitude: "29"; latitude: "84"; height: "116"; }
+ ListElement{ longitude: "29"; latitude: "85"; height: "119"; }
+ ListElement{ longitude: "29"; latitude: "86"; height: "121"; }
+ ListElement{ longitude: "29"; latitude: "87"; height: "121"; }
+ ListElement{ longitude: "29"; latitude: "88"; height: "119"; }
+ ListElement{ longitude: "29"; latitude: "89"; height: "114"; }
+ ListElement{ longitude: "29"; latitude: "90"; height: "117"; }
+ ListElement{ longitude: "29"; latitude: "91"; height: "111"; }
+ ListElement{ longitude: "29"; latitude: "92"; height: "112"; }
+ ListElement{ longitude: "29"; latitude: "93"; height: "122"; }
+ ListElement{ longitude: "29"; latitude: "94"; height: "124"; }
+ ListElement{ longitude: "29"; latitude: "95"; height: "129"; }
+ ListElement{ longitude: "29"; latitude: "96"; height: "132"; }
+ ListElement{ longitude: "29"; latitude: "97"; height: "131"; }
+ ListElement{ longitude: "29"; latitude: "98"; height: "124"; }
+ ListElement{ longitude: "29"; latitude: "99"; height: "109"; }
+ ListElement{ longitude: "30"; latitude: "0"; height: "128"; }
+ ListElement{ longitude: "30"; latitude: "1"; height: "128"; }
+ ListElement{ longitude: "30"; latitude: "2"; height: "126"; }
+ ListElement{ longitude: "30"; latitude: "3"; height: "127"; }
+ ListElement{ longitude: "30"; latitude: "4"; height: "126"; }
+ ListElement{ longitude: "30"; latitude: "5"; height: "124"; }
+ ListElement{ longitude: "30"; latitude: "6"; height: "124"; }
+ ListElement{ longitude: "30"; latitude: "7"; height: "124"; }
+ ListElement{ longitude: "30"; latitude: "8"; height: "126"; }
+ ListElement{ longitude: "30"; latitude: "9"; height: "125"; }
+ ListElement{ longitude: "30"; latitude: "10"; height: "127"; }
+ ListElement{ longitude: "30"; latitude: "11"; height: "125"; }
+ ListElement{ longitude: "30"; latitude: "12"; height: "126"; }
+ ListElement{ longitude: "30"; latitude: "13"; height: "126"; }
+ ListElement{ longitude: "30"; latitude: "14"; height: "126"; }
+ ListElement{ longitude: "30"; latitude: "15"; height: "126"; }
+ ListElement{ longitude: "30"; latitude: "16"; height: "126"; }
+ ListElement{ longitude: "30"; latitude: "17"; height: "125"; }
+ ListElement{ longitude: "30"; latitude: "18"; height: "127"; }
+ ListElement{ longitude: "30"; latitude: "19"; height: "127"; }
+ ListElement{ longitude: "30"; latitude: "20"; height: "126"; }
+ ListElement{ longitude: "30"; latitude: "21"; height: "126"; }
+ ListElement{ longitude: "30"; latitude: "22"; height: "126"; }
+ ListElement{ longitude: "30"; latitude: "23"; height: "127"; }
+ ListElement{ longitude: "30"; latitude: "24"; height: "125"; }
+ ListElement{ longitude: "30"; latitude: "25"; height: "127"; }
+ ListElement{ longitude: "30"; latitude: "26"; height: "127"; }
+ ListElement{ longitude: "30"; latitude: "27"; height: "127"; }
+ ListElement{ longitude: "30"; latitude: "28"; height: "127"; }
+ ListElement{ longitude: "30"; latitude: "29"; height: "127"; }
+ ListElement{ longitude: "30"; latitude: "30"; height: "126"; }
+ ListElement{ longitude: "30"; latitude: "31"; height: "127"; }
+ ListElement{ longitude: "30"; latitude: "32"; height: "124"; }
+ ListElement{ longitude: "30"; latitude: "33"; height: "120"; }
+ ListElement{ longitude: "30"; latitude: "34"; height: "124"; }
+ ListElement{ longitude: "30"; latitude: "35"; height: "123"; }
+ ListElement{ longitude: "30"; latitude: "36"; height: "125"; }
+ ListElement{ longitude: "30"; latitude: "37"; height: "125"; }
+ ListElement{ longitude: "30"; latitude: "38"; height: "125"; }
+ ListElement{ longitude: "30"; latitude: "39"; height: "124"; }
+ ListElement{ longitude: "30"; latitude: "40"; height: "127"; }
+ ListElement{ longitude: "30"; latitude: "41"; height: "128"; }
+ ListElement{ longitude: "30"; latitude: "42"; height: "128"; }
+ ListElement{ longitude: "30"; latitude: "43"; height: "114"; }
+ ListElement{ longitude: "30"; latitude: "44"; height: "105"; }
+ ListElement{ longitude: "30"; latitude: "45"; height: "114"; }
+ ListElement{ longitude: "30"; latitude: "46"; height: "121"; }
+ ListElement{ longitude: "30"; latitude: "47"; height: "119"; }
+ ListElement{ longitude: "30"; latitude: "48"; height: "120"; }
+ ListElement{ longitude: "30"; latitude: "49"; height: "120"; }
+ ListElement{ longitude: "30"; latitude: "50"; height: "118"; }
+ ListElement{ longitude: "30"; latitude: "51"; height: "119"; }
+ ListElement{ longitude: "30"; latitude: "52"; height: "119"; }
+ ListElement{ longitude: "30"; latitude: "53"; height: "116"; }
+ ListElement{ longitude: "30"; latitude: "54"; height: "119"; }
+ ListElement{ longitude: "30"; latitude: "55"; height: "120"; }
+ ListElement{ longitude: "30"; latitude: "56"; height: "123"; }
+ ListElement{ longitude: "30"; latitude: "57"; height: "122"; }
+ ListElement{ longitude: "30"; latitude: "58"; height: "122"; }
+ ListElement{ longitude: "30"; latitude: "59"; height: "122"; }
+ ListElement{ longitude: "30"; latitude: "60"; height: "123"; }
+ ListElement{ longitude: "30"; latitude: "61"; height: "121"; }
+ ListElement{ longitude: "30"; latitude: "62"; height: "121"; }
+ ListElement{ longitude: "30"; latitude: "63"; height: "121"; }
+ ListElement{ longitude: "30"; latitude: "64"; height: "122"; }
+ ListElement{ longitude: "30"; latitude: "65"; height: "124"; }
+ ListElement{ longitude: "30"; latitude: "66"; height: "125"; }
+ ListElement{ longitude: "30"; latitude: "67"; height: "128"; }
+ ListElement{ longitude: "30"; latitude: "68"; height: "133"; }
+ ListElement{ longitude: "30"; latitude: "69"; height: "135"; }
+ ListElement{ longitude: "30"; latitude: "70"; height: "142"; }
+ ListElement{ longitude: "30"; latitude: "71"; height: "146"; }
+ ListElement{ longitude: "30"; latitude: "72"; height: "150"; }
+ ListElement{ longitude: "30"; latitude: "73"; height: "149"; }
+ ListElement{ longitude: "30"; latitude: "74"; height: "147"; }
+ ListElement{ longitude: "30"; latitude: "75"; height: "137"; }
+ ListElement{ longitude: "30"; latitude: "76"; height: "130"; }
+ ListElement{ longitude: "30"; latitude: "77"; height: "124"; }
+ ListElement{ longitude: "30"; latitude: "78"; height: "121"; }
+ ListElement{ longitude: "30"; latitude: "79"; height: "121"; }
+ ListElement{ longitude: "30"; latitude: "80"; height: "119"; }
+ ListElement{ longitude: "30"; latitude: "81"; height: "117"; }
+ ListElement{ longitude: "30"; latitude: "82"; height: "119"; }
+ ListElement{ longitude: "30"; latitude: "83"; height: "115"; }
+ ListElement{ longitude: "30"; latitude: "84"; height: "121"; }
+ ListElement{ longitude: "30"; latitude: "85"; height: "122"; }
+ ListElement{ longitude: "30"; latitude: "86"; height: "119"; }
+ ListElement{ longitude: "30"; latitude: "87"; height: "121"; }
+ ListElement{ longitude: "30"; latitude: "88"; height: "120"; }
+ ListElement{ longitude: "30"; latitude: "89"; height: "117"; }
+ ListElement{ longitude: "30"; latitude: "90"; height: "119"; }
+ ListElement{ longitude: "30"; latitude: "91"; height: "118"; }
+ ListElement{ longitude: "30"; latitude: "92"; height: "119"; }
+ ListElement{ longitude: "30"; latitude: "93"; height: "128"; }
+ ListElement{ longitude: "30"; latitude: "94"; height: "127"; }
+ ListElement{ longitude: "30"; latitude: "95"; height: "124"; }
+ ListElement{ longitude: "30"; latitude: "96"; height: "123"; }
+ ListElement{ longitude: "30"; latitude: "97"; height: "133"; }
+ ListElement{ longitude: "30"; latitude: "98"; height: "128"; }
+ ListElement{ longitude: "30"; latitude: "99"; height: "111"; }
+ ListElement{ longitude: "31"; latitude: "0"; height: "128"; }
+ ListElement{ longitude: "31"; latitude: "1"; height: "128"; }
+ ListElement{ longitude: "31"; latitude: "2"; height: "127"; }
+ ListElement{ longitude: "31"; latitude: "3"; height: "126"; }
+ ListElement{ longitude: "31"; latitude: "4"; height: "123"; }
+ ListElement{ longitude: "31"; latitude: "5"; height: "125"; }
+ ListElement{ longitude: "31"; latitude: "6"; height: "125"; }
+ ListElement{ longitude: "31"; latitude: "7"; height: "124"; }
+ ListElement{ longitude: "31"; latitude: "8"; height: "126"; }
+ ListElement{ longitude: "31"; latitude: "9"; height: "125"; }
+ ListElement{ longitude: "31"; latitude: "10"; height: "127"; }
+ ListElement{ longitude: "31"; latitude: "11"; height: "125"; }
+ ListElement{ longitude: "31"; latitude: "12"; height: "126"; }
+ ListElement{ longitude: "31"; latitude: "13"; height: "126"; }
+ ListElement{ longitude: "31"; latitude: "14"; height: "123"; }
+ ListElement{ longitude: "31"; latitude: "15"; height: "124"; }
+ ListElement{ longitude: "31"; latitude: "16"; height: "126"; }
+ ListElement{ longitude: "31"; latitude: "17"; height: "125"; }
+ ListElement{ longitude: "31"; latitude: "18"; height: "127"; }
+ ListElement{ longitude: "31"; latitude: "19"; height: "126"; }
+ ListElement{ longitude: "31"; latitude: "20"; height: "128"; }
+ ListElement{ longitude: "31"; latitude: "21"; height: "129"; }
+ ListElement{ longitude: "31"; latitude: "22"; height: "128"; }
+ ListElement{ longitude: "31"; latitude: "23"; height: "125"; }
+ ListElement{ longitude: "31"; latitude: "24"; height: "125"; }
+ ListElement{ longitude: "31"; latitude: "25"; height: "125"; }
+ ListElement{ longitude: "31"; latitude: "26"; height: "125"; }
+ ListElement{ longitude: "31"; latitude: "27"; height: "127"; }
+ ListElement{ longitude: "31"; latitude: "28"; height: "127"; }
+ ListElement{ longitude: "31"; latitude: "29"; height: "127"; }
+ ListElement{ longitude: "31"; latitude: "30"; height: "125"; }
+ ListElement{ longitude: "31"; latitude: "31"; height: "126"; }
+ ListElement{ longitude: "31"; latitude: "32"; height: "124"; }
+ ListElement{ longitude: "31"; latitude: "33"; height: "123"; }
+ ListElement{ longitude: "31"; latitude: "34"; height: "126"; }
+ ListElement{ longitude: "31"; latitude: "35"; height: "126"; }
+ ListElement{ longitude: "31"; latitude: "36"; height: "124"; }
+ ListElement{ longitude: "31"; latitude: "37"; height: "125"; }
+ ListElement{ longitude: "31"; latitude: "38"; height: "125"; }
+ ListElement{ longitude: "31"; latitude: "39"; height: "124"; }
+ ListElement{ longitude: "31"; latitude: "40"; height: "127"; }
+ ListElement{ longitude: "31"; latitude: "41"; height: "125"; }
+ ListElement{ longitude: "31"; latitude: "42"; height: "127"; }
+ ListElement{ longitude: "31"; latitude: "43"; height: "118"; }
+ ListElement{ longitude: "31"; latitude: "44"; height: "116"; }
+ ListElement{ longitude: "31"; latitude: "45"; height: "124"; }
+ ListElement{ longitude: "31"; latitude: "46"; height: "120"; }
+ ListElement{ longitude: "31"; latitude: "47"; height: "116"; }
+ ListElement{ longitude: "31"; latitude: "48"; height: "117"; }
+ ListElement{ longitude: "31"; latitude: "49"; height: "117"; }
+ ListElement{ longitude: "31"; latitude: "50"; height: "119"; }
+ ListElement{ longitude: "31"; latitude: "51"; height: "119"; }
+ ListElement{ longitude: "31"; latitude: "52"; height: "118"; }
+ ListElement{ longitude: "31"; latitude: "53"; height: "120"; }
+ ListElement{ longitude: "31"; latitude: "54"; height: "121"; }
+ ListElement{ longitude: "31"; latitude: "55"; height: "121"; }
+ ListElement{ longitude: "31"; latitude: "56"; height: "122"; }
+ ListElement{ longitude: "31"; latitude: "57"; height: "125"; }
+ ListElement{ longitude: "31"; latitude: "58"; height: "125"; }
+ ListElement{ longitude: "31"; latitude: "59"; height: "124"; }
+ ListElement{ longitude: "31"; latitude: "60"; height: "122"; }
+ ListElement{ longitude: "31"; latitude: "61"; height: "121"; }
+ ListElement{ longitude: "31"; latitude: "62"; height: "121"; }
+ ListElement{ longitude: "31"; latitude: "63"; height: "121"; }
+ ListElement{ longitude: "31"; latitude: "64"; height: "122"; }
+ ListElement{ longitude: "31"; latitude: "65"; height: "124"; }
+ ListElement{ longitude: "31"; latitude: "66"; height: "126"; }
+ ListElement{ longitude: "31"; latitude: "67"; height: "129"; }
+ ListElement{ longitude: "31"; latitude: "68"; height: "133"; }
+ ListElement{ longitude: "31"; latitude: "69"; height: "137"; }
+ ListElement{ longitude: "31"; latitude: "70"; height: "143"; }
+ ListElement{ longitude: "31"; latitude: "71"; height: "147"; }
+ ListElement{ longitude: "31"; latitude: "72"; height: "149"; }
+ ListElement{ longitude: "31"; latitude: "73"; height: "148"; }
+ ListElement{ longitude: "31"; latitude: "74"; height: "146"; }
+ ListElement{ longitude: "31"; latitude: "75"; height: "138"; }
+ ListElement{ longitude: "31"; latitude: "76"; height: "130"; }
+ ListElement{ longitude: "31"; latitude: "77"; height: "123"; }
+ ListElement{ longitude: "31"; latitude: "78"; height: "124"; }
+ ListElement{ longitude: "31"; latitude: "79"; height: "122"; }
+ ListElement{ longitude: "31"; latitude: "80"; height: "116"; }
+ ListElement{ longitude: "31"; latitude: "81"; height: "115"; }
+ ListElement{ longitude: "31"; latitude: "82"; height: "119"; }
+ ListElement{ longitude: "31"; latitude: "83"; height: "117"; }
+ ListElement{ longitude: "31"; latitude: "84"; height: "117"; }
+ ListElement{ longitude: "31"; latitude: "85"; height: "116"; }
+ ListElement{ longitude: "31"; latitude: "86"; height: "119"; }
+ ListElement{ longitude: "31"; latitude: "87"; height: "119"; }
+ ListElement{ longitude: "31"; latitude: "88"; height: "119"; }
+ ListElement{ longitude: "31"; latitude: "89"; height: "120"; }
+ ListElement{ longitude: "31"; latitude: "90"; height: "120"; }
+ ListElement{ longitude: "31"; latitude: "91"; height: "123"; }
+ ListElement{ longitude: "31"; latitude: "92"; height: "124"; }
+ ListElement{ longitude: "31"; latitude: "93"; height: "123"; }
+ ListElement{ longitude: "31"; latitude: "94"; height: "123"; }
+ ListElement{ longitude: "31"; latitude: "95"; height: "122"; }
+ ListElement{ longitude: "31"; latitude: "96"; height: "114"; }
+ ListElement{ longitude: "31"; latitude: "97"; height: "125"; }
+ ListElement{ longitude: "31"; latitude: "98"; height: "127"; }
+ ListElement{ longitude: "31"; latitude: "99"; height: "115"; }
+ ListElement{ longitude: "32"; latitude: "0"; height: "128"; }
+ ListElement{ longitude: "32"; latitude: "1"; height: "127"; }
+ ListElement{ longitude: "32"; latitude: "2"; height: "128"; }
+ ListElement{ longitude: "32"; latitude: "3"; height: "123"; }
+ ListElement{ longitude: "32"; latitude: "4"; height: "122"; }
+ ListElement{ longitude: "32"; latitude: "5"; height: "125"; }
+ ListElement{ longitude: "32"; latitude: "6"; height: "125"; }
+ ListElement{ longitude: "32"; latitude: "7"; height: "124"; }
+ ListElement{ longitude: "32"; latitude: "8"; height: "126"; }
+ ListElement{ longitude: "32"; latitude: "9"; height: "127"; }
+ ListElement{ longitude: "32"; latitude: "10"; height: "128"; }
+ ListElement{ longitude: "32"; latitude: "11"; height: "126"; }
+ ListElement{ longitude: "32"; latitude: "12"; height: "127"; }
+ ListElement{ longitude: "32"; latitude: "13"; height: "122"; }
+ ListElement{ longitude: "32"; latitude: "14"; height: "121"; }
+ ListElement{ longitude: "32"; latitude: "15"; height: "124"; }
+ ListElement{ longitude: "32"; latitude: "16"; height: "126"; }
+ ListElement{ longitude: "32"; latitude: "17"; height: "125"; }
+ ListElement{ longitude: "32"; latitude: "18"; height: "127"; }
+ ListElement{ longitude: "32"; latitude: "19"; height: "128"; }
+ ListElement{ longitude: "32"; latitude: "20"; height: "127"; }
+ ListElement{ longitude: "32"; latitude: "21"; height: "129"; }
+ ListElement{ longitude: "32"; latitude: "22"; height: "129"; }
+ ListElement{ longitude: "32"; latitude: "23"; height: "126"; }
+ ListElement{ longitude: "32"; latitude: "24"; height: "127"; }
+ ListElement{ longitude: "32"; latitude: "25"; height: "125"; }
+ ListElement{ longitude: "32"; latitude: "26"; height: "125"; }
+ ListElement{ longitude: "32"; latitude: "27"; height: "127"; }
+ ListElement{ longitude: "32"; latitude: "28"; height: "127"; }
+ ListElement{ longitude: "32"; latitude: "29"; height: "127"; }
+ ListElement{ longitude: "32"; latitude: "30"; height: "127"; }
+ ListElement{ longitude: "32"; latitude: "31"; height: "127"; }
+ ListElement{ longitude: "32"; latitude: "32"; height: "125"; }
+ ListElement{ longitude: "32"; latitude: "33"; height: "125"; }
+ ListElement{ longitude: "32"; latitude: "34"; height: "127"; }
+ ListElement{ longitude: "32"; latitude: "35"; height: "127"; }
+ ListElement{ longitude: "32"; latitude: "36"; height: "124"; }
+ ListElement{ longitude: "32"; latitude: "37"; height: "124"; }
+ ListElement{ longitude: "32"; latitude: "38"; height: "124"; }
+ ListElement{ longitude: "32"; latitude: "39"; height: "124"; }
+ ListElement{ longitude: "32"; latitude: "40"; height: "127"; }
+ ListElement{ longitude: "32"; latitude: "41"; height: "125"; }
+ ListElement{ longitude: "32"; latitude: "42"; height: "126"; }
+ ListElement{ longitude: "32"; latitude: "43"; height: "126"; }
+ ListElement{ longitude: "32"; latitude: "44"; height: "123"; }
+ ListElement{ longitude: "32"; latitude: "45"; height: "122"; }
+ ListElement{ longitude: "32"; latitude: "46"; height: "121"; }
+ ListElement{ longitude: "32"; latitude: "47"; height: "118"; }
+ ListElement{ longitude: "32"; latitude: "48"; height: "119"; }
+ ListElement{ longitude: "32"; latitude: "49"; height: "119"; }
+ ListElement{ longitude: "32"; latitude: "50"; height: "119"; }
+ ListElement{ longitude: "32"; latitude: "51"; height: "119"; }
+ ListElement{ longitude: "32"; latitude: "52"; height: "118"; }
+ ListElement{ longitude: "32"; latitude: "53"; height: "119"; }
+ ListElement{ longitude: "32"; latitude: "54"; height: "122"; }
+ ListElement{ longitude: "32"; latitude: "55"; height: "121"; }
+ ListElement{ longitude: "32"; latitude: "56"; height: "125"; }
+ ListElement{ longitude: "32"; latitude: "57"; height: "126"; }
+ ListElement{ longitude: "32"; latitude: "58"; height: "126"; }
+ ListElement{ longitude: "32"; latitude: "59"; height: "125"; }
+ ListElement{ longitude: "32"; latitude: "60"; height: "122"; }
+ ListElement{ longitude: "32"; latitude: "61"; height: "123"; }
+ ListElement{ longitude: "32"; latitude: "62"; height: "123"; }
+ ListElement{ longitude: "32"; latitude: "63"; height: "123"; }
+ ListElement{ longitude: "32"; latitude: "64"; height: "122"; }
+ ListElement{ longitude: "32"; latitude: "65"; height: "126"; }
+ ListElement{ longitude: "32"; latitude: "66"; height: "127"; }
+ ListElement{ longitude: "32"; latitude: "67"; height: "131"; }
+ ListElement{ longitude: "32"; latitude: "68"; height: "137"; }
+ ListElement{ longitude: "32"; latitude: "69"; height: "141"; }
+ ListElement{ longitude: "32"; latitude: "70"; height: "145"; }
+ ListElement{ longitude: "32"; latitude: "71"; height: "148"; }
+ ListElement{ longitude: "32"; latitude: "72"; height: "151"; }
+ ListElement{ longitude: "32"; latitude: "73"; height: "148"; }
+ ListElement{ longitude: "32"; latitude: "74"; height: "144"; }
+ ListElement{ longitude: "32"; latitude: "75"; height: "138"; }
+ ListElement{ longitude: "32"; latitude: "76"; height: "130"; }
+ ListElement{ longitude: "32"; latitude: "77"; height: "124"; }
+ ListElement{ longitude: "32"; latitude: "78"; height: "126"; }
+ ListElement{ longitude: "32"; latitude: "79"; height: "124"; }
+ ListElement{ longitude: "32"; latitude: "80"; height: "120"; }
+ ListElement{ longitude: "32"; latitude: "81"; height: "119"; }
+ ListElement{ longitude: "32"; latitude: "82"; height: "120"; }
+ ListElement{ longitude: "32"; latitude: "83"; height: "119"; }
+ ListElement{ longitude: "32"; latitude: "84"; height: "117"; }
+ ListElement{ longitude: "32"; latitude: "85"; height: "122"; }
+ ListElement{ longitude: "32"; latitude: "86"; height: "123"; }
+ ListElement{ longitude: "32"; latitude: "87"; height: "121"; }
+ ListElement{ longitude: "32"; latitude: "88"; height: "122"; }
+ ListElement{ longitude: "32"; latitude: "89"; height: "125"; }
+ ListElement{ longitude: "32"; latitude: "90"; height: "126"; }
+ ListElement{ longitude: "32"; latitude: "91"; height: "129"; }
+ ListElement{ longitude: "32"; latitude: "92"; height: "127"; }
+ ListElement{ longitude: "32"; latitude: "93"; height: "125"; }
+ ListElement{ longitude: "32"; latitude: "94"; height: "123"; }
+ ListElement{ longitude: "32"; latitude: "95"; height: "126"; }
+ ListElement{ longitude: "32"; latitude: "96"; height: "122"; }
+ ListElement{ longitude: "32"; latitude: "97"; height: "119"; }
+ ListElement{ longitude: "32"; latitude: "98"; height: "126"; }
+ ListElement{ longitude: "32"; latitude: "99"; height: "120"; }
+ ListElement{ longitude: "33"; latitude: "0"; height: "127"; }
+ ListElement{ longitude: "33"; latitude: "1"; height: "125"; }
+ ListElement{ longitude: "33"; latitude: "2"; height: "125"; }
+ ListElement{ longitude: "33"; latitude: "3"; height: "116"; }
+ ListElement{ longitude: "33"; latitude: "4"; height: "120"; }
+ ListElement{ longitude: "33"; latitude: "5"; height: "125"; }
+ ListElement{ longitude: "33"; latitude: "6"; height: "125"; }
+ ListElement{ longitude: "33"; latitude: "7"; height: "124"; }
+ ListElement{ longitude: "33"; latitude: "8"; height: "124"; }
+ ListElement{ longitude: "33"; latitude: "9"; height: "125"; }
+ ListElement{ longitude: "33"; latitude: "10"; height: "130"; }
+ ListElement{ longitude: "33"; latitude: "11"; height: "127"; }
+ ListElement{ longitude: "33"; latitude: "12"; height: "128"; }
+ ListElement{ longitude: "33"; latitude: "13"; height: "123"; }
+ ListElement{ longitude: "33"; latitude: "14"; height: "126"; }
+ ListElement{ longitude: "33"; latitude: "15"; height: "126"; }
+ ListElement{ longitude: "33"; latitude: "16"; height: "125"; }
+ ListElement{ longitude: "33"; latitude: "17"; height: "125"; }
+ ListElement{ longitude: "33"; latitude: "18"; height: "126"; }
+ ListElement{ longitude: "33"; latitude: "19"; height: "128"; }
+ ListElement{ longitude: "33"; latitude: "20"; height: "127"; }
+ ListElement{ longitude: "33"; latitude: "21"; height: "129"; }
+ ListElement{ longitude: "33"; latitude: "22"; height: "129"; }
+ ListElement{ longitude: "33"; latitude: "23"; height: "126"; }
+ ListElement{ longitude: "33"; latitude: "24"; height: "127"; }
+ ListElement{ longitude: "33"; latitude: "25"; height: "125"; }
+ ListElement{ longitude: "33"; latitude: "26"; height: "125"; }
+ ListElement{ longitude: "33"; latitude: "27"; height: "127"; }
+ ListElement{ longitude: "33"; latitude: "28"; height: "127"; }
+ ListElement{ longitude: "33"; latitude: "29"; height: "127"; }
+ ListElement{ longitude: "33"; latitude: "30"; height: "127"; }
+ ListElement{ longitude: "33"; latitude: "31"; height: "127"; }
+ ListElement{ longitude: "33"; latitude: "32"; height: "127"; }
+ ListElement{ longitude: "33"; latitude: "33"; height: "127"; }
+ ListElement{ longitude: "33"; latitude: "34"; height: "128"; }
+ ListElement{ longitude: "33"; latitude: "35"; height: "127"; }
+ ListElement{ longitude: "33"; latitude: "36"; height: "124"; }
+ ListElement{ longitude: "33"; latitude: "37"; height: "126"; }
+ ListElement{ longitude: "33"; latitude: "38"; height: "125"; }
+ ListElement{ longitude: "33"; latitude: "39"; height: "124"; }
+ ListElement{ longitude: "33"; latitude: "40"; height: "127"; }
+ ListElement{ longitude: "33"; latitude: "41"; height: "125"; }
+ ListElement{ longitude: "33"; latitude: "42"; height: "124"; }
+ ListElement{ longitude: "33"; latitude: "43"; height: "125"; }
+ ListElement{ longitude: "33"; latitude: "44"; height: "124"; }
+ ListElement{ longitude: "33"; latitude: "45"; height: "123"; }
+ ListElement{ longitude: "33"; latitude: "46"; height: "122"; }
+ ListElement{ longitude: "33"; latitude: "47"; height: "119"; }
+ ListElement{ longitude: "33"; latitude: "48"; height: "118"; }
+ ListElement{ longitude: "33"; latitude: "49"; height: "118"; }
+ ListElement{ longitude: "33"; latitude: "50"; height: "119"; }
+ ListElement{ longitude: "33"; latitude: "51"; height: "119"; }
+ ListElement{ longitude: "33"; latitude: "52"; height: "118"; }
+ ListElement{ longitude: "33"; latitude: "53"; height: "119"; }
+ ListElement{ longitude: "33"; latitude: "54"; height: "122"; }
+ ListElement{ longitude: "33"; latitude: "55"; height: "124"; }
+ ListElement{ longitude: "33"; latitude: "56"; height: "126"; }
+ ListElement{ longitude: "33"; latitude: "57"; height: "127"; }
+ ListElement{ longitude: "33"; latitude: "58"; height: "127"; }
+ ListElement{ longitude: "33"; latitude: "59"; height: "126"; }
+ ListElement{ longitude: "33"; latitude: "60"; height: "125"; }
+ ListElement{ longitude: "33"; latitude: "61"; height: "122"; }
+ ListElement{ longitude: "33"; latitude: "62"; height: "122"; }
+ ListElement{ longitude: "33"; latitude: "63"; height: "122"; }
+ ListElement{ longitude: "33"; latitude: "64"; height: "123"; }
+ ListElement{ longitude: "33"; latitude: "65"; height: "127"; }
+ ListElement{ longitude: "33"; latitude: "66"; height: "130"; }
+ ListElement{ longitude: "33"; latitude: "67"; height: "133"; }
+ ListElement{ longitude: "33"; latitude: "68"; height: "141"; }
+ ListElement{ longitude: "33"; latitude: "69"; height: "144"; }
+ ListElement{ longitude: "33"; latitude: "70"; height: "147"; }
+ ListElement{ longitude: "33"; latitude: "71"; height: "149"; }
+ ListElement{ longitude: "33"; latitude: "72"; height: "149"; }
+ ListElement{ longitude: "33"; latitude: "73"; height: "147"; }
+ ListElement{ longitude: "33"; latitude: "74"; height: "144"; }
+ ListElement{ longitude: "33"; latitude: "75"; height: "137"; }
+ ListElement{ longitude: "33"; latitude: "76"; height: "123"; }
+ ListElement{ longitude: "33"; latitude: "77"; height: "124"; }
+ ListElement{ longitude: "33"; latitude: "78"; height: "128"; }
+ ListElement{ longitude: "33"; latitude: "79"; height: "122"; }
+ ListElement{ longitude: "33"; latitude: "80"; height: "127"; }
+ ListElement{ longitude: "33"; latitude: "81"; height: "121"; }
+ ListElement{ longitude: "33"; latitude: "82"; height: "123"; }
+ ListElement{ longitude: "33"; latitude: "83"; height: "118"; }
+ ListElement{ longitude: "33"; latitude: "84"; height: "113"; }
+ ListElement{ longitude: "33"; latitude: "85"; height: "117"; }
+ ListElement{ longitude: "33"; latitude: "86"; height: "118"; }
+ ListElement{ longitude: "33"; latitude: "87"; height: "121"; }
+ ListElement{ longitude: "33"; latitude: "88"; height: "120"; }
+ ListElement{ longitude: "33"; latitude: "89"; height: "127"; }
+ ListElement{ longitude: "33"; latitude: "90"; height: "122"; }
+ ListElement{ longitude: "33"; latitude: "91"; height: "121"; }
+ ListElement{ longitude: "33"; latitude: "92"; height: "123"; }
+ ListElement{ longitude: "33"; latitude: "93"; height: "123"; }
+ ListElement{ longitude: "33"; latitude: "94"; height: "125"; }
+ ListElement{ longitude: "33"; latitude: "95"; height: "127"; }
+ ListElement{ longitude: "33"; latitude: "96"; height: "127"; }
+ ListElement{ longitude: "33"; latitude: "97"; height: "124"; }
+ ListElement{ longitude: "33"; latitude: "98"; height: "132"; }
+ ListElement{ longitude: "33"; latitude: "99"; height: "122"; }
+ ListElement{ longitude: "34"; latitude: "0"; height: "126"; }
+ ListElement{ longitude: "34"; latitude: "1"; height: "125"; }
+ ListElement{ longitude: "34"; latitude: "2"; height: "124"; }
+ ListElement{ longitude: "34"; latitude: "3"; height: "123"; }
+ ListElement{ longitude: "34"; latitude: "4"; height: "125"; }
+ ListElement{ longitude: "34"; latitude: "5"; height: "125"; }
+ ListElement{ longitude: "34"; latitude: "6"; height: "124"; }
+ ListElement{ longitude: "34"; latitude: "7"; height: "124"; }
+ ListElement{ longitude: "34"; latitude: "8"; height: "125"; }
+ ListElement{ longitude: "34"; latitude: "9"; height: "124"; }
+ ListElement{ longitude: "34"; latitude: "10"; height: "131"; }
+ ListElement{ longitude: "34"; latitude: "11"; height: "130"; }
+ ListElement{ longitude: "34"; latitude: "12"; height: "129"; }
+ ListElement{ longitude: "34"; latitude: "13"; height: "130"; }
+ ListElement{ longitude: "34"; latitude: "14"; height: "126"; }
+ ListElement{ longitude: "34"; latitude: "15"; height: "127"; }
+ ListElement{ longitude: "34"; latitude: "16"; height: "127"; }
+ ListElement{ longitude: "34"; latitude: "17"; height: "127"; }
+ ListElement{ longitude: "34"; latitude: "18"; height: "128"; }
+ ListElement{ longitude: "34"; latitude: "19"; height: "129"; }
+ ListElement{ longitude: "34"; latitude: "20"; height: "129"; }
+ ListElement{ longitude: "34"; latitude: "21"; height: "129"; }
+ ListElement{ longitude: "34"; latitude: "22"; height: "129"; }
+ ListElement{ longitude: "34"; latitude: "23"; height: "126"; }
+ ListElement{ longitude: "34"; latitude: "24"; height: "126"; }
+ ListElement{ longitude: "34"; latitude: "25"; height: "127"; }
+ ListElement{ longitude: "34"; latitude: "26"; height: "127"; }
+ ListElement{ longitude: "34"; latitude: "27"; height: "127"; }
+ ListElement{ longitude: "34"; latitude: "28"; height: "127"; }
+ ListElement{ longitude: "34"; latitude: "29"; height: "127"; }
+ ListElement{ longitude: "34"; latitude: "30"; height: "126"; }
+ ListElement{ longitude: "34"; latitude: "31"; height: "127"; }
+ ListElement{ longitude: "34"; latitude: "32"; height: "123"; }
+ ListElement{ longitude: "34"; latitude: "33"; height: "128"; }
+ ListElement{ longitude: "34"; latitude: "34"; height: "130"; }
+ ListElement{ longitude: "34"; latitude: "35"; height: "127"; }
+ ListElement{ longitude: "34"; latitude: "36"; height: "126"; }
+ ListElement{ longitude: "34"; latitude: "37"; height: "123"; }
+ ListElement{ longitude: "34"; latitude: "38"; height: "125"; }
+ ListElement{ longitude: "34"; latitude: "39"; height: "124"; }
+ ListElement{ longitude: "34"; latitude: "40"; height: "128"; }
+ ListElement{ longitude: "34"; latitude: "41"; height: "126"; }
+ ListElement{ longitude: "34"; latitude: "42"; height: "126"; }
+ ListElement{ longitude: "34"; latitude: "43"; height: "125"; }
+ ListElement{ longitude: "34"; latitude: "44"; height: "122"; }
+ ListElement{ longitude: "34"; latitude: "45"; height: "119"; }
+ ListElement{ longitude: "34"; latitude: "46"; height: "122"; }
+ ListElement{ longitude: "34"; latitude: "47"; height: "122"; }
+ ListElement{ longitude: "34"; latitude: "48"; height: "121"; }
+ ListElement{ longitude: "34"; latitude: "49"; height: "118"; }
+ ListElement{ longitude: "34"; latitude: "50"; height: "117"; }
+ ListElement{ longitude: "34"; latitude: "51"; height: "117"; }
+ ListElement{ longitude: "34"; latitude: "52"; height: "119"; }
+ ListElement{ longitude: "34"; latitude: "53"; height: "118"; }
+ ListElement{ longitude: "34"; latitude: "54"; height: "120"; }
+ ListElement{ longitude: "34"; latitude: "55"; height: "122"; }
+ ListElement{ longitude: "34"; latitude: "56"; height: "126"; }
+ ListElement{ longitude: "34"; latitude: "57"; height: "127"; }
+ ListElement{ longitude: "34"; latitude: "58"; height: "127"; }
+ ListElement{ longitude: "34"; latitude: "59"; height: "124"; }
+ ListElement{ longitude: "34"; latitude: "60"; height: "125"; }
+ ListElement{ longitude: "34"; latitude: "61"; height: "122"; }
+ ListElement{ longitude: "34"; latitude: "62"; height: "122"; }
+ ListElement{ longitude: "34"; latitude: "63"; height: "124"; }
+ ListElement{ longitude: "34"; latitude: "64"; height: "124"; }
+ ListElement{ longitude: "34"; latitude: "65"; height: "126"; }
+ ListElement{ longitude: "34"; latitude: "66"; height: "129"; }
+ ListElement{ longitude: "34"; latitude: "67"; height: "135"; }
+ ListElement{ longitude: "34"; latitude: "68"; height: "142"; }
+ ListElement{ longitude: "34"; latitude: "69"; height: "145"; }
+ ListElement{ longitude: "34"; latitude: "70"; height: "149"; }
+ ListElement{ longitude: "34"; latitude: "71"; height: "149"; }
+ ListElement{ longitude: "34"; latitude: "72"; height: "150"; }
+ ListElement{ longitude: "34"; latitude: "73"; height: "145"; }
+ ListElement{ longitude: "34"; latitude: "74"; height: "144"; }
+ ListElement{ longitude: "34"; latitude: "75"; height: "144"; }
+ ListElement{ longitude: "34"; latitude: "76"; height: "138"; }
+ ListElement{ longitude: "34"; latitude: "77"; height: "141"; }
+ ListElement{ longitude: "34"; latitude: "78"; height: "140"; }
+ ListElement{ longitude: "34"; latitude: "79"; height: "125"; }
+ ListElement{ longitude: "34"; latitude: "80"; height: "131"; }
+ ListElement{ longitude: "34"; latitude: "81"; height: "124"; }
+ ListElement{ longitude: "34"; latitude: "82"; height: "123"; }
+ ListElement{ longitude: "34"; latitude: "83"; height: "123"; }
+ ListElement{ longitude: "34"; latitude: "84"; height: "117"; }
+ ListElement{ longitude: "34"; latitude: "85"; height: "121"; }
+ ListElement{ longitude: "34"; latitude: "86"; height: "119"; }
+ ListElement{ longitude: "34"; latitude: "87"; height: "119"; }
+ ListElement{ longitude: "34"; latitude: "88"; height: "115"; }
+ ListElement{ longitude: "34"; latitude: "89"; height: "118"; }
+ ListElement{ longitude: "34"; latitude: "90"; height: "121"; }
+ ListElement{ longitude: "34"; latitude: "91"; height: "124"; }
+ ListElement{ longitude: "34"; latitude: "92"; height: "127"; }
+ ListElement{ longitude: "34"; latitude: "93"; height: "122"; }
+ ListElement{ longitude: "34"; latitude: "94"; height: "126"; }
+ ListElement{ longitude: "34"; latitude: "95"; height: "127"; }
+ ListElement{ longitude: "34"; latitude: "96"; height: "120"; }
+ ListElement{ longitude: "34"; latitude: "97"; height: "126"; }
+ ListElement{ longitude: "34"; latitude: "98"; height: "130"; }
+ ListElement{ longitude: "34"; latitude: "99"; height: "123"; }
+ ListElement{ longitude: "35"; latitude: "0"; height: "125"; }
+ ListElement{ longitude: "35"; latitude: "1"; height: "122"; }
+ ListElement{ longitude: "35"; latitude: "2"; height: "119"; }
+ ListElement{ longitude: "35"; latitude: "3"; height: "118"; }
+ ListElement{ longitude: "35"; latitude: "4"; height: "121"; }
+ ListElement{ longitude: "35"; latitude: "5"; height: "125"; }
+ ListElement{ longitude: "35"; latitude: "6"; height: "124"; }
+ ListElement{ longitude: "35"; latitude: "7"; height: "126"; }
+ ListElement{ longitude: "35"; latitude: "8"; height: "128"; }
+ ListElement{ longitude: "35"; latitude: "9"; height: "131"; }
+ ListElement{ longitude: "35"; latitude: "10"; height: "130"; }
+ ListElement{ longitude: "35"; latitude: "11"; height: "130"; }
+ ListElement{ longitude: "35"; latitude: "12"; height: "130"; }
+ ListElement{ longitude: "35"; latitude: "13"; height: "129"; }
+ ListElement{ longitude: "35"; latitude: "14"; height: "128"; }
+ ListElement{ longitude: "35"; latitude: "15"; height: "128"; }
+ ListElement{ longitude: "35"; latitude: "16"; height: "127"; }
+ ListElement{ longitude: "35"; latitude: "17"; height: "127"; }
+ ListElement{ longitude: "35"; latitude: "18"; height: "128"; }
+ ListElement{ longitude: "35"; latitude: "19"; height: "129"; }
+ ListElement{ longitude: "35"; latitude: "20"; height: "129"; }
+ ListElement{ longitude: "35"; latitude: "21"; height: "129"; }
+ ListElement{ longitude: "35"; latitude: "22"; height: "129"; }
+ ListElement{ longitude: "35"; latitude: "23"; height: "129"; }
+ ListElement{ longitude: "35"; latitude: "24"; height: "126"; }
+ ListElement{ longitude: "35"; latitude: "25"; height: "127"; }
+ ListElement{ longitude: "35"; latitude: "26"; height: "130"; }
+ ListElement{ longitude: "35"; latitude: "27"; height: "128"; }
+ ListElement{ longitude: "35"; latitude: "28"; height: "127"; }
+ ListElement{ longitude: "35"; latitude: "29"; height: "127"; }
+ ListElement{ longitude: "35"; latitude: "30"; height: "126"; }
+ ListElement{ longitude: "35"; latitude: "31"; height: "129"; }
+ ListElement{ longitude: "35"; latitude: "32"; height: "125"; }
+ ListElement{ longitude: "35"; latitude: "33"; height: "127"; }
+ ListElement{ longitude: "35"; latitude: "34"; height: "126"; }
+ ListElement{ longitude: "35"; latitude: "35"; height: "127"; }
+ ListElement{ longitude: "35"; latitude: "36"; height: "126"; }
+ ListElement{ longitude: "35"; latitude: "37"; height: "121"; }
+ ListElement{ longitude: "35"; latitude: "38"; height: "123"; }
+ ListElement{ longitude: "35"; latitude: "39"; height: "124"; }
+ ListElement{ longitude: "35"; latitude: "40"; height: "123"; }
+ ListElement{ longitude: "35"; latitude: "41"; height: "125"; }
+ ListElement{ longitude: "35"; latitude: "42"; height: "126"; }
+ ListElement{ longitude: "35"; latitude: "43"; height: "125"; }
+ ListElement{ longitude: "35"; latitude: "44"; height: "122"; }
+ ListElement{ longitude: "35"; latitude: "45"; height: "123"; }
+ ListElement{ longitude: "35"; latitude: "46"; height: "121"; }
+ ListElement{ longitude: "35"; latitude: "47"; height: "124"; }
+ ListElement{ longitude: "35"; latitude: "48"; height: "120"; }
+ ListElement{ longitude: "35"; latitude: "49"; height: "120"; }
+ ListElement{ longitude: "35"; latitude: "50"; height: "117"; }
+ ListElement{ longitude: "35"; latitude: "51"; height: "117"; }
+ ListElement{ longitude: "35"; latitude: "52"; height: "117"; }
+ ListElement{ longitude: "35"; latitude: "53"; height: "118"; }
+ ListElement{ longitude: "35"; latitude: "54"; height: "121"; }
+ ListElement{ longitude: "35"; latitude: "55"; height: "124"; }
+ ListElement{ longitude: "35"; latitude: "56"; height: "126"; }
+ ListElement{ longitude: "35"; latitude: "57"; height: "125"; }
+ ListElement{ longitude: "35"; latitude: "58"; height: "126"; }
+ ListElement{ longitude: "35"; latitude: "59"; height: "123"; }
+ ListElement{ longitude: "35"; latitude: "60"; height: "124"; }
+ ListElement{ longitude: "35"; latitude: "61"; height: "120"; }
+ ListElement{ longitude: "35"; latitude: "62"; height: "124"; }
+ ListElement{ longitude: "35"; latitude: "63"; height: "125"; }
+ ListElement{ longitude: "35"; latitude: "64"; height: "124"; }
+ ListElement{ longitude: "35"; latitude: "65"; height: "126"; }
+ ListElement{ longitude: "35"; latitude: "66"; height: "130"; }
+ ListElement{ longitude: "35"; latitude: "67"; height: "135"; }
+ ListElement{ longitude: "35"; latitude: "68"; height: "140"; }
+ ListElement{ longitude: "35"; latitude: "69"; height: "146"; }
+ ListElement{ longitude: "35"; latitude: "70"; height: "147"; }
+ ListElement{ longitude: "35"; latitude: "71"; height: "148"; }
+ ListElement{ longitude: "35"; latitude: "72"; height: "148"; }
+ ListElement{ longitude: "35"; latitude: "73"; height: "144"; }
+ ListElement{ longitude: "35"; latitude: "74"; height: "143"; }
+ ListElement{ longitude: "35"; latitude: "75"; height: "145"; }
+ ListElement{ longitude: "35"; latitude: "76"; height: "146"; }
+ ListElement{ longitude: "35"; latitude: "77"; height: "151"; }
+ ListElement{ longitude: "35"; latitude: "78"; height: "146"; }
+ ListElement{ longitude: "35"; latitude: "79"; height: "136"; }
+ ListElement{ longitude: "35"; latitude: "80"; height: "119"; }
+ ListElement{ longitude: "35"; latitude: "81"; height: "122"; }
+ ListElement{ longitude: "35"; latitude: "82"; height: "121"; }
+ ListElement{ longitude: "35"; latitude: "83"; height: "116"; }
+ ListElement{ longitude: "35"; latitude: "84"; height: "101"; }
+ ListElement{ longitude: "35"; latitude: "85"; height: "111"; }
+ ListElement{ longitude: "35"; latitude: "86"; height: "115"; }
+ ListElement{ longitude: "35"; latitude: "87"; height: "126"; }
+ ListElement{ longitude: "35"; latitude: "88"; height: "127"; }
+ ListElement{ longitude: "35"; latitude: "89"; height: "125"; }
+ ListElement{ longitude: "35"; latitude: "90"; height: "128"; }
+ ListElement{ longitude: "35"; latitude: "91"; height: "121"; }
+ ListElement{ longitude: "35"; latitude: "92"; height: "127"; }
+ ListElement{ longitude: "35"; latitude: "93"; height: "129"; }
+ ListElement{ longitude: "35"; latitude: "94"; height: "129"; }
+ ListElement{ longitude: "35"; latitude: "95"; height: "119"; }
+ ListElement{ longitude: "35"; latitude: "96"; height: "117"; }
+ ListElement{ longitude: "35"; latitude: "97"; height: "135"; }
+ ListElement{ longitude: "35"; latitude: "98"; height: "135"; }
+ ListElement{ longitude: "35"; latitude: "99"; height: "125"; }
+ ListElement{ longitude: "36"; latitude: "0"; height: "123"; }
+ ListElement{ longitude: "36"; latitude: "1"; height: "119"; }
+ ListElement{ longitude: "36"; latitude: "2"; height: "122"; }
+ ListElement{ longitude: "36"; latitude: "3"; height: "120"; }
+ ListElement{ longitude: "36"; latitude: "4"; height: "121"; }
+ ListElement{ longitude: "36"; latitude: "5"; height: "124"; }
+ ListElement{ longitude: "36"; latitude: "6"; height: "124"; }
+ ListElement{ longitude: "36"; latitude: "7"; height: "125"; }
+ ListElement{ longitude: "36"; latitude: "8"; height: "127"; }
+ ListElement{ longitude: "36"; latitude: "9"; height: "130"; }
+ ListElement{ longitude: "36"; latitude: "10"; height: "129"; }
+ ListElement{ longitude: "36"; latitude: "11"; height: "130"; }
+ ListElement{ longitude: "36"; latitude: "12"; height: "130"; }
+ ListElement{ longitude: "36"; latitude: "13"; height: "129"; }
+ ListElement{ longitude: "36"; latitude: "14"; height: "126"; }
+ ListElement{ longitude: "36"; latitude: "15"; height: "127"; }
+ ListElement{ longitude: "36"; latitude: "16"; height: "127"; }
+ ListElement{ longitude: "36"; latitude: "17"; height: "125"; }
+ ListElement{ longitude: "36"; latitude: "18"; height: "125"; }
+ ListElement{ longitude: "36"; latitude: "19"; height: "126"; }
+ ListElement{ longitude: "36"; latitude: "20"; height: "128"; }
+ ListElement{ longitude: "36"; latitude: "21"; height: "124"; }
+ ListElement{ longitude: "36"; latitude: "22"; height: "127"; }
+ ListElement{ longitude: "36"; latitude: "23"; height: "129"; }
+ ListElement{ longitude: "36"; latitude: "24"; height: "128"; }
+ ListElement{ longitude: "36"; latitude: "25"; height: "127"; }
+ ListElement{ longitude: "36"; latitude: "26"; height: "122"; }
+ ListElement{ longitude: "36"; latitude: "27"; height: "123"; }
+ ListElement{ longitude: "36"; latitude: "28"; height: "128"; }
+ ListElement{ longitude: "36"; latitude: "29"; height: "127"; }
+ ListElement{ longitude: "36"; latitude: "30"; height: "127"; }
+ ListElement{ longitude: "36"; latitude: "31"; height: "127"; }
+ ListElement{ longitude: "36"; latitude: "32"; height: "127"; }
+ ListElement{ longitude: "36"; latitude: "33"; height: "127"; }
+ ListElement{ longitude: "36"; latitude: "34"; height: "127"; }
+ ListElement{ longitude: "36"; latitude: "35"; height: "127"; }
+ ListElement{ longitude: "36"; latitude: "36"; height: "126"; }
+ ListElement{ longitude: "36"; latitude: "37"; height: "124"; }
+ ListElement{ longitude: "36"; latitude: "38"; height: "126"; }
+ ListElement{ longitude: "36"; latitude: "39"; height: "127"; }
+ ListElement{ longitude: "36"; latitude: "40"; height: "127"; }
+ ListElement{ longitude: "36"; latitude: "41"; height: "129"; }
+ ListElement{ longitude: "36"; latitude: "42"; height: "127"; }
+ ListElement{ longitude: "36"; latitude: "43"; height: "125"; }
+ ListElement{ longitude: "36"; latitude: "44"; height: "122"; }
+ ListElement{ longitude: "36"; latitude: "45"; height: "123"; }
+ ListElement{ longitude: "36"; latitude: "46"; height: "121"; }
+ ListElement{ longitude: "36"; latitude: "47"; height: "124"; }
+ ListElement{ longitude: "36"; latitude: "48"; height: "120"; }
+ ListElement{ longitude: "36"; latitude: "49"; height: "120"; }
+ ListElement{ longitude: "36"; latitude: "50"; height: "117"; }
+ ListElement{ longitude: "36"; latitude: "51"; height: "117"; }
+ ListElement{ longitude: "36"; latitude: "52"; height: "117"; }
+ ListElement{ longitude: "36"; latitude: "53"; height: "117"; }
+ ListElement{ longitude: "36"; latitude: "54"; height: "119"; }
+ ListElement{ longitude: "36"; latitude: "55"; height: "121"; }
+ ListElement{ longitude: "36"; latitude: "56"; height: "125"; }
+ ListElement{ longitude: "36"; latitude: "57"; height: "126"; }
+ ListElement{ longitude: "36"; latitude: "58"; height: "127"; }
+ ListElement{ longitude: "36"; latitude: "59"; height: "123"; }
+ ListElement{ longitude: "36"; latitude: "60"; height: "124"; }
+ ListElement{ longitude: "36"; latitude: "61"; height: "122"; }
+ ListElement{ longitude: "36"; latitude: "62"; height: "123"; }
+ ListElement{ longitude: "36"; latitude: "63"; height: "125"; }
+ ListElement{ longitude: "36"; latitude: "64"; height: "124"; }
+ ListElement{ longitude: "36"; latitude: "65"; height: "125"; }
+ ListElement{ longitude: "36"; latitude: "66"; height: "129"; }
+ ListElement{ longitude: "36"; latitude: "67"; height: "129"; }
+ ListElement{ longitude: "36"; latitude: "68"; height: "137"; }
+ ListElement{ longitude: "36"; latitude: "69"; height: "142"; }
+ ListElement{ longitude: "36"; latitude: "70"; height: "146"; }
+ ListElement{ longitude: "36"; latitude: "71"; height: "148"; }
+ ListElement{ longitude: "36"; latitude: "72"; height: "148"; }
+ ListElement{ longitude: "36"; latitude: "73"; height: "145"; }
+ ListElement{ longitude: "36"; latitude: "74"; height: "141"; }
+ ListElement{ longitude: "36"; latitude: "75"; height: "148"; }
+ ListElement{ longitude: "36"; latitude: "76"; height: "152"; }
+ ListElement{ longitude: "36"; latitude: "77"; height: "146"; }
+ ListElement{ longitude: "36"; latitude: "78"; height: "146"; }
+ ListElement{ longitude: "36"; latitude: "79"; height: "154"; }
+ ListElement{ longitude: "36"; latitude: "80"; height: "146"; }
+ ListElement{ longitude: "36"; latitude: "81"; height: "131"; }
+ ListElement{ longitude: "36"; latitude: "82"; height: "103"; }
+ ListElement{ longitude: "36"; latitude: "83"; height: "94"; }
+ ListElement{ longitude: "36"; latitude: "84"; height: "78"; }
+ ListElement{ longitude: "36"; latitude: "85"; height: "73"; }
+ ListElement{ longitude: "36"; latitude: "86"; height: "87"; }
+ ListElement{ longitude: "36"; latitude: "87"; height: "103"; }
+ ListElement{ longitude: "36"; latitude: "88"; height: "98"; }
+ ListElement{ longitude: "36"; latitude: "89"; height: "110"; }
+ ListElement{ longitude: "36"; latitude: "90"; height: "113"; }
+ ListElement{ longitude: "36"; latitude: "91"; height: "125"; }
+ ListElement{ longitude: "36"; latitude: "92"; height: "129"; }
+ ListElement{ longitude: "36"; latitude: "93"; height: "127"; }
+ ListElement{ longitude: "36"; latitude: "94"; height: "129"; }
+ ListElement{ longitude: "36"; latitude: "95"; height: "122"; }
+ ListElement{ longitude: "36"; latitude: "96"; height: "122"; }
+ ListElement{ longitude: "36"; latitude: "97"; height: "128"; }
+ ListElement{ longitude: "36"; latitude: "98"; height: "131"; }
+ ListElement{ longitude: "36"; latitude: "99"; height: "129"; }
+ ListElement{ longitude: "37"; latitude: "0"; height: "123"; }
+ ListElement{ longitude: "37"; latitude: "1"; height: "120"; }
+ ListElement{ longitude: "37"; latitude: "2"; height: "121"; }
+ ListElement{ longitude: "37"; latitude: "3"; height: "120"; }
+ ListElement{ longitude: "37"; latitude: "4"; height: "121"; }
+ ListElement{ longitude: "37"; latitude: "5"; height: "122"; }
+ ListElement{ longitude: "37"; latitude: "6"; height: "124"; }
+ ListElement{ longitude: "37"; latitude: "7"; height: "127"; }
+ ListElement{ longitude: "37"; latitude: "8"; height: "129"; }
+ ListElement{ longitude: "37"; latitude: "9"; height: "132"; }
+ ListElement{ longitude: "37"; latitude: "10"; height: "129"; }
+ ListElement{ longitude: "37"; latitude: "11"; height: "130"; }
+ ListElement{ longitude: "37"; latitude: "12"; height: "130"; }
+ ListElement{ longitude: "37"; latitude: "13"; height: "127"; }
+ ListElement{ longitude: "37"; latitude: "14"; height: "128"; }
+ ListElement{ longitude: "37"; latitude: "15"; height: "127"; }
+ ListElement{ longitude: "37"; latitude: "16"; height: "120"; }
+ ListElement{ longitude: "37"; latitude: "17"; height: "128"; }
+ ListElement{ longitude: "37"; latitude: "18"; height: "125"; }
+ ListElement{ longitude: "37"; latitude: "19"; height: "127"; }
+ ListElement{ longitude: "37"; latitude: "20"; height: "128"; }
+ ListElement{ longitude: "37"; latitude: "21"; height: "126"; }
+ ListElement{ longitude: "37"; latitude: "22"; height: "129"; }
+ ListElement{ longitude: "37"; latitude: "23"; height: "130"; }
+ ListElement{ longitude: "37"; latitude: "24"; height: "128"; }
+ ListElement{ longitude: "37"; latitude: "25"; height: "110"; }
+ ListElement{ longitude: "37"; latitude: "26"; height: "98"; }
+ ListElement{ longitude: "37"; latitude: "27"; height: "97"; }
+ ListElement{ longitude: "37"; latitude: "28"; height: "123"; }
+ ListElement{ longitude: "37"; latitude: "29"; height: "127"; }
+ ListElement{ longitude: "37"; latitude: "30"; height: "127"; }
+ ListElement{ longitude: "37"; latitude: "31"; height: "127"; }
+ ListElement{ longitude: "37"; latitude: "32"; height: "127"; }
+ ListElement{ longitude: "37"; latitude: "33"; height: "127"; }
+ ListElement{ longitude: "37"; latitude: "34"; height: "127"; }
+ ListElement{ longitude: "37"; latitude: "35"; height: "125"; }
+ ListElement{ longitude: "37"; latitude: "36"; height: "124"; }
+ ListElement{ longitude: "37"; latitude: "37"; height: "124"; }
+ ListElement{ longitude: "37"; latitude: "38"; height: "125"; }
+ ListElement{ longitude: "37"; latitude: "39"; height: "127"; }
+ ListElement{ longitude: "37"; latitude: "40"; height: "126"; }
+ ListElement{ longitude: "37"; latitude: "41"; height: "128"; }
+ ListElement{ longitude: "37"; latitude: "42"; height: "127"; }
+ ListElement{ longitude: "37"; latitude: "43"; height: "124"; }
+ ListElement{ longitude: "37"; latitude: "44"; height: "124"; }
+ ListElement{ longitude: "37"; latitude: "45"; height: "121"; }
+ ListElement{ longitude: "37"; latitude: "46"; height: "121"; }
+ ListElement{ longitude: "37"; latitude: "47"; height: "122"; }
+ ListElement{ longitude: "37"; latitude: "48"; height: "119"; }
+ ListElement{ longitude: "37"; latitude: "49"; height: "120"; }
+ ListElement{ longitude: "37"; latitude: "50"; height: "118"; }
+ ListElement{ longitude: "37"; latitude: "51"; height: "119"; }
+ ListElement{ longitude: "37"; latitude: "52"; height: "117"; }
+ ListElement{ longitude: "37"; latitude: "53"; height: "117"; }
+ ListElement{ longitude: "37"; latitude: "54"; height: "120"; }
+ ListElement{ longitude: "37"; latitude: "55"; height: "120"; }
+ ListElement{ longitude: "37"; latitude: "56"; height: "123"; }
+ ListElement{ longitude: "37"; latitude: "57"; height: "123"; }
+ ListElement{ longitude: "37"; latitude: "58"; height: "123"; }
+ ListElement{ longitude: "37"; latitude: "59"; height: "123"; }
+ ListElement{ longitude: "37"; latitude: "60"; height: "125"; }
+ ListElement{ longitude: "37"; latitude: "61"; height: "125"; }
+ ListElement{ longitude: "37"; latitude: "62"; height: "125"; }
+ ListElement{ longitude: "37"; latitude: "63"; height: "124"; }
+ ListElement{ longitude: "37"; latitude: "64"; height: "124"; }
+ ListElement{ longitude: "37"; latitude: "65"; height: "123"; }
+ ListElement{ longitude: "37"; latitude: "66"; height: "126"; }
+ ListElement{ longitude: "37"; latitude: "67"; height: "127"; }
+ ListElement{ longitude: "37"; latitude: "68"; height: "133"; }
+ ListElement{ longitude: "37"; latitude: "69"; height: "138"; }
+ ListElement{ longitude: "37"; latitude: "70"; height: "145"; }
+ ListElement{ longitude: "37"; latitude: "71"; height: "146"; }
+ ListElement{ longitude: "37"; latitude: "72"; height: "146"; }
+ ListElement{ longitude: "37"; latitude: "73"; height: "149"; }
+ ListElement{ longitude: "37"; latitude: "74"; height: "145"; }
+ ListElement{ longitude: "37"; latitude: "75"; height: "154"; }
+ ListElement{ longitude: "37"; latitude: "76"; height: "153"; }
+ ListElement{ longitude: "37"; latitude: "77"; height: "152"; }
+ ListElement{ longitude: "37"; latitude: "78"; height: "149"; }
+ ListElement{ longitude: "37"; latitude: "79"; height: "127"; }
+ ListElement{ longitude: "37"; latitude: "80"; height: "97"; }
+ ListElement{ longitude: "37"; latitude: "81"; height: "70"; }
+ ListElement{ longitude: "37"; latitude: "82"; height: "66"; }
+ ListElement{ longitude: "37"; latitude: "83"; height: "71"; }
+ ListElement{ longitude: "37"; latitude: "84"; height: "59"; }
+ ListElement{ longitude: "37"; latitude: "85"; height: "48"; }
+ ListElement{ longitude: "37"; latitude: "86"; height: "66"; }
+ ListElement{ longitude: "37"; latitude: "87"; height: "74"; }
+ ListElement{ longitude: "37"; latitude: "88"; height: "78"; }
+ ListElement{ longitude: "37"; latitude: "89"; height: "86"; }
+ ListElement{ longitude: "37"; latitude: "90"; height: "94"; }
+ ListElement{ longitude: "37"; latitude: "91"; height: "107"; }
+ ListElement{ longitude: "37"; latitude: "92"; height: "120"; }
+ ListElement{ longitude: "37"; latitude: "93"; height: "131"; }
+ ListElement{ longitude: "37"; latitude: "94"; height: "129"; }
+ ListElement{ longitude: "37"; latitude: "95"; height: "127"; }
+ ListElement{ longitude: "37"; latitude: "96"; height: "133"; }
+ ListElement{ longitude: "37"; latitude: "97"; height: "135"; }
+ ListElement{ longitude: "37"; latitude: "98"; height: "134"; }
+ ListElement{ longitude: "37"; latitude: "99"; height: "130"; }
+ ListElement{ longitude: "38"; latitude: "0"; height: "122"; }
+ ListElement{ longitude: "38"; latitude: "1"; height: "118"; }
+ ListElement{ longitude: "38"; latitude: "2"; height: "121"; }
+ ListElement{ longitude: "38"; latitude: "3"; height: "120"; }
+ ListElement{ longitude: "38"; latitude: "4"; height: "120"; }
+ ListElement{ longitude: "38"; latitude: "5"; height: "124"; }
+ ListElement{ longitude: "38"; latitude: "6"; height: "126"; }
+ ListElement{ longitude: "38"; latitude: "7"; height: "126"; }
+ ListElement{ longitude: "38"; latitude: "8"; height: "129"; }
+ ListElement{ longitude: "38"; latitude: "9"; height: "128"; }
+ ListElement{ longitude: "38"; latitude: "10"; height: "129"; }
+ ListElement{ longitude: "38"; latitude: "11"; height: "131"; }
+ ListElement{ longitude: "38"; latitude: "12"; height: "128"; }
+ ListElement{ longitude: "38"; latitude: "13"; height: "125"; }
+ ListElement{ longitude: "38"; latitude: "14"; height: "128"; }
+ ListElement{ longitude: "38"; latitude: "15"; height: "125"; }
+ ListElement{ longitude: "38"; latitude: "16"; height: "124"; }
+ ListElement{ longitude: "38"; latitude: "17"; height: "126"; }
+ ListElement{ longitude: "38"; latitude: "18"; height: "125"; }
+ ListElement{ longitude: "38"; latitude: "19"; height: "127"; }
+ ListElement{ longitude: "38"; latitude: "20"; height: "125"; }
+ ListElement{ longitude: "38"; latitude: "21"; height: "128"; }
+ ListElement{ longitude: "38"; latitude: "22"; height: "127"; }
+ ListElement{ longitude: "38"; latitude: "23"; height: "128"; }
+ ListElement{ longitude: "38"; latitude: "24"; height: "126"; }
+ ListElement{ longitude: "38"; latitude: "25"; height: "103"; }
+ ListElement{ longitude: "38"; latitude: "26"; height: "86"; }
+ ListElement{ longitude: "38"; latitude: "27"; height: "90"; }
+ ListElement{ longitude: "38"; latitude: "28"; height: "116"; }
+ ListElement{ longitude: "38"; latitude: "29"; height: "129"; }
+ ListElement{ longitude: "38"; latitude: "30"; height: "124"; }
+ ListElement{ longitude: "38"; latitude: "31"; height: "127"; }
+ ListElement{ longitude: "38"; latitude: "32"; height: "127"; }
+ ListElement{ longitude: "38"; latitude: "33"; height: "125"; }
+ ListElement{ longitude: "38"; latitude: "34"; height: "127"; }
+ ListElement{ longitude: "38"; latitude: "35"; height: "125"; }
+ ListElement{ longitude: "38"; latitude: "36"; height: "126"; }
+ ListElement{ longitude: "38"; latitude: "37"; height: "126"; }
+ ListElement{ longitude: "38"; latitude: "38"; height: "128"; }
+ ListElement{ longitude: "38"; latitude: "39"; height: "125"; }
+ ListElement{ longitude: "38"; latitude: "40"; height: "127"; }
+ ListElement{ longitude: "38"; latitude: "41"; height: "127"; }
+ ListElement{ longitude: "38"; latitude: "42"; height: "126"; }
+ ListElement{ longitude: "38"; latitude: "43"; height: "124"; }
+ ListElement{ longitude: "38"; latitude: "44"; height: "123"; }
+ ListElement{ longitude: "38"; latitude: "45"; height: "122"; }
+ ListElement{ longitude: "38"; latitude: "46"; height: "121"; }
+ ListElement{ longitude: "38"; latitude: "47"; height: "121"; }
+ ListElement{ longitude: "38"; latitude: "48"; height: "119"; }
+ ListElement{ longitude: "38"; latitude: "49"; height: "122"; }
+ ListElement{ longitude: "38"; latitude: "50"; height: "120"; }
+ ListElement{ longitude: "38"; latitude: "51"; height: "120"; }
+ ListElement{ longitude: "38"; latitude: "52"; height: "119"; }
+ ListElement{ longitude: "38"; latitude: "53"; height: "117"; }
+ ListElement{ longitude: "38"; latitude: "54"; height: "120"; }
+ ListElement{ longitude: "38"; latitude: "55"; height: "119"; }
+ ListElement{ longitude: "38"; latitude: "56"; height: "122"; }
+ ListElement{ longitude: "38"; latitude: "57"; height: "122"; }
+ ListElement{ longitude: "38"; latitude: "58"; height: "125"; }
+ ListElement{ longitude: "38"; latitude: "59"; height: "125"; }
+ ListElement{ longitude: "38"; latitude: "60"; height: "125"; }
+ ListElement{ longitude: "38"; latitude: "61"; height: "124"; }
+ ListElement{ longitude: "38"; latitude: "62"; height: "126"; }
+ ListElement{ longitude: "38"; latitude: "63"; height: "125"; }
+ ListElement{ longitude: "38"; latitude: "64"; height: "127"; }
+ ListElement{ longitude: "38"; latitude: "65"; height: "126"; }
+ ListElement{ longitude: "38"; latitude: "66"; height: "124"; }
+ ListElement{ longitude: "38"; latitude: "67"; height: "126"; }
+ ListElement{ longitude: "38"; latitude: "68"; height: "132"; }
+ ListElement{ longitude: "38"; latitude: "69"; height: "137"; }
+ ListElement{ longitude: "38"; latitude: "70"; height: "145"; }
+ ListElement{ longitude: "38"; latitude: "71"; height: "148"; }
+ ListElement{ longitude: "38"; latitude: "72"; height: "155"; }
+ ListElement{ longitude: "38"; latitude: "73"; height: "161"; }
+ ListElement{ longitude: "38"; latitude: "74"; height: "147"; }
+ ListElement{ longitude: "38"; latitude: "75"; height: "146"; }
+ ListElement{ longitude: "38"; latitude: "76"; height: "139"; }
+ ListElement{ longitude: "38"; latitude: "77"; height: "120"; }
+ ListElement{ longitude: "38"; latitude: "78"; height: "108"; }
+ ListElement{ longitude: "38"; latitude: "79"; height: "93"; }
+ ListElement{ longitude: "38"; latitude: "80"; height: "76"; }
+ ListElement{ longitude: "38"; latitude: "81"; height: "59"; }
+ ListElement{ longitude: "38"; latitude: "82"; height: "54"; }
+ ListElement{ longitude: "38"; latitude: "83"; height: "61"; }
+ ListElement{ longitude: "38"; latitude: "84"; height: "24"; }
+ ListElement{ longitude: "38"; latitude: "85"; height: "13"; }
+ ListElement{ longitude: "38"; latitude: "86"; height: "42"; }
+ ListElement{ longitude: "38"; latitude: "87"; height: "58"; }
+ ListElement{ longitude: "38"; latitude: "88"; height: "73"; }
+ ListElement{ longitude: "38"; latitude: "89"; height: "75"; }
+ ListElement{ longitude: "38"; latitude: "90"; height: "74"; }
+ ListElement{ longitude: "38"; latitude: "91"; height: "77"; }
+ ListElement{ longitude: "38"; latitude: "92"; height: "96"; }
+ ListElement{ longitude: "38"; latitude: "93"; height: "116"; }
+ ListElement{ longitude: "38"; latitude: "94"; height: "133"; }
+ ListElement{ longitude: "38"; latitude: "95"; height: "131"; }
+ ListElement{ longitude: "38"; latitude: "96"; height: "137"; }
+ ListElement{ longitude: "38"; latitude: "97"; height: "137"; }
+ ListElement{ longitude: "38"; latitude: "98"; height: "134"; }
+ ListElement{ longitude: "38"; latitude: "99"; height: "130"; }
+ ListElement{ longitude: "39"; latitude: "0"; height: "122"; }
+ ListElement{ longitude: "39"; latitude: "1"; height: "120"; }
+ ListElement{ longitude: "39"; latitude: "2"; height: "121"; }
+ ListElement{ longitude: "39"; latitude: "3"; height: "121"; }
+ ListElement{ longitude: "39"; latitude: "4"; height: "120"; }
+ ListElement{ longitude: "39"; latitude: "5"; height: "121"; }
+ ListElement{ longitude: "39"; latitude: "6"; height: "125"; }
+ ListElement{ longitude: "39"; latitude: "7"; height: "127"; }
+ ListElement{ longitude: "39"; latitude: "8"; height: "129"; }
+ ListElement{ longitude: "39"; latitude: "9"; height: "129"; }
+ ListElement{ longitude: "39"; latitude: "10"; height: "130"; }
+ ListElement{ longitude: "39"; latitude: "11"; height: "132"; }
+ ListElement{ longitude: "39"; latitude: "12"; height: "128"; }
+ ListElement{ longitude: "39"; latitude: "13"; height: "129"; }
+ ListElement{ longitude: "39"; latitude: "14"; height: "128"; }
+ ListElement{ longitude: "39"; latitude: "15"; height: "125"; }
+ ListElement{ longitude: "39"; latitude: "16"; height: "126"; }
+ ListElement{ longitude: "39"; latitude: "17"; height: "126"; }
+ ListElement{ longitude: "39"; latitude: "18"; height: "125"; }
+ ListElement{ longitude: "39"; latitude: "19"; height: "125"; }
+ ListElement{ longitude: "39"; latitude: "20"; height: "123"; }
+ ListElement{ longitude: "39"; latitude: "21"; height: "128"; }
+ ListElement{ longitude: "39"; latitude: "22"; height: "128"; }
+ ListElement{ longitude: "39"; latitude: "23"; height: "130"; }
+ ListElement{ longitude: "39"; latitude: "24"; height: "127"; }
+ ListElement{ longitude: "39"; latitude: "25"; height: "108"; }
+ ListElement{ longitude: "39"; latitude: "26"; height: "88"; }
+ ListElement{ longitude: "39"; latitude: "27"; height: "80"; }
+ ListElement{ longitude: "39"; latitude: "28"; height: "108"; }
+ ListElement{ longitude: "39"; latitude: "29"; height: "127"; }
+ ListElement{ longitude: "39"; latitude: "30"; height: "124"; }
+ ListElement{ longitude: "39"; latitude: "31"; height: "126"; }
+ ListElement{ longitude: "39"; latitude: "32"; height: "124"; }
+ ListElement{ longitude: "39"; latitude: "33"; height: "122"; }
+ ListElement{ longitude: "39"; latitude: "34"; height: "126"; }
+ ListElement{ longitude: "39"; latitude: "35"; height: "126"; }
+ ListElement{ longitude: "39"; latitude: "36"; height: "126"; }
+ ListElement{ longitude: "39"; latitude: "37"; height: "126"; }
+ ListElement{ longitude: "39"; latitude: "38"; height: "124"; }
+ ListElement{ longitude: "39"; latitude: "39"; height: "122"; }
+ ListElement{ longitude: "39"; latitude: "40"; height: "127"; }
+ ListElement{ longitude: "39"; latitude: "41"; height: "121"; }
+ ListElement{ longitude: "39"; latitude: "42"; height: "126"; }
+ ListElement{ longitude: "39"; latitude: "43"; height: "126"; }
+ ListElement{ longitude: "39"; latitude: "44"; height: "125"; }
+ ListElement{ longitude: "39"; latitude: "45"; height: "124"; }
+ ListElement{ longitude: "39"; latitude: "46"; height: "121"; }
+ ListElement{ longitude: "39"; latitude: "47"; height: "121"; }
+ ListElement{ longitude: "39"; latitude: "48"; height: "118"; }
+ ListElement{ longitude: "39"; latitude: "49"; height: "118"; }
+ ListElement{ longitude: "39"; latitude: "50"; height: "118"; }
+ ListElement{ longitude: "39"; latitude: "51"; height: "120"; }
+ ListElement{ longitude: "39"; latitude: "52"; height: "118"; }
+ ListElement{ longitude: "39"; latitude: "53"; height: "116"; }
+ ListElement{ longitude: "39"; latitude: "54"; height: "120"; }
+ ListElement{ longitude: "39"; latitude: "55"; height: "117"; }
+ ListElement{ longitude: "39"; latitude: "56"; height: "119"; }
+ ListElement{ longitude: "39"; latitude: "57"; height: "121"; }
+ ListElement{ longitude: "39"; latitude: "58"; height: "125"; }
+ ListElement{ longitude: "39"; latitude: "59"; height: "124"; }
+ ListElement{ longitude: "39"; latitude: "60"; height: "124"; }
+ ListElement{ longitude: "39"; latitude: "61"; height: "125"; }
+ ListElement{ longitude: "39"; latitude: "62"; height: "128"; }
+ ListElement{ longitude: "39"; latitude: "63"; height: "127"; }
+ ListElement{ longitude: "39"; latitude: "64"; height: "129"; }
+ ListElement{ longitude: "39"; latitude: "65"; height: "129"; }
+ ListElement{ longitude: "39"; latitude: "66"; height: "129"; }
+ ListElement{ longitude: "39"; latitude: "67"; height: "127"; }
+ ListElement{ longitude: "39"; latitude: "68"; height: "132"; }
+ ListElement{ longitude: "39"; latitude: "69"; height: "136"; }
+ ListElement{ longitude: "39"; latitude: "70"; height: "146"; }
+ ListElement{ longitude: "39"; latitude: "71"; height: "153"; }
+ ListElement{ longitude: "39"; latitude: "72"; height: "161"; }
+ ListElement{ longitude: "39"; latitude: "73"; height: "157"; }
+ ListElement{ longitude: "39"; latitude: "74"; height: "152"; }
+ ListElement{ longitude: "39"; latitude: "75"; height: "139"; }
+ ListElement{ longitude: "39"; latitude: "76"; height: "120"; }
+ ListElement{ longitude: "39"; latitude: "77"; height: "116"; }
+ ListElement{ longitude: "39"; latitude: "78"; height: "97"; }
+ ListElement{ longitude: "39"; latitude: "79"; height: "49"; }
+ ListElement{ longitude: "39"; latitude: "80"; height: "16"; }
+ ListElement{ longitude: "39"; latitude: "81"; height: "11"; }
+ ListElement{ longitude: "39"; latitude: "82"; height: "24"; }
+ ListElement{ longitude: "39"; latitude: "83"; height: "58"; }
+ ListElement{ longitude: "39"; latitude: "84"; height: "13"; }
+ ListElement{ longitude: "39"; latitude: "85"; height: "1"; }
+ ListElement{ longitude: "39"; latitude: "86"; height: "31"; }
+ ListElement{ longitude: "39"; latitude: "87"; height: "58"; }
+ ListElement{ longitude: "39"; latitude: "88"; height: "43"; }
+ ListElement{ longitude: "39"; latitude: "89"; height: "48"; }
+ ListElement{ longitude: "39"; latitude: "90"; height: "67"; }
+ ListElement{ longitude: "39"; latitude: "91"; height: "71"; }
+ ListElement{ longitude: "39"; latitude: "92"; height: "81"; }
+ ListElement{ longitude: "39"; latitude: "93"; height: "92"; }
+ ListElement{ longitude: "39"; latitude: "94"; height: "123"; }
+ ListElement{ longitude: "39"; latitude: "95"; height: "143"; }
+ ListElement{ longitude: "39"; latitude: "96"; height: "135"; }
+ ListElement{ longitude: "39"; latitude: "97"; height: "139"; }
+ ListElement{ longitude: "39"; latitude: "98"; height: "136"; }
+ ListElement{ longitude: "39"; latitude: "99"; height: "129"; }
+ ListElement{ longitude: "40"; latitude: "0"; height: "122"; }
+ ListElement{ longitude: "40"; latitude: "1"; height: "122"; }
+ ListElement{ longitude: "40"; latitude: "2"; height: "120"; }
+ ListElement{ longitude: "40"; latitude: "3"; height: "120"; }
+ ListElement{ longitude: "40"; latitude: "4"; height: "120"; }
+ ListElement{ longitude: "40"; latitude: "5"; height: "119"; }
+ ListElement{ longitude: "40"; latitude: "6"; height: "123"; }
+ ListElement{ longitude: "40"; latitude: "7"; height: "125"; }
+ ListElement{ longitude: "40"; latitude: "8"; height: "128"; }
+ ListElement{ longitude: "40"; latitude: "9"; height: "127"; }
+ ListElement{ longitude: "40"; latitude: "10"; height: "128"; }
+ ListElement{ longitude: "40"; latitude: "11"; height: "130"; }
+ ListElement{ longitude: "40"; latitude: "12"; height: "131"; }
+ ListElement{ longitude: "40"; latitude: "13"; height: "129"; }
+ ListElement{ longitude: "40"; latitude: "14"; height: "126"; }
+ ListElement{ longitude: "40"; latitude: "15"; height: "127"; }
+ ListElement{ longitude: "40"; latitude: "16"; height: "126"; }
+ ListElement{ longitude: "40"; latitude: "17"; height: "126"; }
+ ListElement{ longitude: "40"; latitude: "18"; height: "125"; }
+ ListElement{ longitude: "40"; latitude: "19"; height: "127"; }
+ ListElement{ longitude: "40"; latitude: "20"; height: "125"; }
+ ListElement{ longitude: "40"; latitude: "21"; height: "126"; }
+ ListElement{ longitude: "40"; latitude: "22"; height: "128"; }
+ ListElement{ longitude: "40"; latitude: "23"; height: "128"; }
+ ListElement{ longitude: "40"; latitude: "24"; height: "129"; }
+ ListElement{ longitude: "40"; latitude: "25"; height: "119"; }
+ ListElement{ longitude: "40"; latitude: "26"; height: "103"; }
+ ListElement{ longitude: "40"; latitude: "27"; height: "110"; }
+ ListElement{ longitude: "40"; latitude: "28"; height: "126"; }
+ ListElement{ longitude: "40"; latitude: "29"; height: "128"; }
+ ListElement{ longitude: "40"; latitude: "30"; height: "124"; }
+ ListElement{ longitude: "40"; latitude: "31"; height: "128"; }
+ ListElement{ longitude: "40"; latitude: "32"; height: "126"; }
+ ListElement{ longitude: "40"; latitude: "33"; height: "124"; }
+ ListElement{ longitude: "40"; latitude: "34"; height: "126"; }
+ ListElement{ longitude: "40"; latitude: "35"; height: "125"; }
+ ListElement{ longitude: "40"; latitude: "36"; height: "125"; }
+ ListElement{ longitude: "40"; latitude: "37"; height: "127"; }
+ ListElement{ longitude: "40"; latitude: "38"; height: "126"; }
+ ListElement{ longitude: "40"; latitude: "39"; height: "126"; }
+ ListElement{ longitude: "40"; latitude: "40"; height: "128"; }
+ ListElement{ longitude: "40"; latitude: "41"; height: "126"; }
+ ListElement{ longitude: "40"; latitude: "42"; height: "127"; }
+ ListElement{ longitude: "40"; latitude: "43"; height: "127"; }
+ ListElement{ longitude: "40"; latitude: "44"; height: "126"; }
+ ListElement{ longitude: "40"; latitude: "45"; height: "125"; }
+ ListElement{ longitude: "40"; latitude: "46"; height: "123"; }
+ ListElement{ longitude: "40"; latitude: "47"; height: "119"; }
+ ListElement{ longitude: "40"; latitude: "48"; height: "117"; }
+ ListElement{ longitude: "40"; latitude: "49"; height: "117"; }
+ ListElement{ longitude: "40"; latitude: "50"; height: "117"; }
+ ListElement{ longitude: "40"; latitude: "51"; height: "120"; }
+ ListElement{ longitude: "40"; latitude: "52"; height: "120"; }
+ ListElement{ longitude: "40"; latitude: "53"; height: "120"; }
+ ListElement{ longitude: "40"; latitude: "54"; height: "120"; }
+ ListElement{ longitude: "40"; latitude: "55"; height: "119"; }
+ ListElement{ longitude: "40"; latitude: "56"; height: "121"; }
+ ListElement{ longitude: "40"; latitude: "57"; height: "121"; }
+ ListElement{ longitude: "40"; latitude: "58"; height: "125"; }
+ ListElement{ longitude: "40"; latitude: "59"; height: "124"; }
+ ListElement{ longitude: "40"; latitude: "60"; height: "126"; }
+ ListElement{ longitude: "40"; latitude: "61"; height: "126"; }
+ ListElement{ longitude: "40"; latitude: "62"; height: "129"; }
+ ListElement{ longitude: "40"; latitude: "63"; height: "129"; }
+ ListElement{ longitude: "40"; latitude: "64"; height: "133"; }
+ ListElement{ longitude: "40"; latitude: "65"; height: "126"; }
+ ListElement{ longitude: "40"; latitude: "66"; height: "130"; }
+ ListElement{ longitude: "40"; latitude: "67"; height: "131"; }
+ ListElement{ longitude: "40"; latitude: "68"; height: "134"; }
+ ListElement{ longitude: "40"; latitude: "69"; height: "139"; }
+ ListElement{ longitude: "40"; latitude: "70"; height: "146"; }
+ ListElement{ longitude: "40"; latitude: "71"; height: "157"; }
+ ListElement{ longitude: "40"; latitude: "72"; height: "166"; }
+ ListElement{ longitude: "40"; latitude: "73"; height: "159"; }
+ ListElement{ longitude: "40"; latitude: "74"; height: "151"; }
+ ListElement{ longitude: "40"; latitude: "75"; height: "130"; }
+ ListElement{ longitude: "40"; latitude: "76"; height: "117"; }
+ ListElement{ longitude: "40"; latitude: "77"; height: "98"; }
+ ListElement{ longitude: "40"; latitude: "78"; height: "82"; }
+ ListElement{ longitude: "40"; latitude: "79"; height: "73"; }
+ ListElement{ longitude: "40"; latitude: "80"; height: "49"; }
+ ListElement{ longitude: "40"; latitude: "81"; height: "1"; }
+ ListElement{ longitude: "40"; latitude: "82"; height: "1"; }
+ ListElement{ longitude: "40"; latitude: "83"; height: "1"; }
+ ListElement{ longitude: "40"; latitude: "84"; height: "27"; }
+ ListElement{ longitude: "40"; latitude: "85"; height: "10"; }
+ ListElement{ longitude: "40"; latitude: "86"; height: "17"; }
+ ListElement{ longitude: "40"; latitude: "87"; height: "24"; }
+ ListElement{ longitude: "40"; latitude: "88"; height: "16"; }
+ ListElement{ longitude: "40"; latitude: "89"; height: "35"; }
+ ListElement{ longitude: "40"; latitude: "90"; height: "58"; }
+ ListElement{ longitude: "40"; latitude: "91"; height: "66"; }
+ ListElement{ longitude: "40"; latitude: "92"; height: "78"; }
+ ListElement{ longitude: "40"; latitude: "93"; height: "88"; }
+ ListElement{ longitude: "40"; latitude: "94"; height: "107"; }
+ ListElement{ longitude: "40"; latitude: "95"; height: "139"; }
+ ListElement{ longitude: "40"; latitude: "96"; height: "131"; }
+ ListElement{ longitude: "40"; latitude: "97"; height: "133"; }
+ ListElement{ longitude: "40"; latitude: "98"; height: "133"; }
+ ListElement{ longitude: "40"; latitude: "99"; height: "129"; }
+ ListElement{ longitude: "41"; latitude: "0"; height: "122"; }
+ ListElement{ longitude: "41"; latitude: "1"; height: "123"; }
+ ListElement{ longitude: "41"; latitude: "2"; height: "123"; }
+ ListElement{ longitude: "41"; latitude: "3"; height: "121"; }
+ ListElement{ longitude: "41"; latitude: "4"; height: "122"; }
+ ListElement{ longitude: "41"; latitude: "5"; height: "121"; }
+ ListElement{ longitude: "41"; latitude: "6"; height: "124"; }
+ ListElement{ longitude: "41"; latitude: "7"; height: "125"; }
+ ListElement{ longitude: "41"; latitude: "8"; height: "128"; }
+ ListElement{ longitude: "41"; latitude: "9"; height: "129"; }
+ ListElement{ longitude: "41"; latitude: "10"; height: "128"; }
+ ListElement{ longitude: "41"; latitude: "11"; height: "130"; }
+ ListElement{ longitude: "41"; latitude: "12"; height: "131"; }
+ ListElement{ longitude: "41"; latitude: "13"; height: "120"; }
+ ListElement{ longitude: "41"; latitude: "14"; height: "112"; }
+ ListElement{ longitude: "41"; latitude: "15"; height: "122"; }
+ ListElement{ longitude: "41"; latitude: "16"; height: "125"; }
+ ListElement{ longitude: "41"; latitude: "17"; height: "126"; }
+ ListElement{ longitude: "41"; latitude: "18"; height: "125"; }
+ ListElement{ longitude: "41"; latitude: "19"; height: "127"; }
+ ListElement{ longitude: "41"; latitude: "20"; height: "126"; }
+ ListElement{ longitude: "41"; latitude: "21"; height: "128"; }
+ ListElement{ longitude: "41"; latitude: "22"; height: "128"; }
+ ListElement{ longitude: "41"; latitude: "23"; height: "126"; }
+ ListElement{ longitude: "41"; latitude: "24"; height: "127"; }
+ ListElement{ longitude: "41"; latitude: "25"; height: "131"; }
+ ListElement{ longitude: "41"; latitude: "26"; height: "131"; }
+ ListElement{ longitude: "41"; latitude: "27"; height: "129"; }
+ ListElement{ longitude: "41"; latitude: "28"; height: "129"; }
+ ListElement{ longitude: "41"; latitude: "29"; height: "126"; }
+ ListElement{ longitude: "41"; latitude: "30"; height: "124"; }
+ ListElement{ longitude: "41"; latitude: "31"; height: "127"; }
+ ListElement{ longitude: "41"; latitude: "32"; height: "125"; }
+ ListElement{ longitude: "41"; latitude: "33"; height: "126"; }
+ ListElement{ longitude: "41"; latitude: "34"; height: "126"; }
+ ListElement{ longitude: "41"; latitude: "35"; height: "123"; }
+ ListElement{ longitude: "41"; latitude: "36"; height: "118"; }
+ ListElement{ longitude: "41"; latitude: "37"; height: "123"; }
+ ListElement{ longitude: "41"; latitude: "38"; height: "125"; }
+ ListElement{ longitude: "41"; latitude: "39"; height: "125"; }
+ ListElement{ longitude: "41"; latitude: "40"; height: "124"; }
+ ListElement{ longitude: "41"; latitude: "41"; height: "124"; }
+ ListElement{ longitude: "41"; latitude: "42"; height: "127"; }
+ ListElement{ longitude: "41"; latitude: "43"; height: "127"; }
+ ListElement{ longitude: "41"; latitude: "44"; height: "127"; }
+ ListElement{ longitude: "41"; latitude: "45"; height: "125"; }
+ ListElement{ longitude: "41"; latitude: "46"; height: "121"; }
+ ListElement{ longitude: "41"; latitude: "47"; height: "119"; }
+ ListElement{ longitude: "41"; latitude: "48"; height: "117"; }
+ ListElement{ longitude: "41"; latitude: "49"; height: "116"; }
+ ListElement{ longitude: "41"; latitude: "50"; height: "117"; }
+ ListElement{ longitude: "41"; latitude: "51"; height: "118"; }
+ ListElement{ longitude: "41"; latitude: "52"; height: "119"; }
+ ListElement{ longitude: "41"; latitude: "53"; height: "120"; }
+ ListElement{ longitude: "41"; latitude: "54"; height: "120"; }
+ ListElement{ longitude: "41"; latitude: "55"; height: "118"; }
+ ListElement{ longitude: "41"; latitude: "56"; height: "120"; }
+ ListElement{ longitude: "41"; latitude: "57"; height: "122"; }
+ ListElement{ longitude: "41"; latitude: "58"; height: "125"; }
+ ListElement{ longitude: "41"; latitude: "59"; height: "124"; }
+ ListElement{ longitude: "41"; latitude: "60"; height: "126"; }
+ ListElement{ longitude: "41"; latitude: "61"; height: "128"; }
+ ListElement{ longitude: "41"; latitude: "62"; height: "130"; }
+ ListElement{ longitude: "41"; latitude: "63"; height: "130"; }
+ ListElement{ longitude: "41"; latitude: "64"; height: "135"; }
+ ListElement{ longitude: "41"; latitude: "65"; height: "135"; }
+ ListElement{ longitude: "41"; latitude: "66"; height: "137"; }
+ ListElement{ longitude: "41"; latitude: "67"; height: "136"; }
+ ListElement{ longitude: "41"; latitude: "68"; height: "135"; }
+ ListElement{ longitude: "41"; latitude: "69"; height: "141"; }
+ ListElement{ longitude: "41"; latitude: "70"; height: "148"; }
+ ListElement{ longitude: "41"; latitude: "71"; height: "159"; }
+ ListElement{ longitude: "41"; latitude: "72"; height: "160"; }
+ ListElement{ longitude: "41"; latitude: "73"; height: "160"; }
+ ListElement{ longitude: "41"; latitude: "74"; height: "148"; }
+ ListElement{ longitude: "41"; latitude: "75"; height: "122"; }
+ ListElement{ longitude: "41"; latitude: "76"; height: "75"; }
+ ListElement{ longitude: "41"; latitude: "77"; height: "4"; }
+ ListElement{ longitude: "41"; latitude: "78"; height: "50"; }
+ ListElement{ longitude: "41"; latitude: "79"; height: "50"; }
+ ListElement{ longitude: "41"; latitude: "80"; height: "46"; }
+ ListElement{ longitude: "41"; latitude: "81"; height: "3"; }
+ ListElement{ longitude: "41"; latitude: "82"; height: "1"; }
+ ListElement{ longitude: "41"; latitude: "83"; height: "1"; }
+ ListElement{ longitude: "41"; latitude: "84"; height: "19"; }
+ ListElement{ longitude: "41"; latitude: "85"; height: "16"; }
+ ListElement{ longitude: "41"; latitude: "86"; height: "1"; }
+ ListElement{ longitude: "41"; latitude: "87"; height: "4"; }
+ ListElement{ longitude: "41"; latitude: "88"; height: "30"; }
+ ListElement{ longitude: "41"; latitude: "89"; height: "18"; }
+ ListElement{ longitude: "41"; latitude: "90"; height: "19"; }
+ ListElement{ longitude: "41"; latitude: "91"; height: "40"; }
+ ListElement{ longitude: "41"; latitude: "92"; height: "64"; }
+ ListElement{ longitude: "41"; latitude: "93"; height: "80"; }
+ ListElement{ longitude: "41"; latitude: "94"; height: "102"; }
+ ListElement{ longitude: "41"; latitude: "95"; height: "125"; }
+ ListElement{ longitude: "41"; latitude: "96"; height: "143"; }
+ ListElement{ longitude: "41"; latitude: "97"; height: "138"; }
+ ListElement{ longitude: "41"; latitude: "98"; height: "131"; }
+ ListElement{ longitude: "41"; latitude: "99"; height: "130"; }
+ ListElement{ longitude: "42"; latitude: "0"; height: "122"; }
+ ListElement{ longitude: "42"; latitude: "1"; height: "124"; }
+ ListElement{ longitude: "42"; latitude: "2"; height: "124"; }
+ ListElement{ longitude: "42"; latitude: "3"; height: "123"; }
+ ListElement{ longitude: "42"; latitude: "4"; height: "121"; }
+ ListElement{ longitude: "42"; latitude: "5"; height: "121"; }
+ ListElement{ longitude: "42"; latitude: "6"; height: "123"; }
+ ListElement{ longitude: "42"; latitude: "7"; height: "125"; }
+ ListElement{ longitude: "42"; latitude: "8"; height: "129"; }
+ ListElement{ longitude: "42"; latitude: "9"; height: "128"; }
+ ListElement{ longitude: "42"; latitude: "10"; height: "128"; }
+ ListElement{ longitude: "42"; latitude: "11"; height: "130"; }
+ ListElement{ longitude: "42"; latitude: "12"; height: "131"; }
+ ListElement{ longitude: "42"; latitude: "13"; height: "126"; }
+ ListElement{ longitude: "42"; latitude: "14"; height: "120"; }
+ ListElement{ longitude: "42"; latitude: "15"; height: "122"; }
+ ListElement{ longitude: "42"; latitude: "16"; height: "123"; }
+ ListElement{ longitude: "42"; latitude: "17"; height: "126"; }
+ ListElement{ longitude: "42"; latitude: "18"; height: "125"; }
+ ListElement{ longitude: "42"; latitude: "19"; height: "127"; }
+ ListElement{ longitude: "42"; latitude: "20"; height: "126"; }
+ ListElement{ longitude: "42"; latitude: "21"; height: "128"; }
+ ListElement{ longitude: "42"; latitude: "22"; height: "126"; }
+ ListElement{ longitude: "42"; latitude: "23"; height: "125"; }
+ ListElement{ longitude: "42"; latitude: "24"; height: "127"; }
+ ListElement{ longitude: "42"; latitude: "25"; height: "126"; }
+ ListElement{ longitude: "42"; latitude: "26"; height: "127"; }
+ ListElement{ longitude: "42"; latitude: "27"; height: "127"; }
+ ListElement{ longitude: "42"; latitude: "28"; height: "125"; }
+ ListElement{ longitude: "42"; latitude: "29"; height: "125"; }
+ ListElement{ longitude: "42"; latitude: "30"; height: "123"; }
+ ListElement{ longitude: "42"; latitude: "31"; height: "127"; }
+ ListElement{ longitude: "42"; latitude: "32"; height: "125"; }
+ ListElement{ longitude: "42"; latitude: "33"; height: "126"; }
+ ListElement{ longitude: "42"; latitude: "34"; height: "126"; }
+ ListElement{ longitude: "42"; latitude: "35"; height: "127"; }
+ ListElement{ longitude: "42"; latitude: "36"; height: "126"; }
+ ListElement{ longitude: "42"; latitude: "37"; height: "120"; }
+ ListElement{ longitude: "42"; latitude: "38"; height: "122"; }
+ ListElement{ longitude: "42"; latitude: "39"; height: "123"; }
+ ListElement{ longitude: "42"; latitude: "40"; height: "123"; }
+ ListElement{ longitude: "42"; latitude: "41"; height: "125"; }
+ ListElement{ longitude: "42"; latitude: "42"; height: "126"; }
+ ListElement{ longitude: "42"; latitude: "43"; height: "127"; }
+ ListElement{ longitude: "42"; latitude: "44"; height: "127"; }
+ ListElement{ longitude: "42"; latitude: "45"; height: "125"; }
+ ListElement{ longitude: "42"; latitude: "46"; height: "121"; }
+ ListElement{ longitude: "42"; latitude: "47"; height: "119"; }
+ ListElement{ longitude: "42"; latitude: "48"; height: "117"; }
+ ListElement{ longitude: "42"; latitude: "49"; height: "116"; }
+ ListElement{ longitude: "42"; latitude: "50"; height: "117"; }
+ ListElement{ longitude: "42"; latitude: "51"; height: "120"; }
+ ListElement{ longitude: "42"; latitude: "52"; height: "122"; }
+ ListElement{ longitude: "42"; latitude: "53"; height: "123"; }
+ ListElement{ longitude: "42"; latitude: "54"; height: "123"; }
+ ListElement{ longitude: "42"; latitude: "55"; height: "121"; }
+ ListElement{ longitude: "42"; latitude: "56"; height: "123"; }
+ ListElement{ longitude: "42"; latitude: "57"; height: "124"; }
+ ListElement{ longitude: "42"; latitude: "58"; height: "125"; }
+ ListElement{ longitude: "42"; latitude: "59"; height: "124"; }
+ ListElement{ longitude: "42"; latitude: "60"; height: "126"; }
+ ListElement{ longitude: "42"; latitude: "61"; height: "125"; }
+ ListElement{ longitude: "42"; latitude: "62"; height: "129"; }
+ ListElement{ longitude: "42"; latitude: "63"; height: "132"; }
+ ListElement{ longitude: "42"; latitude: "64"; height: "137"; }
+ ListElement{ longitude: "42"; latitude: "65"; height: "137"; }
+ ListElement{ longitude: "42"; latitude: "66"; height: "139"; }
+ ListElement{ longitude: "42"; latitude: "67"; height: "135"; }
+ ListElement{ longitude: "42"; latitude: "68"; height: "133"; }
+ ListElement{ longitude: "42"; latitude: "69"; height: "132"; }
+ ListElement{ longitude: "42"; latitude: "70"; height: "141"; }
+ ListElement{ longitude: "42"; latitude: "71"; height: "160"; }
+ ListElement{ longitude: "42"; latitude: "72"; height: "156"; }
+ ListElement{ longitude: "42"; latitude: "73"; height: "159"; }
+ ListElement{ longitude: "42"; latitude: "74"; height: "143"; }
+ ListElement{ longitude: "42"; latitude: "75"; height: "126"; }
+ ListElement{ longitude: "42"; latitude: "76"; height: "72"; }
+ ListElement{ longitude: "42"; latitude: "77"; height: "1"; }
+ ListElement{ longitude: "42"; latitude: "78"; height: "1"; }
+ ListElement{ longitude: "42"; latitude: "79"; height: "1"; }
+ ListElement{ longitude: "42"; latitude: "80"; height: "17"; }
+ ListElement{ longitude: "42"; latitude: "81"; height: "12"; }
+ ListElement{ longitude: "42"; latitude: "82"; height: "1"; }
+ ListElement{ longitude: "42"; latitude: "83"; height: "2"; }
+ ListElement{ longitude: "42"; latitude: "84"; height: "1"; }
+ ListElement{ longitude: "42"; latitude: "85"; height: "1"; }
+ ListElement{ longitude: "42"; latitude: "86"; height: "20"; }
+ ListElement{ longitude: "42"; latitude: "87"; height: "7"; }
+ ListElement{ longitude: "42"; latitude: "88"; height: "20"; }
+ ListElement{ longitude: "42"; latitude: "89"; height: "1"; }
+ ListElement{ longitude: "42"; latitude: "90"; height: "1"; }
+ ListElement{ longitude: "42"; latitude: "91"; height: "34"; }
+ ListElement{ longitude: "42"; latitude: "92"; height: "55"; }
+ ListElement{ longitude: "42"; latitude: "93"; height: "74"; }
+ ListElement{ longitude: "42"; latitude: "94"; height: "91"; }
+ ListElement{ longitude: "42"; latitude: "95"; height: "133"; }
+ ListElement{ longitude: "42"; latitude: "96"; height: "145"; }
+ ListElement{ longitude: "42"; latitude: "97"; height: "139"; }
+ ListElement{ longitude: "42"; latitude: "98"; height: "133"; }
+ ListElement{ longitude: "42"; latitude: "99"; height: "128"; }
+ ListElement{ longitude: "43"; latitude: "0"; height: "122"; }
+ ListElement{ longitude: "43"; latitude: "1"; height: "122"; }
+ ListElement{ longitude: "43"; latitude: "2"; height: "124"; }
+ ListElement{ longitude: "43"; latitude: "3"; height: "122"; }
+ ListElement{ longitude: "43"; latitude: "4"; height: "123"; }
+ ListElement{ longitude: "43"; latitude: "5"; height: "122"; }
+ ListElement{ longitude: "43"; latitude: "6"; height: "125"; }
+ ListElement{ longitude: "43"; latitude: "7"; height: "127"; }
+ ListElement{ longitude: "43"; latitude: "8"; height: "131"; }
+ ListElement{ longitude: "43"; latitude: "9"; height: "130"; }
+ ListElement{ longitude: "43"; latitude: "10"; height: "128"; }
+ ListElement{ longitude: "43"; latitude: "11"; height: "128"; }
+ ListElement{ longitude: "43"; latitude: "12"; height: "129"; }
+ ListElement{ longitude: "43"; latitude: "13"; height: "128"; }
+ ListElement{ longitude: "43"; latitude: "14"; height: "124"; }
+ ListElement{ longitude: "43"; latitude: "15"; height: "124"; }
+ ListElement{ longitude: "43"; latitude: "16"; height: "126"; }
+ ListElement{ longitude: "43"; latitude: "17"; height: "125"; }
+ ListElement{ longitude: "43"; latitude: "18"; height: "127"; }
+ ListElement{ longitude: "43"; latitude: "19"; height: "127"; }
+ ListElement{ longitude: "43"; latitude: "20"; height: "126"; }
+ ListElement{ longitude: "43"; latitude: "21"; height: "126"; }
+ ListElement{ longitude: "43"; latitude: "22"; height: "127"; }
+ ListElement{ longitude: "43"; latitude: "23"; height: "127"; }
+ ListElement{ longitude: "43"; latitude: "24"; height: "127"; }
+ ListElement{ longitude: "43"; latitude: "25"; height: "127"; }
+ ListElement{ longitude: "43"; latitude: "26"; height: "127"; }
+ ListElement{ longitude: "43"; latitude: "27"; height: "127"; }
+ ListElement{ longitude: "43"; latitude: "28"; height: "127"; }
+ ListElement{ longitude: "43"; latitude: "29"; height: "127"; }
+ ListElement{ longitude: "43"; latitude: "30"; height: "127"; }
+ ListElement{ longitude: "43"; latitude: "31"; height: "127"; }
+ ListElement{ longitude: "43"; latitude: "32"; height: "125"; }
+ ListElement{ longitude: "43"; latitude: "33"; height: "126"; }
+ ListElement{ longitude: "43"; latitude: "34"; height: "126"; }
+ ListElement{ longitude: "43"; latitude: "35"; height: "124"; }
+ ListElement{ longitude: "43"; latitude: "36"; height: "125"; }
+ ListElement{ longitude: "43"; latitude: "37"; height: "120"; }
+ ListElement{ longitude: "43"; latitude: "38"; height: "126"; }
+ ListElement{ longitude: "43"; latitude: "39"; height: "122"; }
+ ListElement{ longitude: "43"; latitude: "40"; height: "122"; }
+ ListElement{ longitude: "43"; latitude: "41"; height: "123"; }
+ ListElement{ longitude: "43"; latitude: "42"; height: "124"; }
+ ListElement{ longitude: "43"; latitude: "43"; height: "125"; }
+ ListElement{ longitude: "43"; latitude: "44"; height: "128"; }
+ ListElement{ longitude: "43"; latitude: "45"; height: "124"; }
+ ListElement{ longitude: "43"; latitude: "46"; height: "120"; }
+ ListElement{ longitude: "43"; latitude: "47"; height: "121"; }
+ ListElement{ longitude: "43"; latitude: "48"; height: "118"; }
+ ListElement{ longitude: "43"; latitude: "49"; height: "117"; }
+ ListElement{ longitude: "43"; latitude: "50"; height: "117"; }
+ ListElement{ longitude: "43"; latitude: "51"; height: "119"; }
+ ListElement{ longitude: "43"; latitude: "52"; height: "123"; }
+ ListElement{ longitude: "43"; latitude: "53"; height: "126"; }
+ ListElement{ longitude: "43"; latitude: "54"; height: "124"; }
+ ListElement{ longitude: "43"; latitude: "55"; height: "123"; }
+ ListElement{ longitude: "43"; latitude: "56"; height: "121"; }
+ ListElement{ longitude: "43"; latitude: "57"; height: "122"; }
+ ListElement{ longitude: "43"; latitude: "58"; height: "125"; }
+ ListElement{ longitude: "43"; latitude: "59"; height: "125"; }
+ ListElement{ longitude: "43"; latitude: "60"; height: "125"; }
+ ListElement{ longitude: "43"; latitude: "61"; height: "124"; }
+ ListElement{ longitude: "43"; latitude: "62"; height: "126"; }
+ ListElement{ longitude: "43"; latitude: "63"; height: "131"; }
+ ListElement{ longitude: "43"; latitude: "64"; height: "135"; }
+ ListElement{ longitude: "43"; latitude: "65"; height: "139"; }
+ ListElement{ longitude: "43"; latitude: "66"; height: "140"; }
+ ListElement{ longitude: "43"; latitude: "67"; height: "137"; }
+ ListElement{ longitude: "43"; latitude: "68"; height: "139"; }
+ ListElement{ longitude: "43"; latitude: "69"; height: "138"; }
+ ListElement{ longitude: "43"; latitude: "70"; height: "145"; }
+ ListElement{ longitude: "43"; latitude: "71"; height: "162"; }
+ ListElement{ longitude: "43"; latitude: "72"; height: "154"; }
+ ListElement{ longitude: "43"; latitude: "73"; height: "153"; }
+ ListElement{ longitude: "43"; latitude: "74"; height: "136"; }
+ ListElement{ longitude: "43"; latitude: "75"; height: "132"; }
+ ListElement{ longitude: "43"; latitude: "76"; height: "101"; }
+ ListElement{ longitude: "43"; latitude: "77"; height: "32"; }
+ ListElement{ longitude: "43"; latitude: "78"; height: "1"; }
+ ListElement{ longitude: "43"; latitude: "79"; height: "1"; }
+ ListElement{ longitude: "43"; latitude: "80"; height: "23"; }
+ ListElement{ longitude: "43"; latitude: "81"; height: "51"; }
+ ListElement{ longitude: "43"; latitude: "82"; height: "50"; }
+ ListElement{ longitude: "43"; latitude: "83"; height: "65"; }
+ ListElement{ longitude: "43"; latitude: "84"; height: "30"; }
+ ListElement{ longitude: "43"; latitude: "85"; height: "16"; }
+ ListElement{ longitude: "43"; latitude: "86"; height: "1"; }
+ ListElement{ longitude: "43"; latitude: "87"; height: "1"; }
+ ListElement{ longitude: "43"; latitude: "88"; height: "8"; }
+ ListElement{ longitude: "43"; latitude: "89"; height: "2"; }
+ ListElement{ longitude: "43"; latitude: "90"; height: "1"; }
+ ListElement{ longitude: "43"; latitude: "91"; height: "22"; }
+ ListElement{ longitude: "43"; latitude: "92"; height: "42"; }
+ ListElement{ longitude: "43"; latitude: "93"; height: "71"; }
+ ListElement{ longitude: "43"; latitude: "94"; height: "86"; }
+ ListElement{ longitude: "43"; latitude: "95"; height: "109"; }
+ ListElement{ longitude: "43"; latitude: "96"; height: "139"; }
+ ListElement{ longitude: "43"; latitude: "97"; height: "140"; }
+ ListElement{ longitude: "43"; latitude: "98"; height: "131"; }
+ ListElement{ longitude: "43"; latitude: "99"; height: "124"; }
+ ListElement{ longitude: "44"; latitude: "0"; height: "122"; }
+ ListElement{ longitude: "44"; latitude: "1"; height: "123"; }
+ ListElement{ longitude: "44"; latitude: "2"; height: "126"; }
+ ListElement{ longitude: "44"; latitude: "3"; height: "124"; }
+ ListElement{ longitude: "44"; latitude: "4"; height: "122"; }
+ ListElement{ longitude: "44"; latitude: "5"; height: "123"; }
+ ListElement{ longitude: "44"; latitude: "6"; height: "126"; }
+ ListElement{ longitude: "44"; latitude: "7"; height: "126"; }
+ ListElement{ longitude: "44"; latitude: "8"; height: "129"; }
+ ListElement{ longitude: "44"; latitude: "9"; height: "130"; }
+ ListElement{ longitude: "44"; latitude: "10"; height: "128"; }
+ ListElement{ longitude: "44"; latitude: "11"; height: "129"; }
+ ListElement{ longitude: "44"; latitude: "12"; height: "129"; }
+ ListElement{ longitude: "44"; latitude: "13"; height: "126"; }
+ ListElement{ longitude: "44"; latitude: "14"; height: "127"; }
+ ListElement{ longitude: "44"; latitude: "15"; height: "127"; }
+ ListElement{ longitude: "44"; latitude: "16"; height: "127"; }
+ ListElement{ longitude: "44"; latitude: "17"; height: "127"; }
+ ListElement{ longitude: "44"; latitude: "18"; height: "127"; }
+ ListElement{ longitude: "44"; latitude: "19"; height: "127"; }
+ ListElement{ longitude: "44"; latitude: "20"; height: "127"; }
+ ListElement{ longitude: "44"; latitude: "21"; height: "127"; }
+ ListElement{ longitude: "44"; latitude: "22"; height: "127"; }
+ ListElement{ longitude: "44"; latitude: "23"; height: "127"; }
+ ListElement{ longitude: "44"; latitude: "24"; height: "127"; }
+ ListElement{ longitude: "44"; latitude: "25"; height: "127"; }
+ ListElement{ longitude: "44"; latitude: "26"; height: "127"; }
+ ListElement{ longitude: "44"; latitude: "27"; height: "127"; }
+ ListElement{ longitude: "44"; latitude: "28"; height: "127"; }
+ ListElement{ longitude: "44"; latitude: "29"; height: "127"; }
+ ListElement{ longitude: "44"; latitude: "30"; height: "127"; }
+ ListElement{ longitude: "44"; latitude: "31"; height: "127"; }
+ ListElement{ longitude: "44"; latitude: "32"; height: "125"; }
+ ListElement{ longitude: "44"; latitude: "33"; height: "126"; }
+ ListElement{ longitude: "44"; latitude: "34"; height: "126"; }
+ ListElement{ longitude: "44"; latitude: "35"; height: "124"; }
+ ListElement{ longitude: "44"; latitude: "36"; height: "124"; }
+ ListElement{ longitude: "44"; latitude: "37"; height: "124"; }
+ ListElement{ longitude: "44"; latitude: "38"; height: "127"; }
+ ListElement{ longitude: "44"; latitude: "39"; height: "121"; }
+ ListElement{ longitude: "44"; latitude: "40"; height: "124"; }
+ ListElement{ longitude: "44"; latitude: "41"; height: "123"; }
+ ListElement{ longitude: "44"; latitude: "42"; height: "126"; }
+ ListElement{ longitude: "44"; latitude: "43"; height: "126"; }
+ ListElement{ longitude: "44"; latitude: "44"; height: "126"; }
+ ListElement{ longitude: "44"; latitude: "45"; height: "122"; }
+ ListElement{ longitude: "44"; latitude: "46"; height: "120"; }
+ ListElement{ longitude: "44"; latitude: "47"; height: "122"; }
+ ListElement{ longitude: "44"; latitude: "48"; height: "121"; }
+ ListElement{ longitude: "44"; latitude: "49"; height: "118"; }
+ ListElement{ longitude: "44"; latitude: "50"; height: "118"; }
+ ListElement{ longitude: "44"; latitude: "51"; height: "121"; }
+ ListElement{ longitude: "44"; latitude: "52"; height: "121"; }
+ ListElement{ longitude: "44"; latitude: "53"; height: "124"; }
+ ListElement{ longitude: "44"; latitude: "54"; height: "124"; }
+ ListElement{ longitude: "44"; latitude: "55"; height: "122"; }
+ ListElement{ longitude: "44"; latitude: "56"; height: "123"; }
+ ListElement{ longitude: "44"; latitude: "57"; height: "122"; }
+ ListElement{ longitude: "44"; latitude: "58"; height: "124"; }
+ ListElement{ longitude: "44"; latitude: "59"; height: "124"; }
+ ListElement{ longitude: "44"; latitude: "60"; height: "124"; }
+ ListElement{ longitude: "44"; latitude: "61"; height: "122"; }
+ ListElement{ longitude: "44"; latitude: "62"; height: "125"; }
+ ListElement{ longitude: "44"; latitude: "63"; height: "129"; }
+ ListElement{ longitude: "44"; latitude: "64"; height: "134"; }
+ ListElement{ longitude: "44"; latitude: "65"; height: "139"; }
+ ListElement{ longitude: "44"; latitude: "66"; height: "139"; }
+ ListElement{ longitude: "44"; latitude: "67"; height: "138"; }
+ ListElement{ longitude: "44"; latitude: "68"; height: "131"; }
+ ListElement{ longitude: "44"; latitude: "69"; height: "130"; }
+ ListElement{ longitude: "44"; latitude: "70"; height: "133"; }
+ ListElement{ longitude: "44"; latitude: "71"; height: "157"; }
+ ListElement{ longitude: "44"; latitude: "72"; height: "153"; }
+ ListElement{ longitude: "44"; latitude: "73"; height: "148"; }
+ ListElement{ longitude: "44"; latitude: "74"; height: "123"; }
+ ListElement{ longitude: "44"; latitude: "75"; height: "108"; }
+ ListElement{ longitude: "44"; latitude: "76"; height: "85"; }
+ ListElement{ longitude: "44"; latitude: "77"; height: "19"; }
+ ListElement{ longitude: "44"; latitude: "78"; height: "1"; }
+ ListElement{ longitude: "44"; latitude: "79"; height: "48"; }
+ ListElement{ longitude: "44"; latitude: "80"; height: "102"; }
+ ListElement{ longitude: "44"; latitude: "81"; height: "112"; }
+ ListElement{ longitude: "44"; latitude: "82"; height: "99"; }
+ ListElement{ longitude: "44"; latitude: "83"; height: "90"; }
+ ListElement{ longitude: "44"; latitude: "84"; height: "71"; }
+ ListElement{ longitude: "44"; latitude: "85"; height: "26"; }
+ ListElement{ longitude: "44"; latitude: "86"; height: "14"; }
+ ListElement{ longitude: "44"; latitude: "87"; height: "1"; }
+ ListElement{ longitude: "44"; latitude: "88"; height: "2"; }
+ ListElement{ longitude: "44"; latitude: "89"; height: "5"; }
+ ListElement{ longitude: "44"; latitude: "90"; height: "1"; }
+ ListElement{ longitude: "44"; latitude: "91"; height: "8"; }
+ ListElement{ longitude: "44"; latitude: "92"; height: "51"; }
+ ListElement{ longitude: "44"; latitude: "93"; height: "67"; }
+ ListElement{ longitude: "44"; latitude: "94"; height: "90"; }
+ ListElement{ longitude: "44"; latitude: "95"; height: "102"; }
+ ListElement{ longitude: "44"; latitude: "96"; height: "132"; }
+ ListElement{ longitude: "44"; latitude: "97"; height: "149"; }
+ ListElement{ longitude: "44"; latitude: "98"; height: "145"; }
+ ListElement{ longitude: "44"; latitude: "99"; height: "128"; }
+ ListElement{ longitude: "45"; latitude: "0"; height: "120"; }
+ ListElement{ longitude: "45"; latitude: "1"; height: "121"; }
+ ListElement{ longitude: "45"; latitude: "2"; height: "124"; }
+ ListElement{ longitude: "45"; latitude: "3"; height: "122"; }
+ ListElement{ longitude: "45"; latitude: "4"; height: "122"; }
+ ListElement{ longitude: "45"; latitude: "5"; height: "123"; }
+ ListElement{ longitude: "45"; latitude: "6"; height: "126"; }
+ ListElement{ longitude: "45"; latitude: "7"; height: "127"; }
+ ListElement{ longitude: "45"; latitude: "8"; height: "128"; }
+ ListElement{ longitude: "45"; latitude: "9"; height: "129"; }
+ ListElement{ longitude: "45"; latitude: "10"; height: "129"; }
+ ListElement{ longitude: "45"; latitude: "11"; height: "129"; }
+ ListElement{ longitude: "45"; latitude: "12"; height: "130"; }
+ ListElement{ longitude: "45"; latitude: "13"; height: "126"; }
+ ListElement{ longitude: "45"; latitude: "14"; height: "127"; }
+ ListElement{ longitude: "45"; latitude: "15"; height: "127"; }
+ ListElement{ longitude: "45"; latitude: "16"; height: "127"; }
+ ListElement{ longitude: "45"; latitude: "17"; height: "127"; }
+ ListElement{ longitude: "45"; latitude: "18"; height: "127"; }
+ ListElement{ longitude: "45"; latitude: "19"; height: "127"; }
+ ListElement{ longitude: "45"; latitude: "20"; height: "127"; }
+ ListElement{ longitude: "45"; latitude: "21"; height: "126"; }
+ ListElement{ longitude: "45"; latitude: "22"; height: "126"; }
+ ListElement{ longitude: "45"; latitude: "23"; height: "126"; }
+ ListElement{ longitude: "45"; latitude: "24"; height: "126"; }
+ ListElement{ longitude: "45"; latitude: "25"; height: "127"; }
+ ListElement{ longitude: "45"; latitude: "26"; height: "127"; }
+ ListElement{ longitude: "45"; latitude: "27"; height: "127"; }
+ ListElement{ longitude: "45"; latitude: "28"; height: "127"; }
+ ListElement{ longitude: "45"; latitude: "29"; height: "127"; }
+ ListElement{ longitude: "45"; latitude: "30"; height: "127"; }
+ ListElement{ longitude: "45"; latitude: "31"; height: "127"; }
+ ListElement{ longitude: "45"; latitude: "32"; height: "125"; }
+ ListElement{ longitude: "45"; latitude: "33"; height: "125"; }
+ ListElement{ longitude: "45"; latitude: "34"; height: "126"; }
+ ListElement{ longitude: "45"; latitude: "35"; height: "127"; }
+ ListElement{ longitude: "45"; latitude: "36"; height: "127"; }
+ ListElement{ longitude: "45"; latitude: "37"; height: "127"; }
+ ListElement{ longitude: "45"; latitude: "38"; height: "126"; }
+ ListElement{ longitude: "45"; latitude: "39"; height: "123"; }
+ ListElement{ longitude: "45"; latitude: "40"; height: "125"; }
+ ListElement{ longitude: "45"; latitude: "41"; height: "125"; }
+ ListElement{ longitude: "45"; latitude: "42"; height: "126"; }
+ ListElement{ longitude: "45"; latitude: "43"; height: "126"; }
+ ListElement{ longitude: "45"; latitude: "44"; height: "127"; }
+ ListElement{ longitude: "45"; latitude: "45"; height: "120"; }
+ ListElement{ longitude: "45"; latitude: "46"; height: "120"; }
+ ListElement{ longitude: "45"; latitude: "47"; height: "122"; }
+ ListElement{ longitude: "45"; latitude: "48"; height: "121"; }
+ ListElement{ longitude: "45"; latitude: "49"; height: "120"; }
+ ListElement{ longitude: "45"; latitude: "50"; height: "118"; }
+ ListElement{ longitude: "45"; latitude: "51"; height: "121"; }
+ ListElement{ longitude: "45"; latitude: "52"; height: "122"; }
+ ListElement{ longitude: "45"; latitude: "53"; height: "123"; }
+ ListElement{ longitude: "45"; latitude: "54"; height: "124"; }
+ ListElement{ longitude: "45"; latitude: "55"; height: "123"; }
+ ListElement{ longitude: "45"; latitude: "56"; height: "123"; }
+ ListElement{ longitude: "45"; latitude: "57"; height: "123"; }
+ ListElement{ longitude: "45"; latitude: "58"; height: "121"; }
+ ListElement{ longitude: "45"; latitude: "59"; height: "122"; }
+ ListElement{ longitude: "45"; latitude: "60"; height: "120"; }
+ ListElement{ longitude: "45"; latitude: "61"; height: "119"; }
+ ListElement{ longitude: "45"; latitude: "62"; height: "120"; }
+ ListElement{ longitude: "45"; latitude: "63"; height: "123"; }
+ ListElement{ longitude: "45"; latitude: "64"; height: "128"; }
+ ListElement{ longitude: "45"; latitude: "65"; height: "132"; }
+ ListElement{ longitude: "45"; latitude: "66"; height: "133"; }
+ ListElement{ longitude: "45"; latitude: "67"; height: "133"; }
+ ListElement{ longitude: "45"; latitude: "68"; height: "131"; }
+ ListElement{ longitude: "45"; latitude: "69"; height: "128"; }
+ ListElement{ longitude: "45"; latitude: "70"; height: "131"; }
+ ListElement{ longitude: "45"; latitude: "71"; height: "156"; }
+ ListElement{ longitude: "45"; latitude: "72"; height: "148"; }
+ ListElement{ longitude: "45"; latitude: "73"; height: "148"; }
+ ListElement{ longitude: "45"; latitude: "74"; height: "117"; }
+ ListElement{ longitude: "45"; latitude: "75"; height: "86"; }
+ ListElement{ longitude: "45"; latitude: "76"; height: "72"; }
+ ListElement{ longitude: "45"; latitude: "77"; height: "42"; }
+ ListElement{ longitude: "45"; latitude: "78"; height: "42"; }
+ ListElement{ longitude: "45"; latitude: "79"; height: "84"; }
+ ListElement{ longitude: "45"; latitude: "80"; height: "116"; }
+ ListElement{ longitude: "45"; latitude: "81"; height: "95"; }
+ ListElement{ longitude: "45"; latitude: "82"; height: "94"; }
+ ListElement{ longitude: "45"; latitude: "83"; height: "84"; }
+ ListElement{ longitude: "45"; latitude: "84"; height: "63"; }
+ ListElement{ longitude: "45"; latitude: "85"; height: "21"; }
+ ListElement{ longitude: "45"; latitude: "86"; height: "18"; }
+ ListElement{ longitude: "45"; latitude: "87"; height: "1"; }
+ ListElement{ longitude: "45"; latitude: "88"; height: "1"; }
+ ListElement{ longitude: "45"; latitude: "89"; height: "2"; }
+ ListElement{ longitude: "45"; latitude: "90"; height: "1"; }
+ ListElement{ longitude: "45"; latitude: "91"; height: "1"; }
+ ListElement{ longitude: "45"; latitude: "92"; height: "39"; }
+ ListElement{ longitude: "45"; latitude: "93"; height: "58"; }
+ ListElement{ longitude: "45"; latitude: "94"; height: "90"; }
+ ListElement{ longitude: "45"; latitude: "95"; height: "103"; }
+ ListElement{ longitude: "45"; latitude: "96"; height: "136"; }
+ ListElement{ longitude: "45"; latitude: "97"; height: "149"; }
+ ListElement{ longitude: "45"; latitude: "98"; height: "140"; }
+ ListElement{ longitude: "45"; latitude: "99"; height: "128"; }
+ ListElement{ longitude: "46"; latitude: "0"; height: "120"; }
+ ListElement{ longitude: "46"; latitude: "1"; height: "122"; }
+ ListElement{ longitude: "46"; latitude: "2"; height: "123"; }
+ ListElement{ longitude: "46"; latitude: "3"; height: "122"; }
+ ListElement{ longitude: "46"; latitude: "4"; height: "122"; }
+ ListElement{ longitude: "46"; latitude: "5"; height: "122"; }
+ ListElement{ longitude: "46"; latitude: "6"; height: "125"; }
+ ListElement{ longitude: "46"; latitude: "7"; height: "125"; }
+ ListElement{ longitude: "46"; latitude: "8"; height: "126"; }
+ ListElement{ longitude: "46"; latitude: "9"; height: "129"; }
+ ListElement{ longitude: "46"; latitude: "10"; height: "127"; }
+ ListElement{ longitude: "46"; latitude: "11"; height: "126"; }
+ ListElement{ longitude: "46"; latitude: "12"; height: "126"; }
+ ListElement{ longitude: "46"; latitude: "13"; height: "127"; }
+ ListElement{ longitude: "46"; latitude: "14"; height: "125"; }
+ ListElement{ longitude: "46"; latitude: "15"; height: "125"; }
+ ListElement{ longitude: "46"; latitude: "16"; height: "125"; }
+ ListElement{ longitude: "46"; latitude: "17"; height: "125"; }
+ ListElement{ longitude: "46"; latitude: "18"; height: "127"; }
+ ListElement{ longitude: "46"; latitude: "19"; height: "127"; }
+ ListElement{ longitude: "46"; latitude: "20"; height: "127"; }
+ ListElement{ longitude: "46"; latitude: "21"; height: "127"; }
+ ListElement{ longitude: "46"; latitude: "22"; height: "128"; }
+ ListElement{ longitude: "46"; latitude: "23"; height: "128"; }
+ ListElement{ longitude: "46"; latitude: "24"; height: "127"; }
+ ListElement{ longitude: "46"; latitude: "25"; height: "127"; }
+ ListElement{ longitude: "46"; latitude: "26"; height: "127"; }
+ ListElement{ longitude: "46"; latitude: "27"; height: "127"; }
+ ListElement{ longitude: "46"; latitude: "28"; height: "127"; }
+ ListElement{ longitude: "46"; latitude: "29"; height: "127"; }
+ ListElement{ longitude: "46"; latitude: "30"; height: "125"; }
+ ListElement{ longitude: "46"; latitude: "31"; height: "127"; }
+ ListElement{ longitude: "46"; latitude: "32"; height: "127"; }
+ ListElement{ longitude: "46"; latitude: "33"; height: "126"; }
+ ListElement{ longitude: "46"; latitude: "34"; height: "126"; }
+ ListElement{ longitude: "46"; latitude: "35"; height: "126"; }
+ ListElement{ longitude: "46"; latitude: "36"; height: "127"; }
+ ListElement{ longitude: "46"; latitude: "37"; height: "127"; }
+ ListElement{ longitude: "46"; latitude: "38"; height: "128"; }
+ ListElement{ longitude: "46"; latitude: "39"; height: "126"; }
+ ListElement{ longitude: "46"; latitude: "40"; height: "125"; }
+ ListElement{ longitude: "46"; latitude: "41"; height: "124"; }
+ ListElement{ longitude: "46"; latitude: "42"; height: "124"; }
+ ListElement{ longitude: "46"; latitude: "43"; height: "124"; }
+ ListElement{ longitude: "46"; latitude: "44"; height: "126"; }
+ ListElement{ longitude: "46"; latitude: "45"; height: "124"; }
+ ListElement{ longitude: "46"; latitude: "46"; height: "121"; }
+ ListElement{ longitude: "46"; latitude: "47"; height: "122"; }
+ ListElement{ longitude: "46"; latitude: "48"; height: "119"; }
+ ListElement{ longitude: "46"; latitude: "49"; height: "117"; }
+ ListElement{ longitude: "46"; latitude: "50"; height: "119"; }
+ ListElement{ longitude: "46"; latitude: "51"; height: "119"; }
+ ListElement{ longitude: "46"; latitude: "52"; height: "122"; }
+ ListElement{ longitude: "46"; latitude: "53"; height: "123"; }
+ ListElement{ longitude: "46"; latitude: "54"; height: "123"; }
+ ListElement{ longitude: "46"; latitude: "55"; height: "122"; }
+ ListElement{ longitude: "46"; latitude: "56"; height: "121"; }
+ ListElement{ longitude: "46"; latitude: "57"; height: "121"; }
+ ListElement{ longitude: "46"; latitude: "58"; height: "121"; }
+ ListElement{ longitude: "46"; latitude: "59"; height: "121"; }
+ ListElement{ longitude: "46"; latitude: "60"; height: "118"; }
+ ListElement{ longitude: "46"; latitude: "61"; height: "119"; }
+ ListElement{ longitude: "46"; latitude: "62"; height: "116"; }
+ ListElement{ longitude: "46"; latitude: "63"; height: "118"; }
+ ListElement{ longitude: "46"; latitude: "64"; height: "123"; }
+ ListElement{ longitude: "46"; latitude: "65"; height: "126"; }
+ ListElement{ longitude: "46"; latitude: "66"; height: "130"; }
+ ListElement{ longitude: "46"; latitude: "67"; height: "129"; }
+ ListElement{ longitude: "46"; latitude: "68"; height: "130"; }
+ ListElement{ longitude: "46"; latitude: "69"; height: "131"; }
+ ListElement{ longitude: "46"; latitude: "70"; height: "137"; }
+ ListElement{ longitude: "46"; latitude: "71"; height: "156"; }
+ ListElement{ longitude: "46"; latitude: "72"; height: "151"; }
+ ListElement{ longitude: "46"; latitude: "73"; height: "152"; }
+ ListElement{ longitude: "46"; latitude: "74"; height: "120"; }
+ ListElement{ longitude: "46"; latitude: "75"; height: "85"; }
+ ListElement{ longitude: "46"; latitude: "76"; height: "46"; }
+ ListElement{ longitude: "46"; latitude: "77"; height: "1"; }
+ ListElement{ longitude: "46"; latitude: "78"; height: "1"; }
+ ListElement{ longitude: "46"; latitude: "79"; height: "67"; }
+ ListElement{ longitude: "46"; latitude: "80"; height: "98"; }
+ ListElement{ longitude: "46"; latitude: "81"; height: "68"; }
+ ListElement{ longitude: "46"; latitude: "82"; height: "62"; }
+ ListElement{ longitude: "46"; latitude: "83"; height: "62"; }
+ ListElement{ longitude: "46"; latitude: "84"; height: "77"; }
+ ListElement{ longitude: "46"; latitude: "85"; height: "33"; }
+ ListElement{ longitude: "46"; latitude: "86"; height: "20"; }
+ ListElement{ longitude: "46"; latitude: "87"; height: "1"; }
+ ListElement{ longitude: "46"; latitude: "88"; height: "1"; }
+ ListElement{ longitude: "46"; latitude: "89"; height: "1"; }
+ ListElement{ longitude: "46"; latitude: "90"; height: "1"; }
+ ListElement{ longitude: "46"; latitude: "91"; height: "1"; }
+ ListElement{ longitude: "46"; latitude: "92"; height: "41"; }
+ ListElement{ longitude: "46"; latitude: "93"; height: "70"; }
+ ListElement{ longitude: "46"; latitude: "94"; height: "89"; }
+ ListElement{ longitude: "46"; latitude: "95"; height: "108"; }
+ ListElement{ longitude: "46"; latitude: "96"; height: "129"; }
+ ListElement{ longitude: "46"; latitude: "97"; height: "153"; }
+ ListElement{ longitude: "46"; latitude: "98"; height: "141"; }
+ ListElement{ longitude: "46"; latitude: "99"; height: "129"; }
+ ListElement{ longitude: "47"; latitude: "0"; height: "120"; }
+ ListElement{ longitude: "47"; latitude: "1"; height: "122"; }
+ ListElement{ longitude: "47"; latitude: "2"; height: "123"; }
+ ListElement{ longitude: "47"; latitude: "3"; height: "123"; }
+ ListElement{ longitude: "47"; latitude: "4"; height: "123"; }
+ ListElement{ longitude: "47"; latitude: "5"; height: "122"; }
+ ListElement{ longitude: "47"; latitude: "6"; height: "125"; }
+ ListElement{ longitude: "47"; latitude: "7"; height: "126"; }
+ ListElement{ longitude: "47"; latitude: "8"; height: "127"; }
+ ListElement{ longitude: "47"; latitude: "9"; height: "128"; }
+ ListElement{ longitude: "47"; latitude: "10"; height: "128"; }
+ ListElement{ longitude: "47"; latitude: "11"; height: "126"; }
+ ListElement{ longitude: "47"; latitude: "12"; height: "127"; }
+ ListElement{ longitude: "47"; latitude: "13"; height: "127"; }
+ ListElement{ longitude: "47"; latitude: "14"; height: "125"; }
+ ListElement{ longitude: "47"; latitude: "15"; height: "126"; }
+ ListElement{ longitude: "47"; latitude: "16"; height: "126"; }
+ ListElement{ longitude: "47"; latitude: "17"; height: "125"; }
+ ListElement{ longitude: "47"; latitude: "18"; height: "127"; }
+ ListElement{ longitude: "47"; latitude: "19"; height: "127"; }
+ ListElement{ longitude: "47"; latitude: "20"; height: "127"; }
+ ListElement{ longitude: "47"; latitude: "21"; height: "127"; }
+ ListElement{ longitude: "47"; latitude: "22"; height: "125"; }
+ ListElement{ longitude: "47"; latitude: "23"; height: "125"; }
+ ListElement{ longitude: "47"; latitude: "24"; height: "127"; }
+ ListElement{ longitude: "47"; latitude: "25"; height: "127"; }
+ ListElement{ longitude: "47"; latitude: "26"; height: "127"; }
+ ListElement{ longitude: "47"; latitude: "27"; height: "127"; }
+ ListElement{ longitude: "47"; latitude: "28"; height: "127"; }
+ ListElement{ longitude: "47"; latitude: "29"; height: "127"; }
+ ListElement{ longitude: "47"; latitude: "30"; height: "125"; }
+ ListElement{ longitude: "47"; latitude: "31"; height: "126"; }
+ ListElement{ longitude: "47"; latitude: "32"; height: "124"; }
+ ListElement{ longitude: "47"; latitude: "33"; height: "122"; }
+ ListElement{ longitude: "47"; latitude: "34"; height: "123"; }
+ ListElement{ longitude: "47"; latitude: "35"; height: "122"; }
+ ListElement{ longitude: "47"; latitude: "36"; height: "124"; }
+ ListElement{ longitude: "47"; latitude: "37"; height: "124"; }
+ ListElement{ longitude: "47"; latitude: "38"; height: "123"; }
+ ListElement{ longitude: "47"; latitude: "39"; height: "123"; }
+ ListElement{ longitude: "47"; latitude: "40"; height: "125"; }
+ ListElement{ longitude: "47"; latitude: "41"; height: "125"; }
+ ListElement{ longitude: "47"; latitude: "42"; height: "124"; }
+ ListElement{ longitude: "47"; latitude: "43"; height: "126"; }
+ ListElement{ longitude: "47"; latitude: "44"; height: "126"; }
+ ListElement{ longitude: "47"; latitude: "45"; height: "125"; }
+ ListElement{ longitude: "47"; latitude: "46"; height: "121"; }
+ ListElement{ longitude: "47"; latitude: "47"; height: "120"; }
+ ListElement{ longitude: "47"; latitude: "48"; height: "119"; }
+ ListElement{ longitude: "47"; latitude: "49"; height: "121"; }
+ ListElement{ longitude: "47"; latitude: "50"; height: "122"; }
+ ListElement{ longitude: "47"; latitude: "51"; height: "122"; }
+ ListElement{ longitude: "47"; latitude: "52"; height: "122"; }
+ ListElement{ longitude: "47"; latitude: "53"; height: "120"; }
+ ListElement{ longitude: "47"; latitude: "54"; height: "119"; }
+ ListElement{ longitude: "47"; latitude: "55"; height: "118"; }
+ ListElement{ longitude: "47"; latitude: "56"; height: "117"; }
+ ListElement{ longitude: "47"; latitude: "57"; height: "117"; }
+ ListElement{ longitude: "47"; latitude: "58"; height: "119"; }
+ ListElement{ longitude: "47"; latitude: "59"; height: "119"; }
+ ListElement{ longitude: "47"; latitude: "60"; height: "117"; }
+ ListElement{ longitude: "47"; latitude: "61"; height: "114"; }
+ ListElement{ longitude: "47"; latitude: "62"; height: "111"; }
+ ListElement{ longitude: "47"; latitude: "63"; height: "113"; }
+ ListElement{ longitude: "47"; latitude: "64"; height: "115"; }
+ ListElement{ longitude: "47"; latitude: "65"; height: "118"; }
+ ListElement{ longitude: "47"; latitude: "66"; height: "121"; }
+ ListElement{ longitude: "47"; latitude: "67"; height: "122"; }
+ ListElement{ longitude: "47"; latitude: "68"; height: "125"; }
+ ListElement{ longitude: "47"; latitude: "69"; height: "128"; }
+ ListElement{ longitude: "47"; latitude: "70"; height: "138"; }
+ ListElement{ longitude: "47"; latitude: "71"; height: "161"; }
+ ListElement{ longitude: "47"; latitude: "72"; height: "157"; }
+ ListElement{ longitude: "47"; latitude: "73"; height: "158"; }
+ ListElement{ longitude: "47"; latitude: "74"; height: "120"; }
+ ListElement{ longitude: "47"; latitude: "75"; height: "98"; }
+ ListElement{ longitude: "47"; latitude: "76"; height: "38"; }
+ ListElement{ longitude: "47"; latitude: "77"; height: "4"; }
+ ListElement{ longitude: "47"; latitude: "78"; height: "16"; }
+ ListElement{ longitude: "47"; latitude: "79"; height: "36"; }
+ ListElement{ longitude: "47"; latitude: "80"; height: "103"; }
+ ListElement{ longitude: "47"; latitude: "81"; height: "83"; }
+ ListElement{ longitude: "47"; latitude: "82"; height: "47"; }
+ ListElement{ longitude: "47"; latitude: "83"; height: "72"; }
+ ListElement{ longitude: "47"; latitude: "84"; height: "97"; }
+ ListElement{ longitude: "47"; latitude: "85"; height: "22"; }
+ ListElement{ longitude: "47"; latitude: "86"; height: "18"; }
+ ListElement{ longitude: "47"; latitude: "87"; height: "2"; }
+ ListElement{ longitude: "47"; latitude: "88"; height: "1"; }
+ ListElement{ longitude: "47"; latitude: "89"; height: "1"; }
+ ListElement{ longitude: "47"; latitude: "90"; height: "1"; }
+ ListElement{ longitude: "47"; latitude: "91"; height: "1"; }
+ ListElement{ longitude: "47"; latitude: "92"; height: "43"; }
+ ListElement{ longitude: "47"; latitude: "93"; height: "76"; }
+ ListElement{ longitude: "47"; latitude: "94"; height: "91"; }
+ ListElement{ longitude: "47"; latitude: "95"; height: "106"; }
+ ListElement{ longitude: "47"; latitude: "96"; height: "143"; }
+ ListElement{ longitude: "47"; latitude: "97"; height: "155"; }
+ ListElement{ longitude: "47"; latitude: "98"; height: "141"; }
+ ListElement{ longitude: "47"; latitude: "99"; height: "131"; }
+ ListElement{ longitude: "48"; latitude: "0"; height: "122"; }
+ ListElement{ longitude: "48"; latitude: "1"; height: "123"; }
+ ListElement{ longitude: "48"; latitude: "2"; height: "123"; }
+ ListElement{ longitude: "48"; latitude: "3"; height: "123"; }
+ ListElement{ longitude: "48"; latitude: "4"; height: "119"; }
+ ListElement{ longitude: "48"; latitude: "5"; height: "121"; }
+ ListElement{ longitude: "48"; latitude: "6"; height: "125"; }
+ ListElement{ longitude: "48"; latitude: "7"; height: "126"; }
+ ListElement{ longitude: "48"; latitude: "8"; height: "127"; }
+ ListElement{ longitude: "48"; latitude: "9"; height: "126"; }
+ ListElement{ longitude: "48"; latitude: "10"; height: "126"; }
+ ListElement{ longitude: "48"; latitude: "11"; height: "127"; }
+ ListElement{ longitude: "48"; latitude: "12"; height: "127"; }
+ ListElement{ longitude: "48"; latitude: "13"; height: "126"; }
+ ListElement{ longitude: "48"; latitude: "14"; height: "126"; }
+ ListElement{ longitude: "48"; latitude: "15"; height: "126"; }
+ ListElement{ longitude: "48"; latitude: "16"; height: "126"; }
+ ListElement{ longitude: "48"; latitude: "17"; height: "126"; }
+ ListElement{ longitude: "48"; latitude: "18"; height: "126"; }
+ ListElement{ longitude: "48"; latitude: "19"; height: "126"; }
+ ListElement{ longitude: "48"; latitude: "20"; height: "126"; }
+ ListElement{ longitude: "48"; latitude: "21"; height: "126"; }
+ ListElement{ longitude: "48"; latitude: "22"; height: "126"; }
+ ListElement{ longitude: "48"; latitude: "23"; height: "126"; }
+ ListElement{ longitude: "48"; latitude: "24"; height: "125"; }
+ ListElement{ longitude: "48"; latitude: "25"; height: "127"; }
+ ListElement{ longitude: "48"; latitude: "26"; height: "127"; }
+ ListElement{ longitude: "48"; latitude: "27"; height: "127"; }
+ ListElement{ longitude: "48"; latitude: "28"; height: "126"; }
+ ListElement{ longitude: "48"; latitude: "29"; height: "126"; }
+ ListElement{ longitude: "48"; latitude: "30"; height: "126"; }
+ ListElement{ longitude: "48"; latitude: "31"; height: "126"; }
+ ListElement{ longitude: "48"; latitude: "32"; height: "125"; }
+ ListElement{ longitude: "48"; latitude: "33"; height: "125"; }
+ ListElement{ longitude: "48"; latitude: "34"; height: "125"; }
+ ListElement{ longitude: "48"; latitude: "35"; height: "125"; }
+ ListElement{ longitude: "48"; latitude: "36"; height: "125"; }
+ ListElement{ longitude: "48"; latitude: "37"; height: "125"; }
+ ListElement{ longitude: "48"; latitude: "38"; height: "120"; }
+ ListElement{ longitude: "48"; latitude: "39"; height: "124"; }
+ ListElement{ longitude: "48"; latitude: "40"; height: "125"; }
+ ListElement{ longitude: "48"; latitude: "41"; height: "125"; }
+ ListElement{ longitude: "48"; latitude: "42"; height: "124"; }
+ ListElement{ longitude: "48"; latitude: "43"; height: "126"; }
+ ListElement{ longitude: "48"; latitude: "44"; height: "126"; }
+ ListElement{ longitude: "48"; latitude: "45"; height: "125"; }
+ ListElement{ longitude: "48"; latitude: "46"; height: "119"; }
+ ListElement{ longitude: "48"; latitude: "47"; height: "121"; }
+ ListElement{ longitude: "48"; latitude: "48"; height: "121"; }
+ ListElement{ longitude: "48"; latitude: "49"; height: "122"; }
+ ListElement{ longitude: "48"; latitude: "50"; height: "123"; }
+ ListElement{ longitude: "48"; latitude: "51"; height: "123"; }
+ ListElement{ longitude: "48"; latitude: "52"; height: "122"; }
+ ListElement{ longitude: "48"; latitude: "53"; height: "120"; }
+ ListElement{ longitude: "48"; latitude: "54"; height: "118"; }
+ ListElement{ longitude: "48"; latitude: "55"; height: "115"; }
+ ListElement{ longitude: "48"; latitude: "56"; height: "115"; }
+ ListElement{ longitude: "48"; latitude: "57"; height: "115"; }
+ ListElement{ longitude: "48"; latitude: "58"; height: "116"; }
+ ListElement{ longitude: "48"; latitude: "59"; height: "116"; }
+ ListElement{ longitude: "48"; latitude: "60"; height: "113"; }
+ ListElement{ longitude: "48"; latitude: "61"; height: "113"; }
+ ListElement{ longitude: "48"; latitude: "62"; height: "110"; }
+ ListElement{ longitude: "48"; latitude: "63"; height: "108"; }
+ ListElement{ longitude: "48"; latitude: "64"; height: "109"; }
+ ListElement{ longitude: "48"; latitude: "65"; height: "115"; }
+ ListElement{ longitude: "48"; latitude: "66"; height: "116"; }
+ ListElement{ longitude: "48"; latitude: "67"; height: "118"; }
+ ListElement{ longitude: "48"; latitude: "68"; height: "121"; }
+ ListElement{ longitude: "48"; latitude: "69"; height: "125"; }
+ ListElement{ longitude: "48"; latitude: "70"; height: "120"; }
+ ListElement{ longitude: "48"; latitude: "71"; height: "145"; }
+ ListElement{ longitude: "48"; latitude: "72"; height: "154"; }
+ ListElement{ longitude: "48"; latitude: "73"; height: "153"; }
+ ListElement{ longitude: "48"; latitude: "74"; height: "125"; }
+ ListElement{ longitude: "48"; latitude: "75"; height: "106"; }
+ ListElement{ longitude: "48"; latitude: "76"; height: "52"; }
+ ListElement{ longitude: "48"; latitude: "77"; height: "6"; }
+ ListElement{ longitude: "48"; latitude: "78"; height: "6"; }
+ ListElement{ longitude: "48"; latitude: "79"; height: "1"; }
+ ListElement{ longitude: "48"; latitude: "80"; height: "67"; }
+ ListElement{ longitude: "48"; latitude: "81"; height: "81"; }
+ ListElement{ longitude: "48"; latitude: "82"; height: "57"; }
+ ListElement{ longitude: "48"; latitude: "83"; height: "93"; }
+ ListElement{ longitude: "48"; latitude: "84"; height: "58"; }
+ ListElement{ longitude: "48"; latitude: "85"; height: "16"; }
+ ListElement{ longitude: "48"; latitude: "86"; height: "1"; }
+ ListElement{ longitude: "48"; latitude: "87"; height: "1"; }
+ ListElement{ longitude: "48"; latitude: "88"; height: "2"; }
+ ListElement{ longitude: "48"; latitude: "89"; height: "1"; }
+ ListElement{ longitude: "48"; latitude: "90"; height: "1"; }
+ ListElement{ longitude: "48"; latitude: "91"; height: "1"; }
+ ListElement{ longitude: "48"; latitude: "92"; height: "45"; }
+ ListElement{ longitude: "48"; latitude: "93"; height: "80"; }
+ ListElement{ longitude: "48"; latitude: "94"; height: "91"; }
+ ListElement{ longitude: "48"; latitude: "95"; height: "97"; }
+ ListElement{ longitude: "48"; latitude: "96"; height: "136"; }
+ ListElement{ longitude: "48"; latitude: "97"; height: "148"; }
+ ListElement{ longitude: "48"; latitude: "98"; height: "140"; }
+ ListElement{ longitude: "48"; latitude: "99"; height: "131"; }
+ ListElement{ longitude: "49"; latitude: "0"; height: "123"; }
+ ListElement{ longitude: "49"; latitude: "1"; height: "123"; }
+ ListElement{ longitude: "49"; latitude: "2"; height: "125"; }
+ ListElement{ longitude: "49"; latitude: "3"; height: "123"; }
+ ListElement{ longitude: "49"; latitude: "4"; height: "120"; }
+ ListElement{ longitude: "49"; latitude: "5"; height: "119"; }
+ ListElement{ longitude: "49"; latitude: "6"; height: "125"; }
+ ListElement{ longitude: "49"; latitude: "7"; height: "124"; }
+ ListElement{ longitude: "49"; latitude: "8"; height: "125"; }
+ ListElement{ longitude: "49"; latitude: "9"; height: "129"; }
+ ListElement{ longitude: "49"; latitude: "10"; height: "125"; }
+ ListElement{ longitude: "49"; latitude: "11"; height: "126"; }
+ ListElement{ longitude: "49"; latitude: "12"; height: "124"; }
+ ListElement{ longitude: "49"; latitude: "13"; height: "125"; }
+ ListElement{ longitude: "49"; latitude: "14"; height: "124"; }
+ ListElement{ longitude: "49"; latitude: "15"; height: "126"; }
+ ListElement{ longitude: "49"; latitude: "16"; height: "125"; }
+ ListElement{ longitude: "49"; latitude: "17"; height: "125"; }
+ ListElement{ longitude: "49"; latitude: "18"; height: "125"; }
+ ListElement{ longitude: "49"; latitude: "19"; height: "123"; }
+ ListElement{ longitude: "49"; latitude: "20"; height: "124"; }
+ ListElement{ longitude: "49"; latitude: "21"; height: "124"; }
+ ListElement{ longitude: "49"; latitude: "22"; height: "123"; }
+ ListElement{ longitude: "49"; latitude: "23"; height: "125"; }
+ ListElement{ longitude: "49"; latitude: "24"; height: "126"; }
+ ListElement{ longitude: "49"; latitude: "25"; height: "127"; }
+ ListElement{ longitude: "49"; latitude: "26"; height: "127"; }
+ ListElement{ longitude: "49"; latitude: "27"; height: "125"; }
+ ListElement{ longitude: "49"; latitude: "28"; height: "124"; }
+ ListElement{ longitude: "49"; latitude: "29"; height: "121"; }
+ ListElement{ longitude: "49"; latitude: "30"; height: "123"; }
+ ListElement{ longitude: "49"; latitude: "31"; height: "125"; }
+ ListElement{ longitude: "49"; latitude: "32"; height: "125"; }
+ ListElement{ longitude: "49"; latitude: "33"; height: "123"; }
+ ListElement{ longitude: "49"; latitude: "34"; height: "125"; }
+ ListElement{ longitude: "49"; latitude: "35"; height: "124"; }
+ ListElement{ longitude: "49"; latitude: "36"; height: "122"; }
+ ListElement{ longitude: "49"; latitude: "37"; height: "122"; }
+ ListElement{ longitude: "49"; latitude: "38"; height: "124"; }
+ ListElement{ longitude: "49"; latitude: "39"; height: "124"; }
+ ListElement{ longitude: "49"; latitude: "40"; height: "123"; }
+ ListElement{ longitude: "49"; latitude: "41"; height: "125"; }
+ ListElement{ longitude: "49"; latitude: "42"; height: "124"; }
+ ListElement{ longitude: "49"; latitude: "43"; height: "124"; }
+ ListElement{ longitude: "49"; latitude: "44"; height: "126"; }
+ ListElement{ longitude: "49"; latitude: "45"; height: "125"; }
+ ListElement{ longitude: "49"; latitude: "46"; height: "121"; }
+ ListElement{ longitude: "49"; latitude: "47"; height: "118"; }
+ ListElement{ longitude: "49"; latitude: "48"; height: "118"; }
+ ListElement{ longitude: "49"; latitude: "49"; height: "121"; }
+ ListElement{ longitude: "49"; latitude: "50"; height: "125"; }
+ ListElement{ longitude: "49"; latitude: "51"; height: "125"; }
+ ListElement{ longitude: "49"; latitude: "52"; height: "120"; }
+ ListElement{ longitude: "49"; latitude: "53"; height: "117"; }
+ ListElement{ longitude: "49"; latitude: "54"; height: "116"; }
+ ListElement{ longitude: "49"; latitude: "55"; height: "111"; }
+ ListElement{ longitude: "49"; latitude: "56"; height: "110"; }
+ ListElement{ longitude: "49"; latitude: "57"; height: "108"; }
+ ListElement{ longitude: "49"; latitude: "58"; height: "112"; }
+ ListElement{ longitude: "49"; latitude: "59"; height: "113"; }
+ ListElement{ longitude: "49"; latitude: "60"; height: "113"; }
+ ListElement{ longitude: "49"; latitude: "61"; height: "110"; }
+ ListElement{ longitude: "49"; latitude: "62"; height: "107"; }
+ ListElement{ longitude: "49"; latitude: "63"; height: "108"; }
+ ListElement{ longitude: "49"; latitude: "64"; height: "107"; }
+ ListElement{ longitude: "49"; latitude: "65"; height: "110"; }
+ ListElement{ longitude: "49"; latitude: "66"; height: "113"; }
+ ListElement{ longitude: "49"; latitude: "67"; height: "117"; }
+ ListElement{ longitude: "49"; latitude: "68"; height: "118"; }
+ ListElement{ longitude: "49"; latitude: "69"; height: "124"; }
+ ListElement{ longitude: "49"; latitude: "70"; height: "130"; }
+ ListElement{ longitude: "49"; latitude: "71"; height: "138"; }
+ ListElement{ longitude: "49"; latitude: "72"; height: "153"; }
+ ListElement{ longitude: "49"; latitude: "73"; height: "156"; }
+ ListElement{ longitude: "49"; latitude: "74"; height: "148"; }
+ ListElement{ longitude: "49"; latitude: "75"; height: "112"; }
+ ListElement{ longitude: "49"; latitude: "76"; height: "83"; }
+ ListElement{ longitude: "49"; latitude: "77"; height: "31"; }
+ ListElement{ longitude: "49"; latitude: "78"; height: "1"; }
+ ListElement{ longitude: "49"; latitude: "79"; height: "9"; }
+ ListElement{ longitude: "49"; latitude: "80"; height: "36"; }
+ ListElement{ longitude: "49"; latitude: "81"; height: "12"; }
+ ListElement{ longitude: "49"; latitude: "82"; height: "15"; }
+ ListElement{ longitude: "49"; latitude: "83"; height: "23"; }
+ ListElement{ longitude: "49"; latitude: "84"; height: "22"; }
+ ListElement{ longitude: "49"; latitude: "85"; height: "9"; }
+ ListElement{ longitude: "49"; latitude: "86"; height: "1"; }
+ ListElement{ longitude: "49"; latitude: "87"; height: "1"; }
+ ListElement{ longitude: "49"; latitude: "88"; height: "1"; }
+ ListElement{ longitude: "49"; latitude: "89"; height: "1"; }
+ ListElement{ longitude: "49"; latitude: "90"; height: "1"; }
+ ListElement{ longitude: "49"; latitude: "91"; height: "5"; }
+ ListElement{ longitude: "49"; latitude: "92"; height: "22"; }
+ ListElement{ longitude: "49"; latitude: "93"; height: "64"; }
+ ListElement{ longitude: "49"; latitude: "94"; height: "87"; }
+ ListElement{ longitude: "49"; latitude: "95"; height: "89"; }
+ ListElement{ longitude: "49"; latitude: "96"; height: "131"; }
+ ListElement{ longitude: "49"; latitude: "97"; height: "139"; }
+ ListElement{ longitude: "49"; latitude: "98"; height: "136"; }
+ ListElement{ longitude: "49"; latitude: "99"; height: "129"; }
+ ListElement{ longitude: "50"; latitude: "0"; height: "123"; }
+ ListElement{ longitude: "50"; latitude: "1"; height: "123"; }
+ ListElement{ longitude: "50"; latitude: "2"; height: "121"; }
+ ListElement{ longitude: "50"; latitude: "3"; height: "121"; }
+ ListElement{ longitude: "50"; latitude: "4"; height: "123"; }
+ ListElement{ longitude: "50"; latitude: "5"; height: "122"; }
+ ListElement{ longitude: "50"; latitude: "6"; height: "124"; }
+ ListElement{ longitude: "50"; latitude: "7"; height: "124"; }
+ ListElement{ longitude: "50"; latitude: "8"; height: "126"; }
+ ListElement{ longitude: "50"; latitude: "9"; height: "127"; }
+ ListElement{ longitude: "50"; latitude: "10"; height: "126"; }
+ ListElement{ longitude: "50"; latitude: "11"; height: "125"; }
+ ListElement{ longitude: "50"; latitude: "12"; height: "122"; }
+ ListElement{ longitude: "50"; latitude: "13"; height: "121"; }
+ ListElement{ longitude: "50"; latitude: "14"; height: "120"; }
+ ListElement{ longitude: "50"; latitude: "15"; height: "118"; }
+ ListElement{ longitude: "50"; latitude: "16"; height: "121"; }
+ ListElement{ longitude: "50"; latitude: "17"; height: "122"; }
+ ListElement{ longitude: "50"; latitude: "18"; height: "122"; }
+ ListElement{ longitude: "50"; latitude: "19"; height: "121"; }
+ ListElement{ longitude: "50"; latitude: "20"; height: "119"; }
+ ListElement{ longitude: "50"; latitude: "21"; height: "121"; }
+ ListElement{ longitude: "50"; latitude: "22"; height: "121"; }
+ ListElement{ longitude: "50"; latitude: "23"; height: "123"; }
+ ListElement{ longitude: "50"; latitude: "24"; height: "126"; }
+ ListElement{ longitude: "50"; latitude: "25"; height: "127"; }
+ ListElement{ longitude: "50"; latitude: "26"; height: "127"; }
+ ListElement{ longitude: "50"; latitude: "27"; height: "126"; }
+ ListElement{ longitude: "50"; latitude: "28"; height: "125"; }
+ ListElement{ longitude: "50"; latitude: "29"; height: "120"; }
+ ListElement{ longitude: "50"; latitude: "30"; height: "123"; }
+ ListElement{ longitude: "50"; latitude: "31"; height: "125"; }
+ ListElement{ longitude: "50"; latitude: "32"; height: "125"; }
+ ListElement{ longitude: "50"; latitude: "33"; height: "119"; }
+ ListElement{ longitude: "50"; latitude: "34"; height: "122"; }
+ ListElement{ longitude: "50"; latitude: "35"; height: "122"; }
+ ListElement{ longitude: "50"; latitude: "36"; height: "122"; }
+ ListElement{ longitude: "50"; latitude: "37"; height: "122"; }
+ ListElement{ longitude: "50"; latitude: "38"; height: "122"; }
+ ListElement{ longitude: "50"; latitude: "39"; height: "122"; }
+ ListElement{ longitude: "50"; latitude: "40"; height: "120"; }
+ ListElement{ longitude: "50"; latitude: "41"; height: "125"; }
+ ListElement{ longitude: "50"; latitude: "42"; height: "127"; }
+ ListElement{ longitude: "50"; latitude: "43"; height: "124"; }
+ ListElement{ longitude: "50"; latitude: "44"; height: "124"; }
+ ListElement{ longitude: "50"; latitude: "45"; height: "126"; }
+ ListElement{ longitude: "50"; latitude: "46"; height: "124"; }
+ ListElement{ longitude: "50"; latitude: "47"; height: "123"; }
+ ListElement{ longitude: "50"; latitude: "48"; height: "122"; }
+ ListElement{ longitude: "50"; latitude: "49"; height: "121"; }
+ ListElement{ longitude: "50"; latitude: "50"; height: "123"; }
+ ListElement{ longitude: "50"; latitude: "51"; height: "123"; }
+ ListElement{ longitude: "50"; latitude: "52"; height: "121"; }
+ ListElement{ longitude: "50"; latitude: "53"; height: "118"; }
+ ListElement{ longitude: "50"; latitude: "54"; height: "112"; }
+ ListElement{ longitude: "50"; latitude: "55"; height: "107"; }
+ ListElement{ longitude: "50"; latitude: "56"; height: "108"; }
+ ListElement{ longitude: "50"; latitude: "57"; height: "106"; }
+ ListElement{ longitude: "50"; latitude: "58"; height: "107"; }
+ ListElement{ longitude: "50"; latitude: "59"; height: "111"; }
+ ListElement{ longitude: "50"; latitude: "60"; height: "110"; }
+ ListElement{ longitude: "50"; latitude: "61"; height: "111"; }
+ ListElement{ longitude: "50"; latitude: "62"; height: "108"; }
+ ListElement{ longitude: "50"; latitude: "63"; height: "108"; }
+ ListElement{ longitude: "50"; latitude: "64"; height: "108"; }
+ ListElement{ longitude: "50"; latitude: "65"; height: "111"; }
+ ListElement{ longitude: "50"; latitude: "66"; height: "111"; }
+ ListElement{ longitude: "50"; latitude: "67"; height: "114"; }
+ ListElement{ longitude: "50"; latitude: "68"; height: "117"; }
+ ListElement{ longitude: "50"; latitude: "69"; height: "120"; }
+ ListElement{ longitude: "50"; latitude: "70"; height: "124"; }
+ ListElement{ longitude: "50"; latitude: "71"; height: "124"; }
+ ListElement{ longitude: "50"; latitude: "72"; height: "141"; }
+ ListElement{ longitude: "50"; latitude: "73"; height: "150"; }
+ ListElement{ longitude: "50"; latitude: "74"; height: "153"; }
+ ListElement{ longitude: "50"; latitude: "75"; height: "118"; }
+ ListElement{ longitude: "50"; latitude: "76"; height: "85"; }
+ ListElement{ longitude: "50"; latitude: "77"; height: "65"; }
+ ListElement{ longitude: "50"; latitude: "78"; height: "19"; }
+ ListElement{ longitude: "50"; latitude: "79"; height: "18"; }
+ ListElement{ longitude: "50"; latitude: "80"; height: "28"; }
+ ListElement{ longitude: "50"; latitude: "81"; height: "3"; }
+ ListElement{ longitude: "50"; latitude: "82"; height: "1"; }
+ ListElement{ longitude: "50"; latitude: "83"; height: "1"; }
+ ListElement{ longitude: "50"; latitude: "84"; height: "1"; }
+ ListElement{ longitude: "50"; latitude: "85"; height: "1"; }
+ ListElement{ longitude: "50"; latitude: "86"; height: "1"; }
+ ListElement{ longitude: "50"; latitude: "87"; height: "1"; }
+ ListElement{ longitude: "50"; latitude: "88"; height: "1"; }
+ ListElement{ longitude: "50"; latitude: "89"; height: "1"; }
+ ListElement{ longitude: "50"; latitude: "90"; height: "1"; }
+ ListElement{ longitude: "50"; latitude: "91"; height: "19"; }
+ ListElement{ longitude: "50"; latitude: "92"; height: "10"; }
+ ListElement{ longitude: "50"; latitude: "93"; height: "59"; }
+ ListElement{ longitude: "50"; latitude: "94"; height: "72"; }
+ ListElement{ longitude: "50"; latitude: "95"; height: "95"; }
+ ListElement{ longitude: "50"; latitude: "96"; height: "127"; }
+ ListElement{ longitude: "50"; latitude: "97"; height: "129"; }
+ ListElement{ longitude: "50"; latitude: "98"; height: "132"; }
+ ListElement{ longitude: "50"; latitude: "99"; height: "126"; }
+ ListElement{ longitude: "51"; latitude: "0"; height: "122"; }
+ ListElement{ longitude: "51"; latitude: "1"; height: "124"; }
+ ListElement{ longitude: "51"; latitude: "2"; height: "122"; }
+ ListElement{ longitude: "51"; latitude: "3"; height: "123"; }
+ ListElement{ longitude: "51"; latitude: "4"; height: "123"; }
+ ListElement{ longitude: "51"; latitude: "5"; height: "122"; }
+ ListElement{ longitude: "51"; latitude: "6"; height: "125"; }
+ ListElement{ longitude: "51"; latitude: "7"; height: "124"; }
+ ListElement{ longitude: "51"; latitude: "8"; height: "125"; }
+ ListElement{ longitude: "51"; latitude: "9"; height: "125"; }
+ ListElement{ longitude: "51"; latitude: "10"; height: "126"; }
+ ListElement{ longitude: "51"; latitude: "11"; height: "123"; }
+ ListElement{ longitude: "51"; latitude: "12"; height: "121"; }
+ ListElement{ longitude: "51"; latitude: "13"; height: "120"; }
+ ListElement{ longitude: "51"; latitude: "14"; height: "119"; }
+ ListElement{ longitude: "51"; latitude: "15"; height: "119"; }
+ ListElement{ longitude: "51"; latitude: "16"; height: "120"; }
+ ListElement{ longitude: "51"; latitude: "17"; height: "123"; }
+ ListElement{ longitude: "51"; latitude: "18"; height: "121"; }
+ ListElement{ longitude: "51"; latitude: "19"; height: "122"; }
+ ListElement{ longitude: "51"; latitude: "20"; height: "118"; }
+ ListElement{ longitude: "51"; latitude: "21"; height: "120"; }
+ ListElement{ longitude: "51"; latitude: "22"; height: "121"; }
+ ListElement{ longitude: "51"; latitude: "23"; height: "122"; }
+ ListElement{ longitude: "51"; latitude: "24"; height: "125"; }
+ ListElement{ longitude: "51"; latitude: "25"; height: "126"; }
+ ListElement{ longitude: "51"; latitude: "26"; height: "126"; }
+ ListElement{ longitude: "51"; latitude: "27"; height: "124"; }
+ ListElement{ longitude: "51"; latitude: "28"; height: "125"; }
+ ListElement{ longitude: "51"; latitude: "29"; height: "125"; }
+ ListElement{ longitude: "51"; latitude: "30"; height: "125"; }
+ ListElement{ longitude: "51"; latitude: "31"; height: "125"; }
+ ListElement{ longitude: "51"; latitude: "32"; height: "125"; }
+ ListElement{ longitude: "51"; latitude: "33"; height: "125"; }
+ ListElement{ longitude: "51"; latitude: "34"; height: "125"; }
+ ListElement{ longitude: "51"; latitude: "35"; height: "124"; }
+ ListElement{ longitude: "51"; latitude: "36"; height: "122"; }
+ ListElement{ longitude: "51"; latitude: "37"; height: "123"; }
+ ListElement{ longitude: "51"; latitude: "38"; height: "123"; }
+ ListElement{ longitude: "51"; latitude: "39"; height: "123"; }
+ ListElement{ longitude: "51"; latitude: "40"; height: "124"; }
+ ListElement{ longitude: "51"; latitude: "41"; height: "122"; }
+ ListElement{ longitude: "51"; latitude: "42"; height: "123"; }
+ ListElement{ longitude: "51"; latitude: "43"; height: "126"; }
+ ListElement{ longitude: "51"; latitude: "44"; height: "126"; }
+ ListElement{ longitude: "51"; latitude: "45"; height: "126"; }
+ ListElement{ longitude: "51"; latitude: "46"; height: "125"; }
+ ListElement{ longitude: "51"; latitude: "47"; height: "122"; }
+ ListElement{ longitude: "51"; latitude: "48"; height: "119"; }
+ ListElement{ longitude: "51"; latitude: "49"; height: "123"; }
+ ListElement{ longitude: "51"; latitude: "50"; height: "123"; }
+ ListElement{ longitude: "51"; latitude: "51"; height: "124"; }
+ ListElement{ longitude: "51"; latitude: "52"; height: "120"; }
+ ListElement{ longitude: "51"; latitude: "53"; height: "117"; }
+ ListElement{ longitude: "51"; latitude: "54"; height: "111"; }
+ ListElement{ longitude: "51"; latitude: "55"; height: "105"; }
+ ListElement{ longitude: "51"; latitude: "56"; height: "102"; }
+ ListElement{ longitude: "51"; latitude: "57"; height: "102"; }
+ ListElement{ longitude: "51"; latitude: "58"; height: "105"; }
+ ListElement{ longitude: "51"; latitude: "59"; height: "111"; }
+ ListElement{ longitude: "51"; latitude: "60"; height: "111"; }
+ ListElement{ longitude: "51"; latitude: "61"; height: "113"; }
+ ListElement{ longitude: "51"; latitude: "62"; height: "109"; }
+ ListElement{ longitude: "51"; latitude: "63"; height: "109"; }
+ ListElement{ longitude: "51"; latitude: "64"; height: "109"; }
+ ListElement{ longitude: "51"; latitude: "65"; height: "110"; }
+ ListElement{ longitude: "51"; latitude: "66"; height: "110"; }
+ ListElement{ longitude: "51"; latitude: "67"; height: "115"; }
+ ListElement{ longitude: "51"; latitude: "68"; height: "116"; }
+ ListElement{ longitude: "51"; latitude: "69"; height: "118"; }
+ ListElement{ longitude: "51"; latitude: "70"; height: "122"; }
+ ListElement{ longitude: "51"; latitude: "71"; height: "121"; }
+ ListElement{ longitude: "51"; latitude: "72"; height: "133"; }
+ ListElement{ longitude: "51"; latitude: "73"; height: "151"; }
+ ListElement{ longitude: "51"; latitude: "74"; height: "153"; }
+ ListElement{ longitude: "51"; latitude: "75"; height: "138"; }
+ ListElement{ longitude: "51"; latitude: "76"; height: "98"; }
+ ListElement{ longitude: "51"; latitude: "77"; height: "64"; }
+ ListElement{ longitude: "51"; latitude: "78"; height: "32"; }
+ ListElement{ longitude: "51"; latitude: "79"; height: "1"; }
+ ListElement{ longitude: "51"; latitude: "80"; height: "1"; }
+ ListElement{ longitude: "51"; latitude: "81"; height: "1"; }
+ ListElement{ longitude: "51"; latitude: "82"; height: "1"; }
+ ListElement{ longitude: "51"; latitude: "83"; height: "6"; }
+ ListElement{ longitude: "51"; latitude: "84"; height: "8"; }
+ ListElement{ longitude: "51"; latitude: "85"; height: "1"; }
+ ListElement{ longitude: "51"; latitude: "86"; height: "1"; }
+ ListElement{ longitude: "51"; latitude: "87"; height: "1"; }
+ ListElement{ longitude: "51"; latitude: "88"; height: "1"; }
+ ListElement{ longitude: "51"; latitude: "89"; height: "13"; }
+ ListElement{ longitude: "51"; latitude: "90"; height: "15"; }
+ ListElement{ longitude: "51"; latitude: "91"; height: "22"; }
+ ListElement{ longitude: "51"; latitude: "92"; height: "33"; }
+ ListElement{ longitude: "51"; latitude: "93"; height: "67"; }
+ ListElement{ longitude: "51"; latitude: "94"; height: "69"; }
+ ListElement{ longitude: "51"; latitude: "95"; height: "110"; }
+ ListElement{ longitude: "51"; latitude: "96"; height: "125"; }
+ ListElement{ longitude: "51"; latitude: "97"; height: "127"; }
+ ListElement{ longitude: "51"; latitude: "98"; height: "131"; }
+ ListElement{ longitude: "51"; latitude: "99"; height: "122"; }
+ ListElement{ longitude: "52"; latitude: "0"; height: "121"; }
+ ListElement{ longitude: "52"; latitude: "1"; height: "119"; }
+ ListElement{ longitude: "52"; latitude: "2"; height: "117"; }
+ ListElement{ longitude: "52"; latitude: "3"; height: "122"; }
+ ListElement{ longitude: "52"; latitude: "4"; height: "123"; }
+ ListElement{ longitude: "52"; latitude: "5"; height: "126"; }
+ ListElement{ longitude: "52"; latitude: "6"; height: "125"; }
+ ListElement{ longitude: "52"; latitude: "7"; height: "126"; }
+ ListElement{ longitude: "52"; latitude: "8"; height: "127"; }
+ ListElement{ longitude: "52"; latitude: "9"; height: "127"; }
+ ListElement{ longitude: "52"; latitude: "10"; height: "127"; }
+ ListElement{ longitude: "52"; latitude: "11"; height: "125"; }
+ ListElement{ longitude: "52"; latitude: "12"; height: "123"; }
+ ListElement{ longitude: "52"; latitude: "13"; height: "122"; }
+ ListElement{ longitude: "52"; latitude: "14"; height: "121"; }
+ ListElement{ longitude: "52"; latitude: "15"; height: "121"; }
+ ListElement{ longitude: "52"; latitude: "16"; height: "122"; }
+ ListElement{ longitude: "52"; latitude: "17"; height: "122"; }
+ ListElement{ longitude: "52"; latitude: "18"; height: "120"; }
+ ListElement{ longitude: "52"; latitude: "19"; height: "120"; }
+ ListElement{ longitude: "52"; latitude: "20"; height: "121"; }
+ ListElement{ longitude: "52"; latitude: "21"; height: "120"; }
+ ListElement{ longitude: "52"; latitude: "22"; height: "122"; }
+ ListElement{ longitude: "52"; latitude: "23"; height: "121"; }
+ ListElement{ longitude: "52"; latitude: "24"; height: "125"; }
+ ListElement{ longitude: "52"; latitude: "25"; height: "126"; }
+ ListElement{ longitude: "52"; latitude: "26"; height: "126"; }
+ ListElement{ longitude: "52"; latitude: "27"; height: "125"; }
+ ListElement{ longitude: "52"; latitude: "28"; height: "125"; }
+ ListElement{ longitude: "52"; latitude: "29"; height: "125"; }
+ ListElement{ longitude: "52"; latitude: "30"; height: "121"; }
+ ListElement{ longitude: "52"; latitude: "31"; height: "125"; }
+ ListElement{ longitude: "52"; latitude: "32"; height: "125"; }
+ ListElement{ longitude: "52"; latitude: "33"; height: "125"; }
+ ListElement{ longitude: "52"; latitude: "34"; height: "125"; }
+ ListElement{ longitude: "52"; latitude: "35"; height: "125"; }
+ ListElement{ longitude: "52"; latitude: "36"; height: "122"; }
+ ListElement{ longitude: "52"; latitude: "37"; height: "121"; }
+ ListElement{ longitude: "52"; latitude: "38"; height: "123"; }
+ ListElement{ longitude: "52"; latitude: "39"; height: "122"; }
+ ListElement{ longitude: "52"; latitude: "40"; height: "122"; }
+ ListElement{ longitude: "52"; latitude: "41"; height: "120"; }
+ ListElement{ longitude: "52"; latitude: "42"; height: "125"; }
+ ListElement{ longitude: "52"; latitude: "43"; height: "126"; }
+ ListElement{ longitude: "52"; latitude: "44"; height: "127"; }
+ ListElement{ longitude: "52"; latitude: "45"; height: "127"; }
+ ListElement{ longitude: "52"; latitude: "46"; height: "126"; }
+ ListElement{ longitude: "52"; latitude: "47"; height: "124"; }
+ ListElement{ longitude: "52"; latitude: "48"; height: "123"; }
+ ListElement{ longitude: "52"; latitude: "49"; height: "124"; }
+ ListElement{ longitude: "52"; latitude: "50"; height: "123"; }
+ ListElement{ longitude: "52"; latitude: "51"; height: "120"; }
+ ListElement{ longitude: "52"; latitude: "52"; height: "119"; }
+ ListElement{ longitude: "52"; latitude: "53"; height: "116"; }
+ ListElement{ longitude: "52"; latitude: "54"; height: "110"; }
+ ListElement{ longitude: "52"; latitude: "55"; height: "106"; }
+ ListElement{ longitude: "52"; latitude: "56"; height: "101"; }
+ ListElement{ longitude: "52"; latitude: "57"; height: "101"; }
+ ListElement{ longitude: "52"; latitude: "58"; height: "104"; }
+ ListElement{ longitude: "52"; latitude: "59"; height: "107"; }
+ ListElement{ longitude: "52"; latitude: "60"; height: "109"; }
+ ListElement{ longitude: "52"; latitude: "61"; height: "112"; }
+ ListElement{ longitude: "52"; latitude: "62"; height: "112"; }
+ ListElement{ longitude: "52"; latitude: "63"; height: "110"; }
+ ListElement{ longitude: "52"; latitude: "64"; height: "110"; }
+ ListElement{ longitude: "52"; latitude: "65"; height: "113"; }
+ ListElement{ longitude: "52"; latitude: "66"; height: "114"; }
+ ListElement{ longitude: "52"; latitude: "67"; height: "116"; }
+ ListElement{ longitude: "52"; latitude: "68"; height: "115"; }
+ ListElement{ longitude: "52"; latitude: "69"; height: "116"; }
+ ListElement{ longitude: "52"; latitude: "70"; height: "117"; }
+ ListElement{ longitude: "52"; latitude: "71"; height: "120"; }
+ ListElement{ longitude: "52"; latitude: "72"; height: "126"; }
+ ListElement{ longitude: "52"; latitude: "73"; height: "146"; }
+ ListElement{ longitude: "52"; latitude: "74"; height: "152"; }
+ ListElement{ longitude: "52"; latitude: "75"; height: "148"; }
+ ListElement{ longitude: "52"; latitude: "76"; height: "117"; }
+ ListElement{ longitude: "52"; latitude: "77"; height: "93"; }
+ ListElement{ longitude: "52"; latitude: "78"; height: "72"; }
+ ListElement{ longitude: "52"; latitude: "79"; height: "50"; }
+ ListElement{ longitude: "52"; latitude: "80"; height: "16"; }
+ ListElement{ longitude: "52"; latitude: "81"; height: "1"; }
+ ListElement{ longitude: "52"; latitude: "82"; height: "3"; }
+ ListElement{ longitude: "52"; latitude: "83"; height: "6"; }
+ ListElement{ longitude: "52"; latitude: "84"; height: "24"; }
+ ListElement{ longitude: "52"; latitude: "85"; height: "1"; }
+ ListElement{ longitude: "52"; latitude: "86"; height: "4"; }
+ ListElement{ longitude: "52"; latitude: "87"; height: "4"; }
+ ListElement{ longitude: "52"; latitude: "88"; height: "7"; }
+ ListElement{ longitude: "52"; latitude: "89"; height: "42"; }
+ ListElement{ longitude: "52"; latitude: "90"; height: "52"; }
+ ListElement{ longitude: "52"; latitude: "91"; height: "47"; }
+ ListElement{ longitude: "52"; latitude: "92"; height: "46"; }
+ ListElement{ longitude: "52"; latitude: "93"; height: "61"; }
+ ListElement{ longitude: "52"; latitude: "94"; height: "73"; }
+ ListElement{ longitude: "52"; latitude: "95"; height: "114"; }
+ ListElement{ longitude: "52"; latitude: "96"; height: "121"; }
+ ListElement{ longitude: "52"; latitude: "97"; height: "127"; }
+ ListElement{ longitude: "52"; latitude: "98"; height: "129"; }
+ ListElement{ longitude: "52"; latitude: "99"; height: "119"; }
+ ListElement{ longitude: "53"; latitude: "0"; height: "119"; }
+ ListElement{ longitude: "53"; latitude: "1"; height: "117"; }
+ ListElement{ longitude: "53"; latitude: "2"; height: "116"; }
+ ListElement{ longitude: "53"; latitude: "3"; height: "119"; }
+ ListElement{ longitude: "53"; latitude: "4"; height: "119"; }
+ ListElement{ longitude: "53"; latitude: "5"; height: "126"; }
+ ListElement{ longitude: "53"; latitude: "6"; height: "124"; }
+ ListElement{ longitude: "53"; latitude: "7"; height: "126"; }
+ ListElement{ longitude: "53"; latitude: "8"; height: "127"; }
+ ListElement{ longitude: "53"; latitude: "9"; height: "127"; }
+ ListElement{ longitude: "53"; latitude: "10"; height: "127"; }
+ ListElement{ longitude: "53"; latitude: "11"; height: "124"; }
+ ListElement{ longitude: "53"; latitude: "12"; height: "122"; }
+ ListElement{ longitude: "53"; latitude: "13"; height: "122"; }
+ ListElement{ longitude: "53"; latitude: "14"; height: "120"; }
+ ListElement{ longitude: "53"; latitude: "15"; height: "120"; }
+ ListElement{ longitude: "53"; latitude: "16"; height: "122"; }
+ ListElement{ longitude: "53"; latitude: "17"; height: "122"; }
+ ListElement{ longitude: "53"; latitude: "18"; height: "120"; }
+ ListElement{ longitude: "53"; latitude: "19"; height: "121"; }
+ ListElement{ longitude: "53"; latitude: "20"; height: "121"; }
+ ListElement{ longitude: "53"; latitude: "21"; height: "120"; }
+ ListElement{ longitude: "53"; latitude: "22"; height: "122"; }
+ ListElement{ longitude: "53"; latitude: "23"; height: "121"; }
+ ListElement{ longitude: "53"; latitude: "24"; height: "124"; }
+ ListElement{ longitude: "53"; latitude: "25"; height: "124"; }
+ ListElement{ longitude: "53"; latitude: "26"; height: "124"; }
+ ListElement{ longitude: "53"; latitude: "27"; height: "122"; }
+ ListElement{ longitude: "53"; latitude: "28"; height: "123"; }
+ ListElement{ longitude: "53"; latitude: "29"; height: "123"; }
+ ListElement{ longitude: "53"; latitude: "30"; height: "122"; }
+ ListElement{ longitude: "53"; latitude: "31"; height: "126"; }
+ ListElement{ longitude: "53"; latitude: "32"; height: "125"; }
+ ListElement{ longitude: "53"; latitude: "33"; height: "125"; }
+ ListElement{ longitude: "53"; latitude: "34"; height: "125"; }
+ ListElement{ longitude: "53"; latitude: "35"; height: "125"; }
+ ListElement{ longitude: "53"; latitude: "36"; height: "125"; }
+ ListElement{ longitude: "53"; latitude: "37"; height: "122"; }
+ ListElement{ longitude: "53"; latitude: "38"; height: "122"; }
+ ListElement{ longitude: "53"; latitude: "39"; height: "122"; }
+ ListElement{ longitude: "53"; latitude: "40"; height: "125"; }
+ ListElement{ longitude: "53"; latitude: "41"; height: "125"; }
+ ListElement{ longitude: "53"; latitude: "42"; height: "126"; }
+ ListElement{ longitude: "53"; latitude: "43"; height: "127"; }
+ ListElement{ longitude: "53"; latitude: "44"; height: "127"; }
+ ListElement{ longitude: "53"; latitude: "45"; height: "127"; }
+ ListElement{ longitude: "53"; latitude: "46"; height: "129"; }
+ ListElement{ longitude: "53"; latitude: "47"; height: "127"; }
+ ListElement{ longitude: "53"; latitude: "48"; height: "127"; }
+ ListElement{ longitude: "53"; latitude: "49"; height: "126"; }
+ ListElement{ longitude: "53"; latitude: "50"; height: "122"; }
+ ListElement{ longitude: "53"; latitude: "51"; height: "121"; }
+ ListElement{ longitude: "53"; latitude: "52"; height: "118"; }
+ ListElement{ longitude: "53"; latitude: "53"; height: "114"; }
+ ListElement{ longitude: "53"; latitude: "54"; height: "106"; }
+ ListElement{ longitude: "53"; latitude: "55"; height: "108"; }
+ ListElement{ longitude: "53"; latitude: "56"; height: "105"; }
+ ListElement{ longitude: "53"; latitude: "57"; height: "104"; }
+ ListElement{ longitude: "53"; latitude: "58"; height: "103"; }
+ ListElement{ longitude: "53"; latitude: "59"; height: "107"; }
+ ListElement{ longitude: "53"; latitude: "60"; height: "109"; }
+ ListElement{ longitude: "53"; latitude: "61"; height: "112"; }
+ ListElement{ longitude: "53"; latitude: "62"; height: "111"; }
+ ListElement{ longitude: "53"; latitude: "63"; height: "113"; }
+ ListElement{ longitude: "53"; latitude: "64"; height: "111"; }
+ ListElement{ longitude: "53"; latitude: "65"; height: "113"; }
+ ListElement{ longitude: "53"; latitude: "66"; height: "113"; }
+ ListElement{ longitude: "53"; latitude: "67"; height: "116"; }
+ ListElement{ longitude: "53"; latitude: "68"; height: "116"; }
+ ListElement{ longitude: "53"; latitude: "69"; height: "114"; }
+ ListElement{ longitude: "53"; latitude: "70"; height: "114"; }
+ ListElement{ longitude: "53"; latitude: "71"; height: "112"; }
+ ListElement{ longitude: "53"; latitude: "72"; height: "118"; }
+ ListElement{ longitude: "53"; latitude: "73"; height: "133"; }
+ ListElement{ longitude: "53"; latitude: "74"; height: "150"; }
+ ListElement{ longitude: "53"; latitude: "75"; height: "154"; }
+ ListElement{ longitude: "53"; latitude: "76"; height: "141"; }
+ ListElement{ longitude: "53"; latitude: "77"; height: "103"; }
+ ListElement{ longitude: "53"; latitude: "78"; height: "97"; }
+ ListElement{ longitude: "53"; latitude: "79"; height: "94"; }
+ ListElement{ longitude: "53"; latitude: "80"; height: "54"; }
+ ListElement{ longitude: "53"; latitude: "81"; height: "17"; }
+ ListElement{ longitude: "53"; latitude: "82"; height: "5"; }
+ ListElement{ longitude: "53"; latitude: "83"; height: "4"; }
+ ListElement{ longitude: "53"; latitude: "84"; height: "1"; }
+ ListElement{ longitude: "53"; latitude: "85"; height: "1"; }
+ ListElement{ longitude: "53"; latitude: "86"; height: "19"; }
+ ListElement{ longitude: "53"; latitude: "87"; height: "9"; }
+ ListElement{ longitude: "53"; latitude: "88"; height: "25"; }
+ ListElement{ longitude: "53"; latitude: "89"; height: "40"; }
+ ListElement{ longitude: "53"; latitude: "90"; height: "55"; }
+ ListElement{ longitude: "53"; latitude: "91"; height: "54"; }
+ ListElement{ longitude: "53"; latitude: "92"; height: "53"; }
+ ListElement{ longitude: "53"; latitude: "93"; height: "69"; }
+ ListElement{ longitude: "53"; latitude: "94"; height: "100"; }
+ ListElement{ longitude: "53"; latitude: "95"; height: "112"; }
+ ListElement{ longitude: "53"; latitude: "96"; height: "120"; }
+ ListElement{ longitude: "53"; latitude: "97"; height: "126"; }
+ ListElement{ longitude: "53"; latitude: "98"; height: "125"; }
+ ListElement{ longitude: "53"; latitude: "99"; height: "118"; }
+ ListElement{ longitude: "54"; latitude: "0"; height: "119"; }
+ ListElement{ longitude: "54"; latitude: "1"; height: "118"; }
+ ListElement{ longitude: "54"; latitude: "2"; height: "118"; }
+ ListElement{ longitude: "54"; latitude: "3"; height: "119"; }
+ ListElement{ longitude: "54"; latitude: "4"; height: "120"; }
+ ListElement{ longitude: "54"; latitude: "5"; height: "123"; }
+ ListElement{ longitude: "54"; latitude: "6"; height: "125"; }
+ ListElement{ longitude: "54"; latitude: "7"; height: "126"; }
+ ListElement{ longitude: "54"; latitude: "8"; height: "127"; }
+ ListElement{ longitude: "54"; latitude: "9"; height: "126"; }
+ ListElement{ longitude: "54"; latitude: "10"; height: "127"; }
+ ListElement{ longitude: "54"; latitude: "11"; height: "126"; }
+ ListElement{ longitude: "54"; latitude: "12"; height: "122"; }
+ ListElement{ longitude: "54"; latitude: "13"; height: "122"; }
+ ListElement{ longitude: "54"; latitude: "14"; height: "120"; }
+ ListElement{ longitude: "54"; latitude: "15"; height: "121"; }
+ ListElement{ longitude: "54"; latitude: "16"; height: "121"; }
+ ListElement{ longitude: "54"; latitude: "17"; height: "121"; }
+ ListElement{ longitude: "54"; latitude: "18"; height: "121"; }
+ ListElement{ longitude: "54"; latitude: "19"; height: "121"; }
+ ListElement{ longitude: "54"; latitude: "20"; height: "121"; }
+ ListElement{ longitude: "54"; latitude: "21"; height: "121"; }
+ ListElement{ longitude: "54"; latitude: "22"; height: "122"; }
+ ListElement{ longitude: "54"; latitude: "23"; height: "122"; }
+ ListElement{ longitude: "54"; latitude: "24"; height: "121"; }
+ ListElement{ longitude: "54"; latitude: "25"; height: "121"; }
+ ListElement{ longitude: "54"; latitude: "26"; height: "121"; }
+ ListElement{ longitude: "54"; latitude: "27"; height: "120"; }
+ ListElement{ longitude: "54"; latitude: "28"; height: "120"; }
+ ListElement{ longitude: "54"; latitude: "29"; height: "120"; }
+ ListElement{ longitude: "54"; latitude: "30"; height: "121"; }
+ ListElement{ longitude: "54"; latitude: "31"; height: "123"; }
+ ListElement{ longitude: "54"; latitude: "32"; height: "121"; }
+ ListElement{ longitude: "54"; latitude: "33"; height: "122"; }
+ ListElement{ longitude: "54"; latitude: "34"; height: "125"; }
+ ListElement{ longitude: "54"; latitude: "35"; height: "124"; }
+ ListElement{ longitude: "54"; latitude: "36"; height: "125"; }
+ ListElement{ longitude: "54"; latitude: "37"; height: "125"; }
+ ListElement{ longitude: "54"; latitude: "38"; height: "123"; }
+ ListElement{ longitude: "54"; latitude: "39"; height: "125"; }
+ ListElement{ longitude: "54"; latitude: "40"; height: "124"; }
+ ListElement{ longitude: "54"; latitude: "41"; height: "126"; }
+ ListElement{ longitude: "54"; latitude: "42"; height: "127"; }
+ ListElement{ longitude: "54"; latitude: "43"; height: "126"; }
+ ListElement{ longitude: "54"; latitude: "44"; height: "126"; }
+ ListElement{ longitude: "54"; latitude: "45"; height: "126"; }
+ ListElement{ longitude: "54"; latitude: "46"; height: "127"; }
+ ListElement{ longitude: "54"; latitude: "47"; height: "125"; }
+ ListElement{ longitude: "54"; latitude: "48"; height: "129"; }
+ ListElement{ longitude: "54"; latitude: "49"; height: "127"; }
+ ListElement{ longitude: "54"; latitude: "50"; height: "125"; }
+ ListElement{ longitude: "54"; latitude: "51"; height: "120"; }
+ ListElement{ longitude: "54"; latitude: "52"; height: "118"; }
+ ListElement{ longitude: "54"; latitude: "53"; height: "112"; }
+ ListElement{ longitude: "54"; latitude: "54"; height: "96"; }
+ ListElement{ longitude: "54"; latitude: "55"; height: "107"; }
+ ListElement{ longitude: "54"; latitude: "56"; height: "108"; }
+ ListElement{ longitude: "54"; latitude: "57"; height: "105"; }
+ ListElement{ longitude: "54"; latitude: "58"; height: "105"; }
+ ListElement{ longitude: "54"; latitude: "59"; height: "108"; }
+ ListElement{ longitude: "54"; latitude: "60"; height: "111"; }
+ ListElement{ longitude: "54"; latitude: "61"; height: "111"; }
+ ListElement{ longitude: "54"; latitude: "62"; height: "115"; }
+ ListElement{ longitude: "54"; latitude: "63"; height: "112"; }
+ ListElement{ longitude: "54"; latitude: "64"; height: "112"; }
+ ListElement{ longitude: "54"; latitude: "65"; height: "112"; }
+ ListElement{ longitude: "54"; latitude: "66"; height: "113"; }
+ ListElement{ longitude: "54"; latitude: "67"; height: "113"; }
+ ListElement{ longitude: "54"; latitude: "68"; height: "115"; }
+ ListElement{ longitude: "54"; latitude: "69"; height: "115"; }
+ ListElement{ longitude: "54"; latitude: "70"; height: "112"; }
+ ListElement{ longitude: "54"; latitude: "71"; height: "110"; }
+ ListElement{ longitude: "54"; latitude: "72"; height: "112"; }
+ ListElement{ longitude: "54"; latitude: "73"; height: "119"; }
+ ListElement{ longitude: "54"; latitude: "74"; height: "140"; }
+ ListElement{ longitude: "54"; latitude: "75"; height: "151"; }
+ ListElement{ longitude: "54"; latitude: "76"; height: "150"; }
+ ListElement{ longitude: "54"; latitude: "77"; height: "140"; }
+ ListElement{ longitude: "54"; latitude: "78"; height: "104"; }
+ ListElement{ longitude: "54"; latitude: "79"; height: "102"; }
+ ListElement{ longitude: "54"; latitude: "80"; height: "90"; }
+ ListElement{ longitude: "54"; latitude: "81"; height: "46"; }
+ ListElement{ longitude: "54"; latitude: "82"; height: "37"; }
+ ListElement{ longitude: "54"; latitude: "83"; height: "30"; }
+ ListElement{ longitude: "54"; latitude: "84"; height: "24"; }
+ ListElement{ longitude: "54"; latitude: "85"; height: "16"; }
+ ListElement{ longitude: "54"; latitude: "86"; height: "18"; }
+ ListElement{ longitude: "54"; latitude: "87"; height: "46"; }
+ ListElement{ longitude: "54"; latitude: "88"; height: "26"; }
+ ListElement{ longitude: "54"; latitude: "89"; height: "28"; }
+ ListElement{ longitude: "54"; latitude: "90"; height: "60"; }
+ ListElement{ longitude: "54"; latitude: "91"; height: "51"; }
+ ListElement{ longitude: "54"; latitude: "92"; height: "54"; }
+ ListElement{ longitude: "54"; latitude: "93"; height: "108"; }
+ ListElement{ longitude: "54"; latitude: "94"; height: "131"; }
+ ListElement{ longitude: "54"; latitude: "95"; height: "116"; }
+ ListElement{ longitude: "54"; latitude: "96"; height: "122"; }
+ ListElement{ longitude: "54"; latitude: "97"; height: "126"; }
+ ListElement{ longitude: "54"; latitude: "98"; height: "125"; }
+ ListElement{ longitude: "54"; latitude: "99"; height: "118"; }
+ ListElement{ longitude: "55"; latitude: "0"; height: "120"; }
+ ListElement{ longitude: "55"; latitude: "1"; height: "120"; }
+ ListElement{ longitude: "55"; latitude: "2"; height: "120"; }
+ ListElement{ longitude: "55"; latitude: "3"; height: "121"; }
+ ListElement{ longitude: "55"; latitude: "4"; height: "120"; }
+ ListElement{ longitude: "55"; latitude: "5"; height: "121"; }
+ ListElement{ longitude: "55"; latitude: "6"; height: "124"; }
+ ListElement{ longitude: "55"; latitude: "7"; height: "124"; }
+ ListElement{ longitude: "55"; latitude: "8"; height: "129"; }
+ ListElement{ longitude: "55"; latitude: "9"; height: "129"; }
+ ListElement{ longitude: "55"; latitude: "10"; height: "127"; }
+ ListElement{ longitude: "55"; latitude: "11"; height: "125"; }
+ ListElement{ longitude: "55"; latitude: "12"; height: "123"; }
+ ListElement{ longitude: "55"; latitude: "13"; height: "120"; }
+ ListElement{ longitude: "55"; latitude: "14"; height: "121"; }
+ ListElement{ longitude: "55"; latitude: "15"; height: "119"; }
+ ListElement{ longitude: "55"; latitude: "16"; height: "119"; }
+ ListElement{ longitude: "55"; latitude: "17"; height: "119"; }
+ ListElement{ longitude: "55"; latitude: "18"; height: "119"; }
+ ListElement{ longitude: "55"; latitude: "19"; height: "119"; }
+ ListElement{ longitude: "55"; latitude: "20"; height: "119"; }
+ ListElement{ longitude: "55"; latitude: "21"; height: "119"; }
+ ListElement{ longitude: "55"; latitude: "22"; height: "121"; }
+ ListElement{ longitude: "55"; latitude: "23"; height: "120"; }
+ ListElement{ longitude: "55"; latitude: "24"; height: "122"; }
+ ListElement{ longitude: "55"; latitude: "25"; height: "122"; }
+ ListElement{ longitude: "55"; latitude: "26"; height: "120"; }
+ ListElement{ longitude: "55"; latitude: "27"; height: "119"; }
+ ListElement{ longitude: "55"; latitude: "28"; height: "119"; }
+ ListElement{ longitude: "55"; latitude: "29"; height: "119"; }
+ ListElement{ longitude: "55"; latitude: "30"; height: "121"; }
+ ListElement{ longitude: "55"; latitude: "31"; height: "124"; }
+ ListElement{ longitude: "55"; latitude: "32"; height: "116"; }
+ ListElement{ longitude: "55"; latitude: "33"; height: "120"; }
+ ListElement{ longitude: "55"; latitude: "34"; height: "127"; }
+ ListElement{ longitude: "55"; latitude: "35"; height: "124"; }
+ ListElement{ longitude: "55"; latitude: "36"; height: "125"; }
+ ListElement{ longitude: "55"; latitude: "37"; height: "127"; }
+ ListElement{ longitude: "55"; latitude: "38"; height: "123"; }
+ ListElement{ longitude: "55"; latitude: "39"; height: "124"; }
+ ListElement{ longitude: "55"; latitude: "40"; height: "123"; }
+ ListElement{ longitude: "55"; latitude: "41"; height: "127"; }
+ ListElement{ longitude: "55"; latitude: "42"; height: "128"; }
+ ListElement{ longitude: "55"; latitude: "43"; height: "128"; }
+ ListElement{ longitude: "55"; latitude: "44"; height: "128"; }
+ ListElement{ longitude: "55"; latitude: "45"; height: "125"; }
+ ListElement{ longitude: "55"; latitude: "46"; height: "127"; }
+ ListElement{ longitude: "55"; latitude: "47"; height: "125"; }
+ ListElement{ longitude: "55"; latitude: "48"; height: "128"; }
+ ListElement{ longitude: "55"; latitude: "49"; height: "126"; }
+ ListElement{ longitude: "55"; latitude: "50"; height: "126"; }
+ ListElement{ longitude: "55"; latitude: "51"; height: "121"; }
+ ListElement{ longitude: "55"; latitude: "52"; height: "117"; }
+ ListElement{ longitude: "55"; latitude: "53"; height: "114"; }
+ ListElement{ longitude: "55"; latitude: "54"; height: "112"; }
+ ListElement{ longitude: "55"; latitude: "55"; height: "115"; }
+ ListElement{ longitude: "55"; latitude: "56"; height: "113"; }
+ ListElement{ longitude: "55"; latitude: "57"; height: "112"; }
+ ListElement{ longitude: "55"; latitude: "58"; height: "110"; }
+ ListElement{ longitude: "55"; latitude: "59"; height: "110"; }
+ ListElement{ longitude: "55"; latitude: "60"; height: "111"; }
+ ListElement{ longitude: "55"; latitude: "61"; height: "111"; }
+ ListElement{ longitude: "55"; latitude: "62"; height: "114"; }
+ ListElement{ longitude: "55"; latitude: "63"; height: "113"; }
+ ListElement{ longitude: "55"; latitude: "64"; height: "113"; }
+ ListElement{ longitude: "55"; latitude: "65"; height: "113"; }
+ ListElement{ longitude: "55"; latitude: "66"; height: "113"; }
+ ListElement{ longitude: "55"; latitude: "67"; height: "115"; }
+ ListElement{ longitude: "55"; latitude: "68"; height: "113"; }
+ ListElement{ longitude: "55"; latitude: "69"; height: "111"; }
+ ListElement{ longitude: "55"; latitude: "70"; height: "110"; }
+ ListElement{ longitude: "55"; latitude: "71"; height: "110"; }
+ ListElement{ longitude: "55"; latitude: "72"; height: "109"; }
+ ListElement{ longitude: "55"; latitude: "73"; height: "113"; }
+ ListElement{ longitude: "55"; latitude: "74"; height: "122"; }
+ ListElement{ longitude: "55"; latitude: "75"; height: "145"; }
+ ListElement{ longitude: "55"; latitude: "76"; height: "156"; }
+ ListElement{ longitude: "55"; latitude: "77"; height: "161"; }
+ ListElement{ longitude: "55"; latitude: "78"; height: "148"; }
+ ListElement{ longitude: "55"; latitude: "79"; height: "109"; }
+ ListElement{ longitude: "55"; latitude: "80"; height: "99"; }
+ ListElement{ longitude: "55"; latitude: "81"; height: "90"; }
+ ListElement{ longitude: "55"; latitude: "82"; height: "59"; }
+ ListElement{ longitude: "55"; latitude: "83"; height: "48"; }
+ ListElement{ longitude: "55"; latitude: "84"; height: "35"; }
+ ListElement{ longitude: "55"; latitude: "85"; height: "9"; }
+ ListElement{ longitude: "55"; latitude: "86"; height: "1"; }
+ ListElement{ longitude: "55"; latitude: "87"; height: "32"; }
+ ListElement{ longitude: "55"; latitude: "88"; height: "55"; }
+ ListElement{ longitude: "55"; latitude: "89"; height: "52"; }
+ ListElement{ longitude: "55"; latitude: "90"; height: "55"; }
+ ListElement{ longitude: "55"; latitude: "91"; height: "70"; }
+ ListElement{ longitude: "55"; latitude: "92"; height: "90"; }
+ ListElement{ longitude: "55"; latitude: "93"; height: "124"; }
+ ListElement{ longitude: "55"; latitude: "94"; height: "128"; }
+ ListElement{ longitude: "55"; latitude: "95"; height: "118"; }
+ ListElement{ longitude: "55"; latitude: "96"; height: "122"; }
+ ListElement{ longitude: "55"; latitude: "97"; height: "126"; }
+ ListElement{ longitude: "55"; latitude: "98"; height: "126"; }
+ ListElement{ longitude: "55"; latitude: "99"; height: "119"; }
+ ListElement{ longitude: "56"; latitude: "0"; height: "120"; }
+ ListElement{ longitude: "56"; latitude: "1"; height: "119"; }
+ ListElement{ longitude: "56"; latitude: "2"; height: "119"; }
+ ListElement{ longitude: "56"; latitude: "3"; height: "119"; }
+ ListElement{ longitude: "56"; latitude: "4"; height: "120"; }
+ ListElement{ longitude: "56"; latitude: "5"; height: "121"; }
+ ListElement{ longitude: "56"; latitude: "6"; height: "124"; }
+ ListElement{ longitude: "56"; latitude: "7"; height: "125"; }
+ ListElement{ longitude: "56"; latitude: "8"; height: "126"; }
+ ListElement{ longitude: "56"; latitude: "9"; height: "125"; }
+ ListElement{ longitude: "56"; latitude: "10"; height: "126"; }
+ ListElement{ longitude: "56"; latitude: "11"; height: "122"; }
+ ListElement{ longitude: "56"; latitude: "12"; height: "121"; }
+ ListElement{ longitude: "56"; latitude: "13"; height: "120"; }
+ ListElement{ longitude: "56"; latitude: "14"; height: "121"; }
+ ListElement{ longitude: "56"; latitude: "15"; height: "118"; }
+ ListElement{ longitude: "56"; latitude: "16"; height: "120"; }
+ ListElement{ longitude: "56"; latitude: "17"; height: "120"; }
+ ListElement{ longitude: "56"; latitude: "18"; height: "120"; }
+ ListElement{ longitude: "56"; latitude: "19"; height: "120"; }
+ ListElement{ longitude: "56"; latitude: "20"; height: "119"; }
+ ListElement{ longitude: "56"; latitude: "21"; height: "119"; }
+ ListElement{ longitude: "56"; latitude: "22"; height: "121"; }
+ ListElement{ longitude: "56"; latitude: "23"; height: "120"; }
+ ListElement{ longitude: "56"; latitude: "24"; height: "122"; }
+ ListElement{ longitude: "56"; latitude: "25"; height: "124"; }
+ ListElement{ longitude: "56"; latitude: "26"; height: "120"; }
+ ListElement{ longitude: "56"; latitude: "27"; height: "119"; }
+ ListElement{ longitude: "56"; latitude: "28"; height: "119"; }
+ ListElement{ longitude: "56"; latitude: "29"; height: "120"; }
+ ListElement{ longitude: "56"; latitude: "30"; height: "117"; }
+ ListElement{ longitude: "56"; latitude: "31"; height: "119"; }
+ ListElement{ longitude: "56"; latitude: "32"; height: "123"; }
+ ListElement{ longitude: "56"; latitude: "33"; height: "126"; }
+ ListElement{ longitude: "56"; latitude: "34"; height: "125"; }
+ ListElement{ longitude: "56"; latitude: "35"; height: "125"; }
+ ListElement{ longitude: "56"; latitude: "36"; height: "125"; }
+ ListElement{ longitude: "56"; latitude: "37"; height: "123"; }
+ ListElement{ longitude: "56"; latitude: "38"; height: "126"; }
+ ListElement{ longitude: "56"; latitude: "39"; height: "127"; }
+ ListElement{ longitude: "56"; latitude: "40"; height: "127"; }
+ ListElement{ longitude: "56"; latitude: "41"; height: "130"; }
+ ListElement{ longitude: "56"; latitude: "42"; height: "128"; }
+ ListElement{ longitude: "56"; latitude: "43"; height: "128"; }
+ ListElement{ longitude: "56"; latitude: "44"; height: "128"; }
+ ListElement{ longitude: "56"; latitude: "45"; height: "125"; }
+ ListElement{ longitude: "56"; latitude: "46"; height: "127"; }
+ ListElement{ longitude: "56"; latitude: "47"; height: "126"; }
+ ListElement{ longitude: "56"; latitude: "48"; height: "128"; }
+ ListElement{ longitude: "56"; latitude: "49"; height: "129"; }
+ ListElement{ longitude: "56"; latitude: "50"; height: "128"; }
+ ListElement{ longitude: "56"; latitude: "51"; height: "123"; }
+ ListElement{ longitude: "56"; latitude: "52"; height: "123"; }
+ ListElement{ longitude: "56"; latitude: "53"; height: "118"; }
+ ListElement{ longitude: "56"; latitude: "54"; height: "117"; }
+ ListElement{ longitude: "56"; latitude: "55"; height: "117"; }
+ ListElement{ longitude: "56"; latitude: "56"; height: "117"; }
+ ListElement{ longitude: "56"; latitude: "57"; height: "116"; }
+ ListElement{ longitude: "56"; latitude: "58"; height: "113"; }
+ ListElement{ longitude: "56"; latitude: "59"; height: "114"; }
+ ListElement{ longitude: "56"; latitude: "60"; height: "114"; }
+ ListElement{ longitude: "56"; latitude: "61"; height: "113"; }
+ ListElement{ longitude: "56"; latitude: "62"; height: "115"; }
+ ListElement{ longitude: "56"; latitude: "63"; height: "116"; }
+ ListElement{ longitude: "56"; latitude: "64"; height: "116"; }
+ ListElement{ longitude: "56"; latitude: "65"; height: "116"; }
+ ListElement{ longitude: "56"; latitude: "66"; height: "116"; }
+ ListElement{ longitude: "56"; latitude: "67"; height: "117"; }
+ ListElement{ longitude: "56"; latitude: "68"; height: "114"; }
+ ListElement{ longitude: "56"; latitude: "69"; height: "111"; }
+ ListElement{ longitude: "56"; latitude: "70"; height: "111"; }
+ ListElement{ longitude: "56"; latitude: "71"; height: "107"; }
+ ListElement{ longitude: "56"; latitude: "72"; height: "106"; }
+ ListElement{ longitude: "56"; latitude: "73"; height: "112"; }
+ ListElement{ longitude: "56"; latitude: "74"; height: "117"; }
+ ListElement{ longitude: "56"; latitude: "75"; height: "129"; }
+ ListElement{ longitude: "56"; latitude: "76"; height: "142"; }
+ ListElement{ longitude: "56"; latitude: "77"; height: "164"; }
+ ListElement{ longitude: "56"; latitude: "78"; height: "167"; }
+ ListElement{ longitude: "56"; latitude: "79"; height: "152"; }
+ ListElement{ longitude: "56"; latitude: "80"; height: "134"; }
+ ListElement{ longitude: "56"; latitude: "81"; height: "118"; }
+ ListElement{ longitude: "56"; latitude: "82"; height: "99"; }
+ ListElement{ longitude: "56"; latitude: "83"; height: "102"; }
+ ListElement{ longitude: "56"; latitude: "84"; height: "102"; }
+ ListElement{ longitude: "56"; latitude: "85"; height: "88"; }
+ ListElement{ longitude: "56"; latitude: "86"; height: "73"; }
+ ListElement{ longitude: "56"; latitude: "87"; height: "66"; }
+ ListElement{ longitude: "56"; latitude: "88"; height: "56"; }
+ ListElement{ longitude: "56"; latitude: "89"; height: "51"; }
+ ListElement{ longitude: "56"; latitude: "90"; height: "73"; }
+ ListElement{ longitude: "56"; latitude: "91"; height: "104"; }
+ ListElement{ longitude: "56"; latitude: "92"; height: "110"; }
+ ListElement{ longitude: "56"; latitude: "93"; height: "114"; }
+ ListElement{ longitude: "56"; latitude: "94"; height: "119"; }
+ ListElement{ longitude: "56"; latitude: "95"; height: "122"; }
+ ListElement{ longitude: "56"; latitude: "96"; height: "126"; }
+ ListElement{ longitude: "56"; latitude: "97"; height: "128"; }
+ ListElement{ longitude: "56"; latitude: "98"; height: "127"; }
+ ListElement{ longitude: "56"; latitude: "99"; height: "123"; }
+ ListElement{ longitude: "57"; latitude: "0"; height: "120"; }
+ ListElement{ longitude: "57"; latitude: "1"; height: "121"; }
+ ListElement{ longitude: "57"; latitude: "2"; height: "122"; }
+ ListElement{ longitude: "57"; latitude: "3"; height: "122"; }
+ ListElement{ longitude: "57"; latitude: "4"; height: "120"; }
+ ListElement{ longitude: "57"; latitude: "5"; height: "120"; }
+ ListElement{ longitude: "57"; latitude: "6"; height: "122"; }
+ ListElement{ longitude: "57"; latitude: "7"; height: "123"; }
+ ListElement{ longitude: "57"; latitude: "8"; height: "125"; }
+ ListElement{ longitude: "57"; latitude: "9"; height: "125"; }
+ ListElement{ longitude: "57"; latitude: "10"; height: "125"; }
+ ListElement{ longitude: "57"; latitude: "11"; height: "124"; }
+ ListElement{ longitude: "57"; latitude: "12"; height: "120"; }
+ ListElement{ longitude: "57"; latitude: "13"; height: "119"; }
+ ListElement{ longitude: "57"; latitude: "14"; height: "119"; }
+ ListElement{ longitude: "57"; latitude: "15"; height: "119"; }
+ ListElement{ longitude: "57"; latitude: "16"; height: "120"; }
+ ListElement{ longitude: "57"; latitude: "17"; height: "120"; }
+ ListElement{ longitude: "57"; latitude: "18"; height: "120"; }
+ ListElement{ longitude: "57"; latitude: "19"; height: "120"; }
+ ListElement{ longitude: "57"; latitude: "20"; height: "119"; }
+ ListElement{ longitude: "57"; latitude: "21"; height: "121"; }
+ ListElement{ longitude: "57"; latitude: "22"; height: "120"; }
+ ListElement{ longitude: "57"; latitude: "23"; height: "120"; }
+ ListElement{ longitude: "57"; latitude: "24"; height: "122"; }
+ ListElement{ longitude: "57"; latitude: "25"; height: "122"; }
+ ListElement{ longitude: "57"; latitude: "26"; height: "119"; }
+ ListElement{ longitude: "57"; latitude: "27"; height: "121"; }
+ ListElement{ longitude: "57"; latitude: "28"; height: "121"; }
+ ListElement{ longitude: "57"; latitude: "29"; height: "118"; }
+ ListElement{ longitude: "57"; latitude: "30"; height: "120"; }
+ ListElement{ longitude: "57"; latitude: "31"; height: "123"; }
+ ListElement{ longitude: "57"; latitude: "32"; height: "121"; }
+ ListElement{ longitude: "57"; latitude: "33"; height: "122"; }
+ ListElement{ longitude: "57"; latitude: "34"; height: "124"; }
+ ListElement{ longitude: "57"; latitude: "35"; height: "125"; }
+ ListElement{ longitude: "57"; latitude: "36"; height: "125"; }
+ ListElement{ longitude: "57"; latitude: "37"; height: "122"; }
+ ListElement{ longitude: "57"; latitude: "38"; height: "127"; }
+ ListElement{ longitude: "57"; latitude: "39"; height: "126"; }
+ ListElement{ longitude: "57"; latitude: "40"; height: "128"; }
+ ListElement{ longitude: "57"; latitude: "41"; height: "128"; }
+ ListElement{ longitude: "57"; latitude: "42"; height: "128"; }
+ ListElement{ longitude: "57"; latitude: "43"; height: "128"; }
+ ListElement{ longitude: "57"; latitude: "44"; height: "125"; }
+ ListElement{ longitude: "57"; latitude: "45"; height: "125"; }
+ ListElement{ longitude: "57"; latitude: "46"; height: "125"; }
+ ListElement{ longitude: "57"; latitude: "47"; height: "126"; }
+ ListElement{ longitude: "57"; latitude: "48"; height: "129"; }
+ ListElement{ longitude: "57"; latitude: "49"; height: "130"; }
+ ListElement{ longitude: "57"; latitude: "50"; height: "128"; }
+ ListElement{ longitude: "57"; latitude: "51"; height: "128"; }
+ ListElement{ longitude: "57"; latitude: "52"; height: "118"; }
+ ListElement{ longitude: "57"; latitude: "53"; height: "111"; }
+ ListElement{ longitude: "57"; latitude: "54"; height: "119"; }
+ ListElement{ longitude: "57"; latitude: "55"; height: "120"; }
+ ListElement{ longitude: "57"; latitude: "56"; height: "120"; }
+ ListElement{ longitude: "57"; latitude: "57"; height: "118"; }
+ ListElement{ longitude: "57"; latitude: "58"; height: "117"; }
+ ListElement{ longitude: "57"; latitude: "59"; height: "115"; }
+ ListElement{ longitude: "57"; latitude: "60"; height: "116"; }
+ ListElement{ longitude: "57"; latitude: "61"; height: "114"; }
+ ListElement{ longitude: "57"; latitude: "62"; height: "114"; }
+ ListElement{ longitude: "57"; latitude: "63"; height: "116"; }
+ ListElement{ longitude: "57"; latitude: "64"; height: "116"; }
+ ListElement{ longitude: "57"; latitude: "65"; height: "116"; }
+ ListElement{ longitude: "57"; latitude: "66"; height: "116"; }
+ ListElement{ longitude: "57"; latitude: "67"; height: "114"; }
+ ListElement{ longitude: "57"; latitude: "68"; height: "112"; }
+ ListElement{ longitude: "57"; latitude: "69"; height: "111"; }
+ ListElement{ longitude: "57"; latitude: "70"; height: "111"; }
+ ListElement{ longitude: "57"; latitude: "71"; height: "109"; }
+ ListElement{ longitude: "57"; latitude: "72"; height: "110"; }
+ ListElement{ longitude: "57"; latitude: "73"; height: "113"; }
+ ListElement{ longitude: "57"; latitude: "74"; height: "118"; }
+ ListElement{ longitude: "57"; latitude: "75"; height: "125"; }
+ ListElement{ longitude: "57"; latitude: "76"; height: "133"; }
+ ListElement{ longitude: "57"; latitude: "77"; height: "139"; }
+ ListElement{ longitude: "57"; latitude: "78"; height: "148"; }
+ ListElement{ longitude: "57"; latitude: "79"; height: "161"; }
+ ListElement{ longitude: "57"; latitude: "80"; height: "167"; }
+ ListElement{ longitude: "57"; latitude: "81"; height: "167"; }
+ ListElement{ longitude: "57"; latitude: "82"; height: "164"; }
+ ListElement{ longitude: "57"; latitude: "83"; height: "152"; }
+ ListElement{ longitude: "57"; latitude: "84"; height: "143"; }
+ ListElement{ longitude: "57"; latitude: "85"; height: "138"; }
+ ListElement{ longitude: "57"; latitude: "86"; height: "102"; }
+ ListElement{ longitude: "57"; latitude: "87"; height: "94"; }
+ ListElement{ longitude: "57"; latitude: "88"; height: "81"; }
+ ListElement{ longitude: "57"; latitude: "89"; height: "81"; }
+ ListElement{ longitude: "57"; latitude: "90"; height: "91"; }
+ ListElement{ longitude: "57"; latitude: "91"; height: "99"; }
+ ListElement{ longitude: "57"; latitude: "92"; height: "107"; }
+ ListElement{ longitude: "57"; latitude: "93"; height: "118"; }
+ ListElement{ longitude: "57"; latitude: "94"; height: "126"; }
+ ListElement{ longitude: "57"; latitude: "95"; height: "127"; }
+ ListElement{ longitude: "57"; latitude: "96"; height: "128"; }
+ ListElement{ longitude: "57"; latitude: "97"; height: "130"; }
+ ListElement{ longitude: "57"; latitude: "98"; height: "130"; }
+ ListElement{ longitude: "57"; latitude: "99"; height: "128"; }
+ ListElement{ longitude: "58"; latitude: "0"; height: "121"; }
+ ListElement{ longitude: "58"; latitude: "1"; height: "122"; }
+ ListElement{ longitude: "58"; latitude: "2"; height: "122"; }
+ ListElement{ longitude: "58"; latitude: "3"; height: "120"; }
+ ListElement{ longitude: "58"; latitude: "4"; height: "122"; }
+ ListElement{ longitude: "58"; latitude: "5"; height: "121"; }
+ ListElement{ longitude: "58"; latitude: "6"; height: "123"; }
+ ListElement{ longitude: "58"; latitude: "7"; height: "124"; }
+ ListElement{ longitude: "58"; latitude: "8"; height: "125"; }
+ ListElement{ longitude: "58"; latitude: "9"; height: "121"; }
+ ListElement{ longitude: "58"; latitude: "10"; height: "122"; }
+ ListElement{ longitude: "58"; latitude: "11"; height: "121"; }
+ ListElement{ longitude: "58"; latitude: "12"; height: "120"; }
+ ListElement{ longitude: "58"; latitude: "13"; height: "120"; }
+ ListElement{ longitude: "58"; latitude: "14"; height: "121"; }
+ ListElement{ longitude: "58"; latitude: "15"; height: "119"; }
+ ListElement{ longitude: "58"; latitude: "16"; height: "119"; }
+ ListElement{ longitude: "58"; latitude: "17"; height: "120"; }
+ ListElement{ longitude: "58"; latitude: "18"; height: "120"; }
+ ListElement{ longitude: "58"; latitude: "19"; height: "118"; }
+ ListElement{ longitude: "58"; latitude: "20"; height: "121"; }
+ ListElement{ longitude: "58"; latitude: "21"; height: "121"; }
+ ListElement{ longitude: "58"; latitude: "22"; height: "122"; }
+ ListElement{ longitude: "58"; latitude: "23"; height: "122"; }
+ ListElement{ longitude: "58"; latitude: "24"; height: "122"; }
+ ListElement{ longitude: "58"; latitude: "25"; height: "121"; }
+ ListElement{ longitude: "58"; latitude: "26"; height: "119"; }
+ ListElement{ longitude: "58"; latitude: "27"; height: "121"; }
+ ListElement{ longitude: "58"; latitude: "28"; height: "122"; }
+ ListElement{ longitude: "58"; latitude: "29"; height: "119"; }
+ ListElement{ longitude: "58"; latitude: "30"; height: "115"; }
+ ListElement{ longitude: "58"; latitude: "31"; height: "122"; }
+ ListElement{ longitude: "58"; latitude: "32"; height: "120"; }
+ ListElement{ longitude: "58"; latitude: "33"; height: "121"; }
+ ListElement{ longitude: "58"; latitude: "34"; height: "122"; }
+ ListElement{ longitude: "58"; latitude: "35"; height: "123"; }
+ ListElement{ longitude: "58"; latitude: "36"; height: "125"; }
+ ListElement{ longitude: "58"; latitude: "37"; height: "124"; }
+ ListElement{ longitude: "58"; latitude: "38"; height: "127"; }
+ ListElement{ longitude: "58"; latitude: "39"; height: "128"; }
+ ListElement{ longitude: "58"; latitude: "40"; height: "130"; }
+ ListElement{ longitude: "58"; latitude: "41"; height: "128"; }
+ ListElement{ longitude: "58"; latitude: "42"; height: "127"; }
+ ListElement{ longitude: "58"; latitude: "43"; height: "127"; }
+ ListElement{ longitude: "58"; latitude: "44"; height: "126"; }
+ ListElement{ longitude: "58"; latitude: "45"; height: "126"; }
+ ListElement{ longitude: "58"; latitude: "46"; height: "123"; }
+ ListElement{ longitude: "58"; latitude: "47"; height: "125"; }
+ ListElement{ longitude: "58"; latitude: "48"; height: "130"; }
+ ListElement{ longitude: "58"; latitude: "49"; height: "131"; }
+ ListElement{ longitude: "58"; latitude: "50"; height: "134"; }
+ ListElement{ longitude: "58"; latitude: "51"; height: "131"; }
+ ListElement{ longitude: "58"; latitude: "52"; height: "130"; }
+ ListElement{ longitude: "58"; latitude: "53"; height: "128"; }
+ ListElement{ longitude: "58"; latitude: "54"; height: "124"; }
+ ListElement{ longitude: "58"; latitude: "55"; height: "121"; }
+ ListElement{ longitude: "58"; latitude: "56"; height: "121"; }
+ ListElement{ longitude: "58"; latitude: "57"; height: "120"; }
+ ListElement{ longitude: "58"; latitude: "58"; height: "120"; }
+ ListElement{ longitude: "58"; latitude: "59"; height: "119"; }
+ ListElement{ longitude: "58"; latitude: "60"; height: "118"; }
+ ListElement{ longitude: "58"; latitude: "61"; height: "116"; }
+ ListElement{ longitude: "58"; latitude: "62"; height: "115"; }
+ ListElement{ longitude: "58"; latitude: "63"; height: "115"; }
+ ListElement{ longitude: "58"; latitude: "64"; height: "115"; }
+ ListElement{ longitude: "58"; latitude: "65"; height: "115"; }
+ ListElement{ longitude: "58"; latitude: "66"; height: "117"; }
+ ListElement{ longitude: "58"; latitude: "67"; height: "117"; }
+ ListElement{ longitude: "58"; latitude: "68"; height: "114"; }
+ ListElement{ longitude: "58"; latitude: "69"; height: "111"; }
+ ListElement{ longitude: "58"; latitude: "70"; height: "110"; }
+ ListElement{ longitude: "58"; latitude: "71"; height: "109"; }
+ ListElement{ longitude: "58"; latitude: "72"; height: "109"; }
+ ListElement{ longitude: "58"; latitude: "73"; height: "113"; }
+ ListElement{ longitude: "58"; latitude: "74"; height: "117"; }
+ ListElement{ longitude: "58"; latitude: "75"; height: "122"; }
+ ListElement{ longitude: "58"; latitude: "76"; height: "126"; }
+ ListElement{ longitude: "58"; latitude: "77"; height: "126"; }
+ ListElement{ longitude: "58"; latitude: "78"; height: "136"; }
+ ListElement{ longitude: "58"; latitude: "79"; height: "139"; }
+ ListElement{ longitude: "58"; latitude: "80"; height: "142"; }
+ ListElement{ longitude: "58"; latitude: "81"; height: "149"; }
+ ListElement{ longitude: "58"; latitude: "82"; height: "153"; }
+ ListElement{ longitude: "58"; latitude: "83"; height: "149"; }
+ ListElement{ longitude: "58"; latitude: "84"; height: "141"; }
+ ListElement{ longitude: "58"; latitude: "85"; height: "134"; }
+ ListElement{ longitude: "58"; latitude: "86"; height: "113"; }
+ ListElement{ longitude: "58"; latitude: "87"; height: "94"; }
+ ListElement{ longitude: "58"; latitude: "88"; height: "83"; }
+ ListElement{ longitude: "58"; latitude: "89"; height: "89"; }
+ ListElement{ longitude: "58"; latitude: "90"; height: "98"; }
+ ListElement{ longitude: "58"; latitude: "91"; height: "109"; }
+ ListElement{ longitude: "58"; latitude: "92"; height: "119"; }
+ ListElement{ longitude: "58"; latitude: "93"; height: "126"; }
+ ListElement{ longitude: "58"; latitude: "94"; height: "128"; }
+ ListElement{ longitude: "58"; latitude: "95"; height: "127"; }
+ ListElement{ longitude: "58"; latitude: "96"; height: "129"; }
+ ListElement{ longitude: "58"; latitude: "97"; height: "131"; }
+ ListElement{ longitude: "58"; latitude: "98"; height: "135"; }
+ ListElement{ longitude: "58"; latitude: "99"; height: "131"; }
+ ListElement{ longitude: "59"; latitude: "0"; height: "122"; }
+ ListElement{ longitude: "59"; latitude: "1"; height: "122"; }
+ ListElement{ longitude: "59"; latitude: "2"; height: "122"; }
+ ListElement{ longitude: "59"; latitude: "3"; height: "121"; }
+ ListElement{ longitude: "59"; latitude: "4"; height: "123"; }
+ ListElement{ longitude: "59"; latitude: "5"; height: "122"; }
+ ListElement{ longitude: "59"; latitude: "6"; height: "121"; }
+ ListElement{ longitude: "59"; latitude: "7"; height: "123"; }
+ ListElement{ longitude: "59"; latitude: "8"; height: "125"; }
+ ListElement{ longitude: "59"; latitude: "9"; height: "124"; }
+ ListElement{ longitude: "59"; latitude: "10"; height: "123"; }
+ ListElement{ longitude: "59"; latitude: "11"; height: "120"; }
+ ListElement{ longitude: "59"; latitude: "12"; height: "120"; }
+ ListElement{ longitude: "59"; latitude: "13"; height: "124"; }
+ ListElement{ longitude: "59"; latitude: "14"; height: "124"; }
+ ListElement{ longitude: "59"; latitude: "15"; height: "121"; }
+ ListElement{ longitude: "59"; latitude: "16"; height: "119"; }
+ ListElement{ longitude: "59"; latitude: "17"; height: "120"; }
+ ListElement{ longitude: "59"; latitude: "18"; height: "120"; }
+ ListElement{ longitude: "59"; latitude: "19"; height: "118"; }
+ ListElement{ longitude: "59"; latitude: "20"; height: "121"; }
+ ListElement{ longitude: "59"; latitude: "21"; height: "121"; }
+ ListElement{ longitude: "59"; latitude: "22"; height: "119"; }
+ ListElement{ longitude: "59"; latitude: "23"; height: "119"; }
+ ListElement{ longitude: "59"; latitude: "24"; height: "119"; }
+ ListElement{ longitude: "59"; latitude: "25"; height: "119"; }
+ ListElement{ longitude: "59"; latitude: "26"; height: "120"; }
+ ListElement{ longitude: "59"; latitude: "27"; height: "120"; }
+ ListElement{ longitude: "59"; latitude: "28"; height: "119"; }
+ ListElement{ longitude: "59"; latitude: "29"; height: "113"; }
+ ListElement{ longitude: "59"; latitude: "30"; height: "105"; }
+ ListElement{ longitude: "59"; latitude: "31"; height: "122"; }
+ ListElement{ longitude: "59"; latitude: "32"; height: "123"; }
+ ListElement{ longitude: "59"; latitude: "33"; height: "121"; }
+ ListElement{ longitude: "59"; latitude: "34"; height: "120"; }
+ ListElement{ longitude: "59"; latitude: "35"; height: "123"; }
+ ListElement{ longitude: "59"; latitude: "36"; height: "124"; }
+ ListElement{ longitude: "59"; latitude: "37"; height: "127"; }
+ ListElement{ longitude: "59"; latitude: "38"; height: "124"; }
+ ListElement{ longitude: "59"; latitude: "39"; height: "130"; }
+ ListElement{ longitude: "59"; latitude: "40"; height: "127"; }
+ ListElement{ longitude: "59"; latitude: "41"; height: "128"; }
+ ListElement{ longitude: "59"; latitude: "42"; height: "125"; }
+ ListElement{ longitude: "59"; latitude: "43"; height: "125"; }
+ ListElement{ longitude: "59"; latitude: "44"; height: "125"; }
+ ListElement{ longitude: "59"; latitude: "45"; height: "125"; }
+ ListElement{ longitude: "59"; latitude: "46"; height: "129"; }
+ ListElement{ longitude: "59"; latitude: "47"; height: "131"; }
+ ListElement{ longitude: "59"; latitude: "48"; height: "133"; }
+ ListElement{ longitude: "59"; latitude: "49"; height: "127"; }
+ ListElement{ longitude: "59"; latitude: "50"; height: "136"; }
+ ListElement{ longitude: "59"; latitude: "51"; height: "134"; }
+ ListElement{ longitude: "59"; latitude: "52"; height: "132"; }
+ ListElement{ longitude: "59"; latitude: "53"; height: "129"; }
+ ListElement{ longitude: "59"; latitude: "54"; height: "128"; }
+ ListElement{ longitude: "59"; latitude: "55"; height: "125"; }
+ ListElement{ longitude: "59"; latitude: "56"; height: "123"; }
+ ListElement{ longitude: "59"; latitude: "57"; height: "120"; }
+ ListElement{ longitude: "59"; latitude: "58"; height: "116"; }
+ ListElement{ longitude: "59"; latitude: "59"; height: "115"; }
+ ListElement{ longitude: "59"; latitude: "60"; height: "114"; }
+ ListElement{ longitude: "59"; latitude: "61"; height: "113"; }
+ ListElement{ longitude: "59"; latitude: "62"; height: "112"; }
+ ListElement{ longitude: "59"; latitude: "63"; height: "111"; }
+ ListElement{ longitude: "59"; latitude: "64"; height: "111"; }
+ ListElement{ longitude: "59"; latitude: "65"; height: "111"; }
+ ListElement{ longitude: "59"; latitude: "66"; height: "112"; }
+ ListElement{ longitude: "59"; latitude: "67"; height: "114"; }
+ ListElement{ longitude: "59"; latitude: "68"; height: "113"; }
+ ListElement{ longitude: "59"; latitude: "69"; height: "111"; }
+ ListElement{ longitude: "59"; latitude: "70"; height: "110"; }
+ ListElement{ longitude: "59"; latitude: "71"; height: "112"; }
+ ListElement{ longitude: "59"; latitude: "72"; height: "111"; }
+ ListElement{ longitude: "59"; latitude: "73"; height: "116"; }
+ ListElement{ longitude: "59"; latitude: "74"; height: "117"; }
+ ListElement{ longitude: "59"; latitude: "75"; height: "120"; }
+ ListElement{ longitude: "59"; latitude: "76"; height: "124"; }
+ ListElement{ longitude: "59"; latitude: "77"; height: "118"; }
+ ListElement{ longitude: "59"; latitude: "78"; height: "125"; }
+ ListElement{ longitude: "59"; latitude: "79"; height: "122"; }
+ ListElement{ longitude: "59"; latitude: "80"; height: "132"; }
+ ListElement{ longitude: "59"; latitude: "81"; height: "131"; }
+ ListElement{ longitude: "59"; latitude: "82"; height: "132"; }
+ ListElement{ longitude: "59"; latitude: "83"; height: "139"; }
+ ListElement{ longitude: "59"; latitude: "84"; height: "133"; }
+ ListElement{ longitude: "59"; latitude: "85"; height: "120"; }
+ ListElement{ longitude: "59"; latitude: "86"; height: "111"; }
+ ListElement{ longitude: "59"; latitude: "87"; height: "105"; }
+ ListElement{ longitude: "59"; latitude: "88"; height: "92"; }
+ ListElement{ longitude: "59"; latitude: "89"; height: "95"; }
+ ListElement{ longitude: "59"; latitude: "90"; height: "100"; }
+ ListElement{ longitude: "59"; latitude: "91"; height: "111"; }
+ ListElement{ longitude: "59"; latitude: "92"; height: "120"; }
+ ListElement{ longitude: "59"; latitude: "93"; height: "123"; }
+ ListElement{ longitude: "59"; latitude: "94"; height: "125"; }
+ ListElement{ longitude: "59"; latitude: "95"; height: "130"; }
+ ListElement{ longitude: "59"; latitude: "96"; height: "131"; }
+ ListElement{ longitude: "59"; latitude: "97"; height: "137"; }
+ ListElement{ longitude: "59"; latitude: "98"; height: "138"; }
+ ListElement{ longitude: "59"; latitude: "99"; height: "135"; }
+ ListElement{ longitude: "60"; latitude: "0"; height: "121"; }
+ ListElement{ longitude: "60"; latitude: "1"; height: "118"; }
+ ListElement{ longitude: "60"; latitude: "2"; height: "122"; }
+ ListElement{ longitude: "60"; latitude: "3"; height: "121"; }
+ ListElement{ longitude: "60"; latitude: "4"; height: "124"; }
+ ListElement{ longitude: "60"; latitude: "5"; height: "126"; }
+ ListElement{ longitude: "60"; latitude: "6"; height: "128"; }
+ ListElement{ longitude: "60"; latitude: "7"; height: "126"; }
+ ListElement{ longitude: "60"; latitude: "8"; height: "125"; }
+ ListElement{ longitude: "60"; latitude: "9"; height: "122"; }
+ ListElement{ longitude: "60"; latitude: "10"; height: "121"; }
+ ListElement{ longitude: "60"; latitude: "11"; height: "120"; }
+ ListElement{ longitude: "60"; latitude: "12"; height: "120"; }
+ ListElement{ longitude: "60"; latitude: "13"; height: "119"; }
+ ListElement{ longitude: "60"; latitude: "14"; height: "120"; }
+ ListElement{ longitude: "60"; latitude: "15"; height: "120"; }
+ ListElement{ longitude: "60"; latitude: "16"; height: "121"; }
+ ListElement{ longitude: "60"; latitude: "17"; height: "118"; }
+ ListElement{ longitude: "60"; latitude: "18"; height: "118"; }
+ ListElement{ longitude: "60"; latitude: "19"; height: "120"; }
+ ListElement{ longitude: "60"; latitude: "20"; height: "119"; }
+ ListElement{ longitude: "60"; latitude: "21"; height: "121"; }
+ ListElement{ longitude: "60"; latitude: "22"; height: "121"; }
+ ListElement{ longitude: "60"; latitude: "23"; height: "121"; }
+ ListElement{ longitude: "60"; latitude: "24"; height: "120"; }
+ ListElement{ longitude: "60"; latitude: "25"; height: "118"; }
+ ListElement{ longitude: "60"; latitude: "26"; height: "118"; }
+ ListElement{ longitude: "60"; latitude: "27"; height: "120"; }
+ ListElement{ longitude: "60"; latitude: "28"; height: "119"; }
+ ListElement{ longitude: "60"; latitude: "29"; height: "113"; }
+ ListElement{ longitude: "60"; latitude: "30"; height: "111"; }
+ ListElement{ longitude: "60"; latitude: "31"; height: "122"; }
+ ListElement{ longitude: "60"; latitude: "32"; height: "124"; }
+ ListElement{ longitude: "60"; latitude: "33"; height: "124"; }
+ ListElement{ longitude: "60"; latitude: "34"; height: "123"; }
+ ListElement{ longitude: "60"; latitude: "35"; height: "129"; }
+ ListElement{ longitude: "60"; latitude: "36"; height: "128"; }
+ ListElement{ longitude: "60"; latitude: "37"; height: "128"; }
+ ListElement{ longitude: "60"; latitude: "38"; height: "128"; }
+ ListElement{ longitude: "60"; latitude: "39"; height: "127"; }
+ ListElement{ longitude: "60"; latitude: "40"; height: "125"; }
+ ListElement{ longitude: "60"; latitude: "41"; height: "124"; }
+ ListElement{ longitude: "60"; latitude: "42"; height: "122"; }
+ ListElement{ longitude: "60"; latitude: "43"; height: "122"; }
+ ListElement{ longitude: "60"; latitude: "44"; height: "118"; }
+ ListElement{ longitude: "60"; latitude: "45"; height: "120"; }
+ ListElement{ longitude: "60"; latitude: "46"; height: "126"; }
+ ListElement{ longitude: "60"; latitude: "47"; height: "127"; }
+ ListElement{ longitude: "60"; latitude: "48"; height: "130"; }
+ ListElement{ longitude: "60"; latitude: "49"; height: "136"; }
+ ListElement{ longitude: "60"; latitude: "50"; height: "139"; }
+ ListElement{ longitude: "60"; latitude: "51"; height: "135"; }
+ ListElement{ longitude: "60"; latitude: "52"; height: "133"; }
+ ListElement{ longitude: "60"; latitude: "53"; height: "130"; }
+ ListElement{ longitude: "60"; latitude: "54"; height: "124"; }
+ ListElement{ longitude: "60"; latitude: "55"; height: "117"; }
+ ListElement{ longitude: "60"; latitude: "56"; height: "119"; }
+ ListElement{ longitude: "60"; latitude: "57"; height: "117"; }
+ ListElement{ longitude: "60"; latitude: "58"; height: "116"; }
+ ListElement{ longitude: "60"; latitude: "59"; height: "113"; }
+ ListElement{ longitude: "60"; latitude: "60"; height: "112"; }
+ ListElement{ longitude: "60"; latitude: "61"; height: "113"; }
+ ListElement{ longitude: "60"; latitude: "62"; height: "114"; }
+ ListElement{ longitude: "60"; latitude: "63"; height: "112"; }
+ ListElement{ longitude: "60"; latitude: "64"; height: "111"; }
+ ListElement{ longitude: "60"; latitude: "65"; height: "111"; }
+ ListElement{ longitude: "60"; latitude: "66"; height: "110"; }
+ ListElement{ longitude: "60"; latitude: "67"; height: "112"; }
+ ListElement{ longitude: "60"; latitude: "68"; height: "112"; }
+ ListElement{ longitude: "60"; latitude: "69"; height: "112"; }
+ ListElement{ longitude: "60"; latitude: "70"; height: "112"; }
+ ListElement{ longitude: "60"; latitude: "71"; height: "113"; }
+ ListElement{ longitude: "60"; latitude: "72"; height: "113"; }
+ ListElement{ longitude: "60"; latitude: "73"; height: "113"; }
+ ListElement{ longitude: "60"; latitude: "74"; height: "119"; }
+ ListElement{ longitude: "60"; latitude: "75"; height: "117"; }
+ ListElement{ longitude: "60"; latitude: "76"; height: "123"; }
+ ListElement{ longitude: "60"; latitude: "77"; height: "123"; }
+ ListElement{ longitude: "60"; latitude: "78"; height: "127"; }
+ ListElement{ longitude: "60"; latitude: "79"; height: "125"; }
+ ListElement{ longitude: "60"; latitude: "80"; height: "130"; }
+ ListElement{ longitude: "60"; latitude: "81"; height: "124"; }
+ ListElement{ longitude: "60"; latitude: "82"; height: "132"; }
+ ListElement{ longitude: "60"; latitude: "83"; height: "132"; }
+ ListElement{ longitude: "60"; latitude: "84"; height: "130"; }
+ ListElement{ longitude: "60"; latitude: "85"; height: "122"; }
+ ListElement{ longitude: "60"; latitude: "86"; height: "113"; }
+ ListElement{ longitude: "60"; latitude: "87"; height: "102"; }
+ ListElement{ longitude: "60"; latitude: "88"; height: "98"; }
+ ListElement{ longitude: "60"; latitude: "89"; height: "103"; }
+ ListElement{ longitude: "60"; latitude: "90"; height: "112"; }
+ ListElement{ longitude: "60"; latitude: "91"; height: "114"; }
+ ListElement{ longitude: "60"; latitude: "92"; height: "119"; }
+ ListElement{ longitude: "60"; latitude: "93"; height: "122"; }
+ ListElement{ longitude: "60"; latitude: "94"; height: "127"; }
+ ListElement{ longitude: "60"; latitude: "95"; height: "129"; }
+ ListElement{ longitude: "60"; latitude: "96"; height: "137"; }
+ ListElement{ longitude: "60"; latitude: "97"; height: "139"; }
+ ListElement{ longitude: "60"; latitude: "98"; height: "140"; }
+ ListElement{ longitude: "60"; latitude: "99"; height: "138"; }
+ ListElement{ longitude: "61"; latitude: "0"; height: "122"; }
+ ListElement{ longitude: "61"; latitude: "1"; height: "120"; }
+ ListElement{ longitude: "61"; latitude: "2"; height: "122"; }
+ ListElement{ longitude: "61"; latitude: "3"; height: "122"; }
+ ListElement{ longitude: "61"; latitude: "4"; height: "125"; }
+ ListElement{ longitude: "61"; latitude: "5"; height: "127"; }
+ ListElement{ longitude: "61"; latitude: "6"; height: "129"; }
+ ListElement{ longitude: "61"; latitude: "7"; height: "127"; }
+ ListElement{ longitude: "61"; latitude: "8"; height: "127"; }
+ ListElement{ longitude: "61"; latitude: "9"; height: "123"; }
+ ListElement{ longitude: "61"; latitude: "10"; height: "121"; }
+ ListElement{ longitude: "61"; latitude: "11"; height: "123"; }
+ ListElement{ longitude: "61"; latitude: "12"; height: "125"; }
+ ListElement{ longitude: "61"; latitude: "13"; height: "123"; }
+ ListElement{ longitude: "61"; latitude: "14"; height: "123"; }
+ ListElement{ longitude: "61"; latitude: "15"; height: "123"; }
+ ListElement{ longitude: "61"; latitude: "16"; height: "122"; }
+ ListElement{ longitude: "61"; latitude: "17"; height: "121"; }
+ ListElement{ longitude: "61"; latitude: "18"; height: "118"; }
+ ListElement{ longitude: "61"; latitude: "19"; height: "120"; }
+ ListElement{ longitude: "61"; latitude: "20"; height: "118"; }
+ ListElement{ longitude: "61"; latitude: "21"; height: "121"; }
+ ListElement{ longitude: "61"; latitude: "22"; height: "121"; }
+ ListElement{ longitude: "61"; latitude: "23"; height: "121"; }
+ ListElement{ longitude: "61"; latitude: "24"; height: "121"; }
+ ListElement{ longitude: "61"; latitude: "25"; height: "119"; }
+ ListElement{ longitude: "61"; latitude: "26"; height: "117"; }
+ ListElement{ longitude: "61"; latitude: "27"; height: "120"; }
+ ListElement{ longitude: "61"; latitude: "28"; height: "120"; }
+ ListElement{ longitude: "61"; latitude: "29"; height: "118"; }
+ ListElement{ longitude: "61"; latitude: "30"; height: "117"; }
+ ListElement{ longitude: "61"; latitude: "31"; height: "123"; }
+ ListElement{ longitude: "61"; latitude: "32"; height: "126"; }
+ ListElement{ longitude: "61"; latitude: "33"; height: "125"; }
+ ListElement{ longitude: "61"; latitude: "34"; height: "127"; }
+ ListElement{ longitude: "61"; latitude: "35"; height: "130"; }
+ ListElement{ longitude: "61"; latitude: "36"; height: "129"; }
+ ListElement{ longitude: "61"; latitude: "37"; height: "130"; }
+ ListElement{ longitude: "61"; latitude: "38"; height: "129"; }
+ ListElement{ longitude: "61"; latitude: "39"; height: "128"; }
+ ListElement{ longitude: "61"; latitude: "40"; height: "126"; }
+ ListElement{ longitude: "61"; latitude: "41"; height: "107"; }
+ ListElement{ longitude: "61"; latitude: "42"; height: "98"; }
+ ListElement{ longitude: "61"; latitude: "43"; height: "117"; }
+ ListElement{ longitude: "61"; latitude: "44"; height: "117"; }
+ ListElement{ longitude: "61"; latitude: "45"; height: "121"; }
+ ListElement{ longitude: "61"; latitude: "46"; height: "126"; }
+ ListElement{ longitude: "61"; latitude: "47"; height: "125"; }
+ ListElement{ longitude: "61"; latitude: "48"; height: "130"; }
+ ListElement{ longitude: "61"; latitude: "49"; height: "137"; }
+ ListElement{ longitude: "61"; latitude: "50"; height: "138"; }
+ ListElement{ longitude: "61"; latitude: "51"; height: "134"; }
+ ListElement{ longitude: "61"; latitude: "52"; height: "134"; }
+ ListElement{ longitude: "61"; latitude: "53"; height: "131"; }
+ ListElement{ longitude: "61"; latitude: "54"; height: "119"; }
+ ListElement{ longitude: "61"; latitude: "55"; height: "121"; }
+ ListElement{ longitude: "61"; latitude: "56"; height: "121"; }
+ ListElement{ longitude: "61"; latitude: "57"; height: "117"; }
+ ListElement{ longitude: "61"; latitude: "58"; height: "113"; }
+ ListElement{ longitude: "61"; latitude: "59"; height: "111"; }
+ ListElement{ longitude: "61"; latitude: "60"; height: "110"; }
+ ListElement{ longitude: "61"; latitude: "61"; height: "109"; }
+ ListElement{ longitude: "61"; latitude: "62"; height: "109"; }
+ ListElement{ longitude: "61"; latitude: "63"; height: "110"; }
+ ListElement{ longitude: "61"; latitude: "64"; height: "108"; }
+ ListElement{ longitude: "61"; latitude: "65"; height: "108"; }
+ ListElement{ longitude: "61"; latitude: "66"; height: "108"; }
+ ListElement{ longitude: "61"; latitude: "67"; height: "108"; }
+ ListElement{ longitude: "61"; latitude: "68"; height: "110"; }
+ ListElement{ longitude: "61"; latitude: "69"; height: "109"; }
+ ListElement{ longitude: "61"; latitude: "70"; height: "110"; }
+ ListElement{ longitude: "61"; latitude: "71"; height: "112"; }
+ ListElement{ longitude: "61"; latitude: "72"; height: "116"; }
+ ListElement{ longitude: "61"; latitude: "73"; height: "116"; }
+ ListElement{ longitude: "61"; latitude: "74"; height: "119"; }
+ ListElement{ longitude: "61"; latitude: "75"; height: "120"; }
+ ListElement{ longitude: "61"; latitude: "76"; height: "123"; }
+ ListElement{ longitude: "61"; latitude: "77"; height: "121"; }
+ ListElement{ longitude: "61"; latitude: "78"; height: "125"; }
+ ListElement{ longitude: "61"; latitude: "79"; height: "122"; }
+ ListElement{ longitude: "61"; latitude: "80"; height: "124"; }
+ ListElement{ longitude: "61"; latitude: "81"; height: "125"; }
+ ListElement{ longitude: "61"; latitude: "82"; height: "128"; }
+ ListElement{ longitude: "61"; latitude: "83"; height: "128"; }
+ ListElement{ longitude: "61"; latitude: "84"; height: "124"; }
+ ListElement{ longitude: "61"; latitude: "85"; height: "119"; }
+ ListElement{ longitude: "61"; latitude: "86"; height: "116"; }
+ ListElement{ longitude: "61"; latitude: "87"; height: "112"; }
+ ListElement{ longitude: "61"; latitude: "88"; height: "110"; }
+ ListElement{ longitude: "61"; latitude: "89"; height: "109"; }
+ ListElement{ longitude: "61"; latitude: "90"; height: "113"; }
+ ListElement{ longitude: "61"; latitude: "91"; height: "119"; }
+ ListElement{ longitude: "61"; latitude: "92"; height: "119"; }
+ ListElement{ longitude: "61"; latitude: "93"; height: "118"; }
+ ListElement{ longitude: "61"; latitude: "94"; height: "120"; }
+ ListElement{ longitude: "61"; latitude: "95"; height: "124"; }
+ ListElement{ longitude: "61"; latitude: "96"; height: "131"; }
+ ListElement{ longitude: "61"; latitude: "97"; height: "144"; }
+ ListElement{ longitude: "61"; latitude: "98"; height: "143"; }
+ ListElement{ longitude: "61"; latitude: "99"; height: "137"; }
+ ListElement{ longitude: "62"; latitude: "0"; height: "122"; }
+ ListElement{ longitude: "62"; latitude: "1"; height: "121"; }
+ ListElement{ longitude: "62"; latitude: "2"; height: "121"; }
+ ListElement{ longitude: "62"; latitude: "3"; height: "124"; }
+ ListElement{ longitude: "62"; latitude: "4"; height: "127"; }
+ ListElement{ longitude: "62"; latitude: "5"; height: "128"; }
+ ListElement{ longitude: "62"; latitude: "6"; height: "128"; }
+ ListElement{ longitude: "62"; latitude: "7"; height: "125"; }
+ ListElement{ longitude: "62"; latitude: "8"; height: "122"; }
+ ListElement{ longitude: "62"; latitude: "9"; height: "122"; }
+ ListElement{ longitude: "62"; latitude: "10"; height: "120"; }
+ ListElement{ longitude: "62"; latitude: "11"; height: "122"; }
+ ListElement{ longitude: "62"; latitude: "12"; height: "123"; }
+ ListElement{ longitude: "62"; latitude: "13"; height: "123"; }
+ ListElement{ longitude: "62"; latitude: "14"; height: "127"; }
+ ListElement{ longitude: "62"; latitude: "15"; height: "125"; }
+ ListElement{ longitude: "62"; latitude: "16"; height: "124"; }
+ ListElement{ longitude: "62"; latitude: "17"; height: "121"; }
+ ListElement{ longitude: "62"; latitude: "18"; height: "120"; }
+ ListElement{ longitude: "62"; latitude: "19"; height: "117"; }
+ ListElement{ longitude: "62"; latitude: "20"; height: "116"; }
+ ListElement{ longitude: "62"; latitude: "21"; height: "119"; }
+ ListElement{ longitude: "62"; latitude: "22"; height: "110"; }
+ ListElement{ longitude: "62"; latitude: "23"; height: "110"; }
+ ListElement{ longitude: "62"; latitude: "24"; height: "119"; }
+ ListElement{ longitude: "62"; latitude: "25"; height: "119"; }
+ ListElement{ longitude: "62"; latitude: "26"; height: "116"; }
+ ListElement{ longitude: "62"; latitude: "27"; height: "114"; }
+ ListElement{ longitude: "62"; latitude: "28"; height: "114"; }
+ ListElement{ longitude: "62"; latitude: "29"; height: "117"; }
+ ListElement{ longitude: "62"; latitude: "30"; height: "121"; }
+ ListElement{ longitude: "62"; latitude: "31"; height: "121"; }
+ ListElement{ longitude: "62"; latitude: "32"; height: "123"; }
+ ListElement{ longitude: "62"; latitude: "33"; height: "122"; }
+ ListElement{ longitude: "62"; latitude: "34"; height: "124"; }
+ ListElement{ longitude: "62"; latitude: "35"; height: "130"; }
+ ListElement{ longitude: "62"; latitude: "36"; height: "128"; }
+ ListElement{ longitude: "62"; latitude: "37"; height: "125"; }
+ ListElement{ longitude: "62"; latitude: "38"; height: "124"; }
+ ListElement{ longitude: "62"; latitude: "39"; height: "123"; }
+ ListElement{ longitude: "62"; latitude: "40"; height: "125"; }
+ ListElement{ longitude: "62"; latitude: "41"; height: "106"; }
+ ListElement{ longitude: "62"; latitude: "42"; height: "94"; }
+ ListElement{ longitude: "62"; latitude: "43"; height: "120"; }
+ ListElement{ longitude: "62"; latitude: "44"; height: "122"; }
+ ListElement{ longitude: "62"; latitude: "45"; height: "120"; }
+ ListElement{ longitude: "62"; latitude: "46"; height: "126"; }
+ ListElement{ longitude: "62"; latitude: "47"; height: "125"; }
+ ListElement{ longitude: "62"; latitude: "48"; height: "132"; }
+ ListElement{ longitude: "62"; latitude: "49"; height: "137"; }
+ ListElement{ longitude: "62"; latitude: "50"; height: "137"; }
+ ListElement{ longitude: "62"; latitude: "51"; height: "127"; }
+ ListElement{ longitude: "62"; latitude: "52"; height: "131"; }
+ ListElement{ longitude: "62"; latitude: "53"; height: "128"; }
+ ListElement{ longitude: "62"; latitude: "54"; height: "125"; }
+ ListElement{ longitude: "62"; latitude: "55"; height: "123"; }
+ ListElement{ longitude: "62"; latitude: "56"; height: "110"; }
+ ListElement{ longitude: "62"; latitude: "57"; height: "116"; }
+ ListElement{ longitude: "62"; latitude: "58"; height: "112"; }
+ ListElement{ longitude: "62"; latitude: "59"; height: "109"; }
+ ListElement{ longitude: "62"; latitude: "60"; height: "108"; }
+ ListElement{ longitude: "62"; latitude: "61"; height: "107"; }
+ ListElement{ longitude: "62"; latitude: "62"; height: "107"; }
+ ListElement{ longitude: "62"; latitude: "63"; height: "107"; }
+ ListElement{ longitude: "62"; latitude: "64"; height: "108"; }
+ ListElement{ longitude: "62"; latitude: "65"; height: "108"; }
+ ListElement{ longitude: "62"; latitude: "66"; height: "108"; }
+ ListElement{ longitude: "62"; latitude: "67"; height: "106"; }
+ ListElement{ longitude: "62"; latitude: "68"; height: "107"; }
+ ListElement{ longitude: "62"; latitude: "69"; height: "107"; }
+ ListElement{ longitude: "62"; latitude: "70"; height: "109"; }
+ ListElement{ longitude: "62"; latitude: "71"; height: "114"; }
+ ListElement{ longitude: "62"; latitude: "72"; height: "116"; }
+ ListElement{ longitude: "62"; latitude: "73"; height: "118"; }
+ ListElement{ longitude: "62"; latitude: "74"; height: "119"; }
+ ListElement{ longitude: "62"; latitude: "75"; height: "121"; }
+ ListElement{ longitude: "62"; latitude: "76"; height: "123"; }
+ ListElement{ longitude: "62"; latitude: "77"; height: "126"; }
+ ListElement{ longitude: "62"; latitude: "78"; height: "126"; }
+ ListElement{ longitude: "62"; latitude: "79"; height: "123"; }
+ ListElement{ longitude: "62"; latitude: "80"; height: "121"; }
+ ListElement{ longitude: "62"; latitude: "81"; height: "123"; }
+ ListElement{ longitude: "62"; latitude: "82"; height: "123"; }
+ ListElement{ longitude: "62"; latitude: "83"; height: "127"; }
+ ListElement{ longitude: "62"; latitude: "84"; height: "124"; }
+ ListElement{ longitude: "62"; latitude: "85"; height: "119"; }
+ ListElement{ longitude: "62"; latitude: "86"; height: "118"; }
+ ListElement{ longitude: "62"; latitude: "87"; height: "116"; }
+ ListElement{ longitude: "62"; latitude: "88"; height: "117"; }
+ ListElement{ longitude: "62"; latitude: "89"; height: "113"; }
+ ListElement{ longitude: "62"; latitude: "90"; height: "114"; }
+ ListElement{ longitude: "62"; latitude: "91"; height: "116"; }
+ ListElement{ longitude: "62"; latitude: "92"; height: "120"; }
+ ListElement{ longitude: "62"; latitude: "93"; height: "116"; }
+ ListElement{ longitude: "62"; latitude: "94"; height: "116"; }
+ ListElement{ longitude: "62"; latitude: "95"; height: "118"; }
+ ListElement{ longitude: "62"; latitude: "96"; height: "126"; }
+ ListElement{ longitude: "62"; latitude: "97"; height: "126"; }
+ ListElement{ longitude: "62"; latitude: "98"; height: "122"; }
+ ListElement{ longitude: "62"; latitude: "99"; height: "124"; }
+ ListElement{ longitude: "63"; latitude: "0"; height: "125"; }
+ ListElement{ longitude: "63"; latitude: "1"; height: "125"; }
+ ListElement{ longitude: "63"; latitude: "2"; height: "122"; }
+ ListElement{ longitude: "63"; latitude: "3"; height: "120"; }
+ ListElement{ longitude: "63"; latitude: "4"; height: "122"; }
+ ListElement{ longitude: "63"; latitude: "5"; height: "122"; }
+ ListElement{ longitude: "63"; latitude: "6"; height: "121"; }
+ ListElement{ longitude: "63"; latitude: "7"; height: "122"; }
+ ListElement{ longitude: "63"; latitude: "8"; height: "121"; }
+ ListElement{ longitude: "63"; latitude: "9"; height: "118"; }
+ ListElement{ longitude: "63"; latitude: "10"; height: "121"; }
+ ListElement{ longitude: "63"; latitude: "11"; height: "119"; }
+ ListElement{ longitude: "63"; latitude: "12"; height: "122"; }
+ ListElement{ longitude: "63"; latitude: "13"; height: "121"; }
+ ListElement{ longitude: "63"; latitude: "14"; height: "121"; }
+ ListElement{ longitude: "63"; latitude: "15"; height: "122"; }
+ ListElement{ longitude: "63"; latitude: "16"; height: "121"; }
+ ListElement{ longitude: "63"; latitude: "17"; height: "120"; }
+ ListElement{ longitude: "63"; latitude: "18"; height: "119"; }
+ ListElement{ longitude: "63"; latitude: "19"; height: "116"; }
+ ListElement{ longitude: "63"; latitude: "20"; height: "115"; }
+ ListElement{ longitude: "63"; latitude: "21"; height: "116"; }
+ ListElement{ longitude: "63"; latitude: "22"; height: "109"; }
+ ListElement{ longitude: "63"; latitude: "23"; height: "109"; }
+ ListElement{ longitude: "63"; latitude: "24"; height: "117"; }
+ ListElement{ longitude: "63"; latitude: "25"; height: "113"; }
+ ListElement{ longitude: "63"; latitude: "26"; height: "112"; }
+ ListElement{ longitude: "63"; latitude: "27"; height: "111"; }
+ ListElement{ longitude: "63"; latitude: "28"; height: "111"; }
+ ListElement{ longitude: "63"; latitude: "29"; height: "113"; }
+ ListElement{ longitude: "63"; latitude: "30"; height: "115"; }
+ ListElement{ longitude: "63"; latitude: "31"; height: "119"; }
+ ListElement{ longitude: "63"; latitude: "32"; height: "121"; }
+ ListElement{ longitude: "63"; latitude: "33"; height: "122"; }
+ ListElement{ longitude: "63"; latitude: "34"; height: "124"; }
+ ListElement{ longitude: "63"; latitude: "35"; height: "127"; }
+ ListElement{ longitude: "63"; latitude: "36"; height: "127"; }
+ ListElement{ longitude: "63"; latitude: "37"; height: "122"; }
+ ListElement{ longitude: "63"; latitude: "38"; height: "125"; }
+ ListElement{ longitude: "63"; latitude: "39"; height: "121"; }
+ ListElement{ longitude: "63"; latitude: "40"; height: "123"; }
+ ListElement{ longitude: "63"; latitude: "41"; height: "121"; }
+ ListElement{ longitude: "63"; latitude: "42"; height: "118"; }
+ ListElement{ longitude: "63"; latitude: "43"; height: "126"; }
+ ListElement{ longitude: "63"; latitude: "44"; height: "125"; }
+ ListElement{ longitude: "63"; latitude: "45"; height: "124"; }
+ ListElement{ longitude: "63"; latitude: "46"; height: "125"; }
+ ListElement{ longitude: "63"; latitude: "47"; height: "128"; }
+ ListElement{ longitude: "63"; latitude: "48"; height: "133"; }
+ ListElement{ longitude: "63"; latitude: "49"; height: "135"; }
+ ListElement{ longitude: "63"; latitude: "50"; height: "136"; }
+ ListElement{ longitude: "63"; latitude: "51"; height: "132"; }
+ ListElement{ longitude: "63"; latitude: "52"; height: "128"; }
+ ListElement{ longitude: "63"; latitude: "53"; height: "124"; }
+ ListElement{ longitude: "63"; latitude: "54"; height: "122"; }
+ ListElement{ longitude: "63"; latitude: "55"; height: "121"; }
+ ListElement{ longitude: "63"; latitude: "56"; height: "110"; }
+ ListElement{ longitude: "63"; latitude: "57"; height: "113"; }
+ ListElement{ longitude: "63"; latitude: "58"; height: "113"; }
+ ListElement{ longitude: "63"; latitude: "59"; height: "109"; }
+ ListElement{ longitude: "63"; latitude: "60"; height: "107"; }
+ ListElement{ longitude: "63"; latitude: "61"; height: "106"; }
+ ListElement{ longitude: "63"; latitude: "62"; height: "106"; }
+ ListElement{ longitude: "63"; latitude: "63"; height: "106"; }
+ ListElement{ longitude: "63"; latitude: "64"; height: "104"; }
+ ListElement{ longitude: "63"; latitude: "65"; height: "104"; }
+ ListElement{ longitude: "63"; latitude: "66"; height: "104"; }
+ ListElement{ longitude: "63"; latitude: "67"; height: "106"; }
+ ListElement{ longitude: "63"; latitude: "68"; height: "106"; }
+ ListElement{ longitude: "63"; latitude: "69"; height: "107"; }
+ ListElement{ longitude: "63"; latitude: "70"; height: "109"; }
+ ListElement{ longitude: "63"; latitude: "71"; height: "114"; }
+ ListElement{ longitude: "63"; latitude: "72"; height: "115"; }
+ ListElement{ longitude: "63"; latitude: "73"; height: "117"; }
+ ListElement{ longitude: "63"; latitude: "74"; height: "122"; }
+ ListElement{ longitude: "63"; latitude: "75"; height: "123"; }
+ ListElement{ longitude: "63"; latitude: "76"; height: "127"; }
+ ListElement{ longitude: "63"; latitude: "77"; height: "128"; }
+ ListElement{ longitude: "63"; latitude: "78"; height: "127"; }
+ ListElement{ longitude: "63"; latitude: "79"; height: "124"; }
+ ListElement{ longitude: "63"; latitude: "80"; height: "125"; }
+ ListElement{ longitude: "63"; latitude: "81"; height: "122"; }
+ ListElement{ longitude: "63"; latitude: "82"; height: "123"; }
+ ListElement{ longitude: "63"; latitude: "83"; height: "123"; }
+ ListElement{ longitude: "63"; latitude: "84"; height: "123"; }
+ ListElement{ longitude: "63"; latitude: "85"; height: "121"; }
+ ListElement{ longitude: "63"; latitude: "86"; height: "115"; }
+ ListElement{ longitude: "63"; latitude: "87"; height: "115"; }
+ ListElement{ longitude: "63"; latitude: "88"; height: "117"; }
+ ListElement{ longitude: "63"; latitude: "89"; height: "117"; }
+ ListElement{ longitude: "63"; latitude: "90"; height: "118"; }
+ ListElement{ longitude: "63"; latitude: "91"; height: "121"; }
+ ListElement{ longitude: "63"; latitude: "92"; height: "119"; }
+ ListElement{ longitude: "63"; latitude: "93"; height: "109"; }
+ ListElement{ longitude: "63"; latitude: "94"; height: "111"; }
+ ListElement{ longitude: "63"; latitude: "95"; height: "116"; }
+ ListElement{ longitude: "63"; latitude: "96"; height: "121"; }
+ ListElement{ longitude: "63"; latitude: "97"; height: "119"; }
+ ListElement{ longitude: "63"; latitude: "98"; height: "124"; }
+ ListElement{ longitude: "63"; latitude: "99"; height: "118"; }
+ ListElement{ longitude: "64"; latitude: "0"; height: "127"; }
+ ListElement{ longitude: "64"; latitude: "1"; height: "127"; }
+ ListElement{ longitude: "64"; latitude: "2"; height: "127"; }
+ ListElement{ longitude: "64"; latitude: "3"; height: "120"; }
+ ListElement{ longitude: "64"; latitude: "4"; height: "120"; }
+ ListElement{ longitude: "64"; latitude: "5"; height: "118"; }
+ ListElement{ longitude: "64"; latitude: "6"; height: "119"; }
+ ListElement{ longitude: "64"; latitude: "7"; height: "118"; }
+ ListElement{ longitude: "64"; latitude: "8"; height: "119"; }
+ ListElement{ longitude: "64"; latitude: "9"; height: "114"; }
+ ListElement{ longitude: "64"; latitude: "10"; height: "114"; }
+ ListElement{ longitude: "64"; latitude: "11"; height: "114"; }
+ ListElement{ longitude: "64"; latitude: "12"; height: "114"; }
+ ListElement{ longitude: "64"; latitude: "13"; height: "115"; }
+ ListElement{ longitude: "64"; latitude: "14"; height: "116"; }
+ ListElement{ longitude: "64"; latitude: "15"; height: "117"; }
+ ListElement{ longitude: "64"; latitude: "16"; height: "119"; }
+ ListElement{ longitude: "64"; latitude: "17"; height: "119"; }
+ ListElement{ longitude: "64"; latitude: "18"; height: "116"; }
+ ListElement{ longitude: "64"; latitude: "19"; height: "115"; }
+ ListElement{ longitude: "64"; latitude: "20"; height: "114"; }
+ ListElement{ longitude: "64"; latitude: "21"; height: "116"; }
+ ListElement{ longitude: "64"; latitude: "22"; height: "118"; }
+ ListElement{ longitude: "64"; latitude: "23"; height: "116"; }
+ ListElement{ longitude: "64"; latitude: "24"; height: "113"; }
+ ListElement{ longitude: "64"; latitude: "25"; height: "111"; }
+ ListElement{ longitude: "64"; latitude: "26"; height: "109"; }
+ ListElement{ longitude: "64"; latitude: "27"; height: "108"; }
+ ListElement{ longitude: "64"; latitude: "28"; height: "110"; }
+ ListElement{ longitude: "64"; latitude: "29"; height: "110"; }
+ ListElement{ longitude: "64"; latitude: "30"; height: "114"; }
+ ListElement{ longitude: "64"; latitude: "31"; height: "114"; }
+ ListElement{ longitude: "64"; latitude: "32"; height: "118"; }
+ ListElement{ longitude: "64"; latitude: "33"; height: "119"; }
+ ListElement{ longitude: "64"; latitude: "34"; height: "120"; }
+ ListElement{ longitude: "64"; latitude: "35"; height: "121"; }
+ ListElement{ longitude: "64"; latitude: "36"; height: "121"; }
+ ListElement{ longitude: "64"; latitude: "37"; height: "121"; }
+ ListElement{ longitude: "64"; latitude: "38"; height: "122"; }
+ ListElement{ longitude: "64"; latitude: "39"; height: "116"; }
+ ListElement{ longitude: "64"; latitude: "40"; height: "119"; }
+ ListElement{ longitude: "64"; latitude: "41"; height: "123"; }
+ ListElement{ longitude: "64"; latitude: "42"; height: "129"; }
+ ListElement{ longitude: "64"; latitude: "43"; height: "127"; }
+ ListElement{ longitude: "64"; latitude: "44"; height: "128"; }
+ ListElement{ longitude: "64"; latitude: "45"; height: "127"; }
+ ListElement{ longitude: "64"; latitude: "46"; height: "128"; }
+ ListElement{ longitude: "64"; latitude: "47"; height: "130"; }
+ ListElement{ longitude: "64"; latitude: "48"; height: "134"; }
+ ListElement{ longitude: "64"; latitude: "49"; height: "137"; }
+ ListElement{ longitude: "64"; latitude: "50"; height: "135"; }
+ ListElement{ longitude: "64"; latitude: "51"; height: "126"; }
+ ListElement{ longitude: "64"; latitude: "52"; height: "125"; }
+ ListElement{ longitude: "64"; latitude: "53"; height: "122"; }
+ ListElement{ longitude: "64"; latitude: "54"; height: "120"; }
+ ListElement{ longitude: "64"; latitude: "55"; height: "120"; }
+ ListElement{ longitude: "64"; latitude: "56"; height: "121"; }
+ ListElement{ longitude: "64"; latitude: "57"; height: "118"; }
+ ListElement{ longitude: "64"; latitude: "58"; height: "112"; }
+ ListElement{ longitude: "64"; latitude: "59"; height: "109"; }
+ ListElement{ longitude: "64"; latitude: "60"; height: "107"; }
+ ListElement{ longitude: "64"; latitude: "61"; height: "106"; }
+ ListElement{ longitude: "64"; latitude: "62"; height: "106"; }
+ ListElement{ longitude: "64"; latitude: "63"; height: "106"; }
+ ListElement{ longitude: "64"; latitude: "64"; height: "108"; }
+ ListElement{ longitude: "64"; latitude: "65"; height: "108"; }
+ ListElement{ longitude: "64"; latitude: "66"; height: "108"; }
+ ListElement{ longitude: "64"; latitude: "67"; height: "110"; }
+ ListElement{ longitude: "64"; latitude: "68"; height: "107"; }
+ ListElement{ longitude: "64"; latitude: "69"; height: "110"; }
+ ListElement{ longitude: "64"; latitude: "70"; height: "110"; }
+ ListElement{ longitude: "64"; latitude: "71"; height: "113"; }
+ ListElement{ longitude: "64"; latitude: "72"; height: "115"; }
+ ListElement{ longitude: "64"; latitude: "73"; height: "118"; }
+ ListElement{ longitude: "64"; latitude: "74"; height: "123"; }
+ ListElement{ longitude: "64"; latitude: "75"; height: "127"; }
+ ListElement{ longitude: "64"; latitude: "76"; height: "129"; }
+ ListElement{ longitude: "64"; latitude: "77"; height: "130"; }
+ ListElement{ longitude: "64"; latitude: "78"; height: "131"; }
+ ListElement{ longitude: "64"; latitude: "79"; height: "127"; }
+ ListElement{ longitude: "64"; latitude: "80"; height: "123"; }
+ ListElement{ longitude: "64"; latitude: "81"; height: "121"; }
+ ListElement{ longitude: "64"; latitude: "82"; height: "120"; }
+ ListElement{ longitude: "64"; latitude: "83"; height: "120"; }
+ ListElement{ longitude: "64"; latitude: "84"; height: "120"; }
+ ListElement{ longitude: "64"; latitude: "85"; height: "121"; }
+ ListElement{ longitude: "64"; latitude: "86"; height: "117"; }
+ ListElement{ longitude: "64"; latitude: "87"; height: "116"; }
+ ListElement{ longitude: "64"; latitude: "88"; height: "116"; }
+ ListElement{ longitude: "64"; latitude: "89"; height: "118"; }
+ ListElement{ longitude: "64"; latitude: "90"; height: "120"; }
+ ListElement{ longitude: "64"; latitude: "91"; height: "122"; }
+ ListElement{ longitude: "64"; latitude: "92"; height: "119"; }
+ ListElement{ longitude: "64"; latitude: "93"; height: "106"; }
+ ListElement{ longitude: "64"; latitude: "94"; height: "111"; }
+ ListElement{ longitude: "64"; latitude: "95"; height: "116"; }
+ ListElement{ longitude: "64"; latitude: "96"; height: "120"; }
+ ListElement{ longitude: "64"; latitude: "97"; height: "118"; }
+ ListElement{ longitude: "64"; latitude: "98"; height: "119"; }
+ ListElement{ longitude: "64"; latitude: "99"; height: "116"; }
+ ListElement{ longitude: "65"; latitude: "0"; height: "128"; }
+ ListElement{ longitude: "65"; latitude: "1"; height: "128"; }
+ ListElement{ longitude: "65"; latitude: "2"; height: "127"; }
+ ListElement{ longitude: "65"; latitude: "3"; height: "123"; }
+ ListElement{ longitude: "65"; latitude: "4"; height: "122"; }
+ ListElement{ longitude: "65"; latitude: "5"; height: "119"; }
+ ListElement{ longitude: "65"; latitude: "6"; height: "120"; }
+ ListElement{ longitude: "65"; latitude: "7"; height: "117"; }
+ ListElement{ longitude: "65"; latitude: "8"; height: "117"; }
+ ListElement{ longitude: "65"; latitude: "9"; height: "114"; }
+ ListElement{ longitude: "65"; latitude: "10"; height: "112"; }
+ ListElement{ longitude: "65"; latitude: "11"; height: "110"; }
+ ListElement{ longitude: "65"; latitude: "12"; height: "110"; }
+ ListElement{ longitude: "65"; latitude: "13"; height: "111"; }
+ ListElement{ longitude: "65"; latitude: "14"; height: "113"; }
+ ListElement{ longitude: "65"; latitude: "15"; height: "118"; }
+ ListElement{ longitude: "65"; latitude: "16"; height: "117"; }
+ ListElement{ longitude: "65"; latitude: "17"; height: "114"; }
+ ListElement{ longitude: "65"; latitude: "18"; height: "116"; }
+ ListElement{ longitude: "65"; latitude: "19"; height: "114"; }
+ ListElement{ longitude: "65"; latitude: "20"; height: "114"; }
+ ListElement{ longitude: "65"; latitude: "21"; height: "116"; }
+ ListElement{ longitude: "65"; latitude: "22"; height: "117"; }
+ ListElement{ longitude: "65"; latitude: "23"; height: "117"; }
+ ListElement{ longitude: "65"; latitude: "24"; height: "113"; }
+ ListElement{ longitude: "65"; latitude: "25"; height: "112"; }
+ ListElement{ longitude: "65"; latitude: "26"; height: "107"; }
+ ListElement{ longitude: "65"; latitude: "27"; height: "104"; }
+ ListElement{ longitude: "65"; latitude: "28"; height: "104"; }
+ ListElement{ longitude: "65"; latitude: "29"; height: "108"; }
+ ListElement{ longitude: "65"; latitude: "30"; height: "110"; }
+ ListElement{ longitude: "65"; latitude: "31"; height: "112"; }
+ ListElement{ longitude: "65"; latitude: "32"; height: "115"; }
+ ListElement{ longitude: "65"; latitude: "33"; height: "115"; }
+ ListElement{ longitude: "65"; latitude: "34"; height: "115"; }
+ ListElement{ longitude: "65"; latitude: "35"; height: "113"; }
+ ListElement{ longitude: "65"; latitude: "36"; height: "117"; }
+ ListElement{ longitude: "65"; latitude: "37"; height: "116"; }
+ ListElement{ longitude: "65"; latitude: "38"; height: "114"; }
+ ListElement{ longitude: "65"; latitude: "39"; height: "116"; }
+ ListElement{ longitude: "65"; latitude: "40"; height: "118"; }
+ ListElement{ longitude: "65"; latitude: "41"; height: "122"; }
+ ListElement{ longitude: "65"; latitude: "42"; height: "129"; }
+ ListElement{ longitude: "65"; latitude: "43"; height: "130"; }
+ ListElement{ longitude: "65"; latitude: "44"; height: "131"; }
+ ListElement{ longitude: "65"; latitude: "45"; height: "132"; }
+ ListElement{ longitude: "65"; latitude: "46"; height: "133"; }
+ ListElement{ longitude: "65"; latitude: "47"; height: "134"; }
+ ListElement{ longitude: "65"; latitude: "48"; height: "130"; }
+ ListElement{ longitude: "65"; latitude: "49"; height: "136"; }
+ ListElement{ longitude: "65"; latitude: "50"; height: "133"; }
+ ListElement{ longitude: "65"; latitude: "51"; height: "120"; }
+ ListElement{ longitude: "65"; latitude: "52"; height: "125"; }
+ ListElement{ longitude: "65"; latitude: "53"; height: "124"; }
+ ListElement{ longitude: "65"; latitude: "54"; height: "120"; }
+ ListElement{ longitude: "65"; latitude: "55"; height: "119"; }
+ ListElement{ longitude: "65"; latitude: "56"; height: "119"; }
+ ListElement{ longitude: "65"; latitude: "57"; height: "117"; }
+ ListElement{ longitude: "65"; latitude: "58"; height: "113"; }
+ ListElement{ longitude: "65"; latitude: "59"; height: "110"; }
+ ListElement{ longitude: "65"; latitude: "60"; height: "110"; }
+ ListElement{ longitude: "65"; latitude: "61"; height: "108"; }
+ ListElement{ longitude: "65"; latitude: "62"; height: "109"; }
+ ListElement{ longitude: "65"; latitude: "63"; height: "109"; }
+ ListElement{ longitude: "65"; latitude: "64"; height: "107"; }
+ ListElement{ longitude: "65"; latitude: "65"; height: "107"; }
+ ListElement{ longitude: "65"; latitude: "66"; height: "107"; }
+ ListElement{ longitude: "65"; latitude: "67"; height: "109"; }
+ ListElement{ longitude: "65"; latitude: "68"; height: "104"; }
+ ListElement{ longitude: "65"; latitude: "69"; height: "112"; }
+ ListElement{ longitude: "65"; latitude: "70"; height: "112"; }
+ ListElement{ longitude: "65"; latitude: "71"; height: "116"; }
+ ListElement{ longitude: "65"; latitude: "72"; height: "118"; }
+ ListElement{ longitude: "65"; latitude: "73"; height: "119"; }
+ ListElement{ longitude: "65"; latitude: "74"; height: "126"; }
+ ListElement{ longitude: "65"; latitude: "75"; height: "128"; }
+ ListElement{ longitude: "65"; latitude: "76"; height: "132"; }
+ ListElement{ longitude: "65"; latitude: "77"; height: "129"; }
+ ListElement{ longitude: "65"; latitude: "78"; height: "131"; }
+ ListElement{ longitude: "65"; latitude: "79"; height: "129"; }
+ ListElement{ longitude: "65"; latitude: "80"; height: "124"; }
+ ListElement{ longitude: "65"; latitude: "81"; height: "119"; }
+ ListElement{ longitude: "65"; latitude: "82"; height: "120"; }
+ ListElement{ longitude: "65"; latitude: "83"; height: "121"; }
+ ListElement{ longitude: "65"; latitude: "84"; height: "121"; }
+ ListElement{ longitude: "65"; latitude: "85"; height: "120"; }
+ ListElement{ longitude: "65"; latitude: "86"; height: "119"; }
+ ListElement{ longitude: "65"; latitude: "87"; height: "116"; }
+ ListElement{ longitude: "65"; latitude: "88"; height: "116"; }
+ ListElement{ longitude: "65"; latitude: "89"; height: "118"; }
+ ListElement{ longitude: "65"; latitude: "90"; height: "120"; }
+ ListElement{ longitude: "65"; latitude: "91"; height: "122"; }
+ ListElement{ longitude: "65"; latitude: "92"; height: "120"; }
+ ListElement{ longitude: "65"; latitude: "93"; height: "111"; }
+ ListElement{ longitude: "65"; latitude: "94"; height: "110"; }
+ ListElement{ longitude: "65"; latitude: "95"; height: "110"; }
+ ListElement{ longitude: "65"; latitude: "96"; height: "117"; }
+ ListElement{ longitude: "65"; latitude: "97"; height: "116"; }
+ ListElement{ longitude: "65"; latitude: "98"; height: "116"; }
+ ListElement{ longitude: "65"; latitude: "99"; height: "116"; }
+ ListElement{ longitude: "66"; latitude: "0"; height: "128"; }
+ ListElement{ longitude: "66"; latitude: "1"; height: "130"; }
+ ListElement{ longitude: "66"; latitude: "2"; height: "127"; }
+ ListElement{ longitude: "66"; latitude: "3"; height: "125"; }
+ ListElement{ longitude: "66"; latitude: "4"; height: "123"; }
+ ListElement{ longitude: "66"; latitude: "5"; height: "120"; }
+ ListElement{ longitude: "66"; latitude: "6"; height: "121"; }
+ ListElement{ longitude: "66"; latitude: "7"; height: "119"; }
+ ListElement{ longitude: "66"; latitude: "8"; height: "115"; }
+ ListElement{ longitude: "66"; latitude: "9"; height: "113"; }
+ ListElement{ longitude: "66"; latitude: "10"; height: "110"; }
+ ListElement{ longitude: "66"; latitude: "11"; height: "107"; }
+ ListElement{ longitude: "66"; latitude: "12"; height: "108"; }
+ ListElement{ longitude: "66"; latitude: "13"; height: "111"; }
+ ListElement{ longitude: "66"; latitude: "14"; height: "111"; }
+ ListElement{ longitude: "66"; latitude: "15"; height: "116"; }
+ ListElement{ longitude: "66"; latitude: "16"; height: "114"; }
+ ListElement{ longitude: "66"; latitude: "17"; height: "112"; }
+ ListElement{ longitude: "66"; latitude: "18"; height: "114"; }
+ ListElement{ longitude: "66"; latitude: "19"; height: "115"; }
+ ListElement{ longitude: "66"; latitude: "20"; height: "114"; }
+ ListElement{ longitude: "66"; latitude: "21"; height: "119"; }
+ ListElement{ longitude: "66"; latitude: "22"; height: "117"; }
+ ListElement{ longitude: "66"; latitude: "23"; height: "117"; }
+ ListElement{ longitude: "66"; latitude: "24"; height: "115"; }
+ ListElement{ longitude: "66"; latitude: "25"; height: "112"; }
+ ListElement{ longitude: "66"; latitude: "26"; height: "107"; }
+ ListElement{ longitude: "66"; latitude: "27"; height: "102"; }
+ ListElement{ longitude: "66"; latitude: "28"; height: "102"; }
+ ListElement{ longitude: "66"; latitude: "29"; height: "107"; }
+ ListElement{ longitude: "66"; latitude: "30"; height: "110"; }
+ ListElement{ longitude: "66"; latitude: "31"; height: "110"; }
+ ListElement{ longitude: "66"; latitude: "32"; height: "113"; }
+ ListElement{ longitude: "66"; latitude: "33"; height: "114"; }
+ ListElement{ longitude: "66"; latitude: "34"; height: "113"; }
+ ListElement{ longitude: "66"; latitude: "35"; height: "114"; }
+ ListElement{ longitude: "66"; latitude: "36"; height: "112"; }
+ ListElement{ longitude: "66"; latitude: "37"; height: "111"; }
+ ListElement{ longitude: "66"; latitude: "38"; height: "114"; }
+ ListElement{ longitude: "66"; latitude: "39"; height: "116"; }
+ ListElement{ longitude: "66"; latitude: "40"; height: "119"; }
+ ListElement{ longitude: "66"; latitude: "41"; height: "124"; }
+ ListElement{ longitude: "66"; latitude: "42"; height: "126"; }
+ ListElement{ longitude: "66"; latitude: "43"; height: "131"; }
+ ListElement{ longitude: "66"; latitude: "44"; height: "133"; }
+ ListElement{ longitude: "66"; latitude: "45"; height: "136"; }
+ ListElement{ longitude: "66"; latitude: "46"; height: "137"; }
+ ListElement{ longitude: "66"; latitude: "47"; height: "134"; }
+ ListElement{ longitude: "66"; latitude: "48"; height: "136"; }
+ ListElement{ longitude: "66"; latitude: "49"; height: "128"; }
+ ListElement{ longitude: "66"; latitude: "50"; height: "130"; }
+ ListElement{ longitude: "66"; latitude: "51"; height: "121"; }
+ ListElement{ longitude: "66"; latitude: "52"; height: "124"; }
+ ListElement{ longitude: "66"; latitude: "53"; height: "125"; }
+ ListElement{ longitude: "66"; latitude: "54"; height: "121"; }
+ ListElement{ longitude: "66"; latitude: "55"; height: "120"; }
+ ListElement{ longitude: "66"; latitude: "56"; height: "118"; }
+ ListElement{ longitude: "66"; latitude: "57"; height: "118"; }
+ ListElement{ longitude: "66"; latitude: "58"; height: "117"; }
+ ListElement{ longitude: "66"; latitude: "59"; height: "109"; }
+ ListElement{ longitude: "66"; latitude: "60"; height: "114"; }
+ ListElement{ longitude: "66"; latitude: "61"; height: "109"; }
+ ListElement{ longitude: "66"; latitude: "62"; height: "110"; }
+ ListElement{ longitude: "66"; latitude: "63"; height: "111"; }
+ ListElement{ longitude: "66"; latitude: "64"; height: "110"; }
+ ListElement{ longitude: "66"; latitude: "65"; height: "108"; }
+ ListElement{ longitude: "66"; latitude: "66"; height: "108"; }
+ ListElement{ longitude: "66"; latitude: "67"; height: "109"; }
+ ListElement{ longitude: "66"; latitude: "68"; height: "112"; }
+ ListElement{ longitude: "66"; latitude: "69"; height: "112"; }
+ ListElement{ longitude: "66"; latitude: "70"; height: "114"; }
+ ListElement{ longitude: "66"; latitude: "71"; height: "117"; }
+ ListElement{ longitude: "66"; latitude: "72"; height: "119"; }
+ ListElement{ longitude: "66"; latitude: "73"; height: "120"; }
+ ListElement{ longitude: "66"; latitude: "74"; height: "123"; }
+ ListElement{ longitude: "66"; latitude: "75"; height: "128"; }
+ ListElement{ longitude: "66"; latitude: "76"; height: "131"; }
+ ListElement{ longitude: "66"; latitude: "77"; height: "134"; }
+ ListElement{ longitude: "66"; latitude: "78"; height: "136"; }
+ ListElement{ longitude: "66"; latitude: "79"; height: "130"; }
+ ListElement{ longitude: "66"; latitude: "80"; height: "126"; }
+ ListElement{ longitude: "66"; latitude: "81"; height: "120"; }
+ ListElement{ longitude: "66"; latitude: "82"; height: "120"; }
+ ListElement{ longitude: "66"; latitude: "83"; height: "119"; }
+ ListElement{ longitude: "66"; latitude: "84"; height: "119"; }
+ ListElement{ longitude: "66"; latitude: "85"; height: "119"; }
+ ListElement{ longitude: "66"; latitude: "86"; height: "120"; }
+ ListElement{ longitude: "66"; latitude: "87"; height: "117"; }
+ ListElement{ longitude: "66"; latitude: "88"; height: "116"; }
+ ListElement{ longitude: "66"; latitude: "89"; height: "114"; }
+ ListElement{ longitude: "66"; latitude: "90"; height: "117"; }
+ ListElement{ longitude: "66"; latitude: "91"; height: "120"; }
+ ListElement{ longitude: "66"; latitude: "92"; height: "121"; }
+ ListElement{ longitude: "66"; latitude: "93"; height: "114"; }
+ ListElement{ longitude: "66"; latitude: "94"; height: "115"; }
+ ListElement{ longitude: "66"; latitude: "95"; height: "112"; }
+ ListElement{ longitude: "66"; latitude: "96"; height: "119"; }
+ ListElement{ longitude: "66"; latitude: "97"; height: "116"; }
+ ListElement{ longitude: "66"; latitude: "98"; height: "116"; }
+ ListElement{ longitude: "66"; latitude: "99"; height: "119"; }
+ ListElement{ longitude: "67"; latitude: "0"; height: "126"; }
+ ListElement{ longitude: "67"; latitude: "1"; height: "128"; }
+ ListElement{ longitude: "67"; latitude: "2"; height: "127"; }
+ ListElement{ longitude: "67"; latitude: "3"; height: "126"; }
+ ListElement{ longitude: "67"; latitude: "4"; height: "124"; }
+ ListElement{ longitude: "67"; latitude: "5"; height: "120"; }
+ ListElement{ longitude: "67"; latitude: "6"; height: "121"; }
+ ListElement{ longitude: "67"; latitude: "7"; height: "119"; }
+ ListElement{ longitude: "67"; latitude: "8"; height: "116"; }
+ ListElement{ longitude: "67"; latitude: "9"; height: "114"; }
+ ListElement{ longitude: "67"; latitude: "10"; height: "111"; }
+ ListElement{ longitude: "67"; latitude: "11"; height: "108"; }
+ ListElement{ longitude: "67"; latitude: "12"; height: "108"; }
+ ListElement{ longitude: "67"; latitude: "13"; height: "108"; }
+ ListElement{ longitude: "67"; latitude: "14"; height: "109"; }
+ ListElement{ longitude: "67"; latitude: "15"; height: "109"; }
+ ListElement{ longitude: "67"; latitude: "16"; height: "109"; }
+ ListElement{ longitude: "67"; latitude: "17"; height: "112"; }
+ ListElement{ longitude: "67"; latitude: "18"; height: "112"; }
+ ListElement{ longitude: "67"; latitude: "19"; height: "110"; }
+ ListElement{ longitude: "67"; latitude: "20"; height: "97"; }
+ ListElement{ longitude: "67"; latitude: "21"; height: "113"; }
+ ListElement{ longitude: "67"; latitude: "22"; height: "118"; }
+ ListElement{ longitude: "67"; latitude: "23"; height: "118"; }
+ ListElement{ longitude: "67"; latitude: "24"; height: "114"; }
+ ListElement{ longitude: "67"; latitude: "25"; height: "112"; }
+ ListElement{ longitude: "67"; latitude: "26"; height: "109"; }
+ ListElement{ longitude: "67"; latitude: "27"; height: "105"; }
+ ListElement{ longitude: "67"; latitude: "28"; height: "104"; }
+ ListElement{ longitude: "67"; latitude: "29"; height: "102"; }
+ ListElement{ longitude: "67"; latitude: "30"; height: "107"; }
+ ListElement{ longitude: "67"; latitude: "31"; height: "111"; }
+ ListElement{ longitude: "67"; latitude: "32"; height: "111"; }
+ ListElement{ longitude: "67"; latitude: "33"; height: "114"; }
+ ListElement{ longitude: "67"; latitude: "34"; height: "113"; }
+ ListElement{ longitude: "67"; latitude: "35"; height: "112"; }
+ ListElement{ longitude: "67"; latitude: "36"; height: "110"; }
+ ListElement{ longitude: "67"; latitude: "37"; height: "109"; }
+ ListElement{ longitude: "67"; latitude: "38"; height: "114"; }
+ ListElement{ longitude: "67"; latitude: "39"; height: "117"; }
+ ListElement{ longitude: "67"; latitude: "40"; height: "122"; }
+ ListElement{ longitude: "67"; latitude: "41"; height: "125"; }
+ ListElement{ longitude: "67"; latitude: "42"; height: "128"; }
+ ListElement{ longitude: "67"; latitude: "43"; height: "131"; }
+ ListElement{ longitude: "67"; latitude: "44"; height: "134"; }
+ ListElement{ longitude: "67"; latitude: "45"; height: "136"; }
+ ListElement{ longitude: "67"; latitude: "46"; height: "134"; }
+ ListElement{ longitude: "67"; latitude: "47"; height: "133"; }
+ ListElement{ longitude: "67"; latitude: "48"; height: "136"; }
+ ListElement{ longitude: "67"; latitude: "49"; height: "133"; }
+ ListElement{ longitude: "67"; latitude: "50"; height: "129"; }
+ ListElement{ longitude: "67"; latitude: "51"; height: "128"; }
+ ListElement{ longitude: "67"; latitude: "52"; height: "128"; }
+ ListElement{ longitude: "67"; latitude: "53"; height: "128"; }
+ ListElement{ longitude: "67"; latitude: "54"; height: "123"; }
+ ListElement{ longitude: "67"; latitude: "55"; height: "123"; }
+ ListElement{ longitude: "67"; latitude: "56"; height: "121"; }
+ ListElement{ longitude: "67"; latitude: "57"; height: "118"; }
+ ListElement{ longitude: "67"; latitude: "58"; height: "117"; }
+ ListElement{ longitude: "67"; latitude: "59"; height: "104"; }
+ ListElement{ longitude: "67"; latitude: "60"; height: "114"; }
+ ListElement{ longitude: "67"; latitude: "61"; height: "117"; }
+ ListElement{ longitude: "67"; latitude: "62"; height: "116"; }
+ ListElement{ longitude: "67"; latitude: "63"; height: "114"; }
+ ListElement{ longitude: "67"; latitude: "64"; height: "110"; }
+ ListElement{ longitude: "67"; latitude: "65"; height: "109"; }
+ ListElement{ longitude: "67"; latitude: "66"; height: "111"; }
+ ListElement{ longitude: "67"; latitude: "67"; height: "112"; }
+ ListElement{ longitude: "67"; latitude: "68"; height: "112"; }
+ ListElement{ longitude: "67"; latitude: "69"; height: "116"; }
+ ListElement{ longitude: "67"; latitude: "70"; height: "117"; }
+ ListElement{ longitude: "67"; latitude: "71"; height: "119"; }
+ ListElement{ longitude: "67"; latitude: "72"; height: "118"; }
+ ListElement{ longitude: "67"; latitude: "73"; height: "121"; }
+ ListElement{ longitude: "67"; latitude: "74"; height: "124"; }
+ ListElement{ longitude: "67"; latitude: "75"; height: "127"; }
+ ListElement{ longitude: "67"; latitude: "76"; height: "132"; }
+ ListElement{ longitude: "67"; latitude: "77"; height: "132"; }
+ ListElement{ longitude: "67"; latitude: "78"; height: "132"; }
+ ListElement{ longitude: "67"; latitude: "79"; height: "124"; }
+ ListElement{ longitude: "67"; latitude: "80"; height: "127"; }
+ ListElement{ longitude: "67"; latitude: "81"; height: "123"; }
+ ListElement{ longitude: "67"; latitude: "82"; height: "121"; }
+ ListElement{ longitude: "67"; latitude: "83"; height: "122"; }
+ ListElement{ longitude: "67"; latitude: "84"; height: "122"; }
+ ListElement{ longitude: "67"; latitude: "85"; height: "122"; }
+ ListElement{ longitude: "67"; latitude: "86"; height: "122"; }
+ ListElement{ longitude: "67"; latitude: "87"; height: "120"; }
+ ListElement{ longitude: "67"; latitude: "88"; height: "116"; }
+ ListElement{ longitude: "67"; latitude: "89"; height: "115"; }
+ ListElement{ longitude: "67"; latitude: "90"; height: "115"; }
+ ListElement{ longitude: "67"; latitude: "91"; height: "117"; }
+ ListElement{ longitude: "67"; latitude: "92"; height: "120"; }
+ ListElement{ longitude: "67"; latitude: "93"; height: "122"; }
+ ListElement{ longitude: "67"; latitude: "94"; height: "121"; }
+ ListElement{ longitude: "67"; latitude: "95"; height: "120"; }
+ ListElement{ longitude: "67"; latitude: "96"; height: "124"; }
+ ListElement{ longitude: "67"; latitude: "97"; height: "128"; }
+ ListElement{ longitude: "67"; latitude: "98"; height: "122"; }
+ ListElement{ longitude: "67"; latitude: "99"; height: "123"; }
+ ListElement{ longitude: "68"; latitude: "0"; height: "125"; }
+ ListElement{ longitude: "68"; latitude: "1"; height: "126"; }
+ ListElement{ longitude: "68"; latitude: "2"; height: "128"; }
+ ListElement{ longitude: "68"; latitude: "3"; height: "125"; }
+ ListElement{ longitude: "68"; latitude: "4"; height: "121"; }
+ ListElement{ longitude: "68"; latitude: "5"; height: "121"; }
+ ListElement{ longitude: "68"; latitude: "6"; height: "120"; }
+ ListElement{ longitude: "68"; latitude: "7"; height: "118"; }
+ ListElement{ longitude: "68"; latitude: "8"; height: "115"; }
+ ListElement{ longitude: "68"; latitude: "9"; height: "110"; }
+ ListElement{ longitude: "68"; latitude: "10"; height: "109"; }
+ ListElement{ longitude: "68"; latitude: "11"; height: "108"; }
+ ListElement{ longitude: "68"; latitude: "12"; height: "109"; }
+ ListElement{ longitude: "68"; latitude: "13"; height: "109"; }
+ ListElement{ longitude: "68"; latitude: "14"; height: "108"; }
+ ListElement{ longitude: "68"; latitude: "15"; height: "108"; }
+ ListElement{ longitude: "68"; latitude: "16"; height: "104"; }
+ ListElement{ longitude: "68"; latitude: "17"; height: "108"; }
+ ListElement{ longitude: "68"; latitude: "18"; height: "111"; }
+ ListElement{ longitude: "68"; latitude: "19"; height: "113"; }
+ ListElement{ longitude: "68"; latitude: "20"; height: "105"; }
+ ListElement{ longitude: "68"; latitude: "21"; height: "114"; }
+ ListElement{ longitude: "68"; latitude: "22"; height: "114"; }
+ ListElement{ longitude: "68"; latitude: "23"; height: "114"; }
+ ListElement{ longitude: "68"; latitude: "24"; height: "113"; }
+ ListElement{ longitude: "68"; latitude: "25"; height: "111"; }
+ ListElement{ longitude: "68"; latitude: "26"; height: "109"; }
+ ListElement{ longitude: "68"; latitude: "27"; height: "107"; }
+ ListElement{ longitude: "68"; latitude: "28"; height: "105"; }
+ ListElement{ longitude: "68"; latitude: "29"; height: "104"; }
+ ListElement{ longitude: "68"; latitude: "30"; height: "100"; }
+ ListElement{ longitude: "68"; latitude: "31"; height: "105"; }
+ ListElement{ longitude: "68"; latitude: "32"; height: "107"; }
+ ListElement{ longitude: "68"; latitude: "33"; height: "109"; }
+ ListElement{ longitude: "68"; latitude: "34"; height: "111"; }
+ ListElement{ longitude: "68"; latitude: "35"; height: "108"; }
+ ListElement{ longitude: "68"; latitude: "36"; height: "109"; }
+ ListElement{ longitude: "68"; latitude: "37"; height: "111"; }
+ ListElement{ longitude: "68"; latitude: "38"; height: "116"; }
+ ListElement{ longitude: "68"; latitude: "39"; height: "118"; }
+ ListElement{ longitude: "68"; latitude: "40"; height: "123"; }
+ ListElement{ longitude: "68"; latitude: "41"; height: "122"; }
+ ListElement{ longitude: "68"; latitude: "42"; height: "131"; }
+ ListElement{ longitude: "68"; latitude: "43"; height: "124"; }
+ ListElement{ longitude: "68"; latitude: "44"; height: "131"; }
+ ListElement{ longitude: "68"; latitude: "45"; height: "130"; }
+ ListElement{ longitude: "68"; latitude: "46"; height: "131"; }
+ ListElement{ longitude: "68"; latitude: "47"; height: "129"; }
+ ListElement{ longitude: "68"; latitude: "48"; height: "130"; }
+ ListElement{ longitude: "68"; latitude: "49"; height: "126"; }
+ ListElement{ longitude: "68"; latitude: "50"; height: "128"; }
+ ListElement{ longitude: "68"; latitude: "51"; height: "130"; }
+ ListElement{ longitude: "68"; latitude: "52"; height: "129"; }
+ ListElement{ longitude: "68"; latitude: "53"; height: "127"; }
+ ListElement{ longitude: "68"; latitude: "54"; height: "126"; }
+ ListElement{ longitude: "68"; latitude: "55"; height: "124"; }
+ ListElement{ longitude: "68"; latitude: "56"; height: "121"; }
+ ListElement{ longitude: "68"; latitude: "57"; height: "119"; }
+ ListElement{ longitude: "68"; latitude: "58"; height: "120"; }
+ ListElement{ longitude: "68"; latitude: "59"; height: "120"; }
+ ListElement{ longitude: "68"; latitude: "60"; height: "120"; }
+ ListElement{ longitude: "68"; latitude: "61"; height: "122"; }
+ ListElement{ longitude: "68"; latitude: "62"; height: "121"; }
+ ListElement{ longitude: "68"; latitude: "63"; height: "115"; }
+ ListElement{ longitude: "68"; latitude: "64"; height: "115"; }
+ ListElement{ longitude: "68"; latitude: "65"; height: "111"; }
+ ListElement{ longitude: "68"; latitude: "66"; height: "111"; }
+ ListElement{ longitude: "68"; latitude: "67"; height: "112"; }
+ ListElement{ longitude: "68"; latitude: "68"; height: "116"; }
+ ListElement{ longitude: "68"; latitude: "69"; height: "116"; }
+ ListElement{ longitude: "68"; latitude: "70"; height: "119"; }
+ ListElement{ longitude: "68"; latitude: "71"; height: "119"; }
+ ListElement{ longitude: "68"; latitude: "72"; height: "119"; }
+ ListElement{ longitude: "68"; latitude: "73"; height: "119"; }
+ ListElement{ longitude: "68"; latitude: "74"; height: "121"; }
+ ListElement{ longitude: "68"; latitude: "75"; height: "126"; }
+ ListElement{ longitude: "68"; latitude: "76"; height: "127"; }
+ ListElement{ longitude: "68"; latitude: "77"; height: "129"; }
+ ListElement{ longitude: "68"; latitude: "78"; height: "133"; }
+ ListElement{ longitude: "68"; latitude: "79"; height: "130"; }
+ ListElement{ longitude: "68"; latitude: "80"; height: "128"; }
+ ListElement{ longitude: "68"; latitude: "81"; height: "125"; }
+ ListElement{ longitude: "68"; latitude: "82"; height: "123"; }
+ ListElement{ longitude: "68"; latitude: "83"; height: "122"; }
+ ListElement{ longitude: "68"; latitude: "84"; height: "122"; }
+ ListElement{ longitude: "68"; latitude: "85"; height: "123"; }
+ ListElement{ longitude: "68"; latitude: "86"; height: "124"; }
+ ListElement{ longitude: "68"; latitude: "87"; height: "122"; }
+ ListElement{ longitude: "68"; latitude: "88"; height: "117"; }
+ ListElement{ longitude: "68"; latitude: "89"; height: "115"; }
+ ListElement{ longitude: "68"; latitude: "90"; height: "115"; }
+ ListElement{ longitude: "68"; latitude: "91"; height: "116"; }
+ ListElement{ longitude: "68"; latitude: "92"; height: "118"; }
+ ListElement{ longitude: "68"; latitude: "93"; height: "122"; }
+ ListElement{ longitude: "68"; latitude: "94"; height: "122"; }
+ ListElement{ longitude: "68"; latitude: "95"; height: "124"; }
+ ListElement{ longitude: "68"; latitude: "96"; height: "128"; }
+ ListElement{ longitude: "68"; latitude: "97"; height: "133"; }
+ ListElement{ longitude: "68"; latitude: "98"; height: "125"; }
+ ListElement{ longitude: "68"; latitude: "99"; height: "124"; }
+ ListElement{ longitude: "69"; latitude: "0"; height: "126"; }
+ ListElement{ longitude: "69"; latitude: "1"; height: "122"; }
+ ListElement{ longitude: "69"; latitude: "2"; height: "125"; }
+ ListElement{ longitude: "69"; latitude: "3"; height: "124"; }
+ ListElement{ longitude: "69"; latitude: "4"; height: "120"; }
+ ListElement{ longitude: "69"; latitude: "5"; height: "118"; }
+ ListElement{ longitude: "69"; latitude: "6"; height: "118"; }
+ ListElement{ longitude: "69"; latitude: "7"; height: "116"; }
+ ListElement{ longitude: "69"; latitude: "8"; height: "113"; }
+ ListElement{ longitude: "69"; latitude: "9"; height: "109"; }
+ ListElement{ longitude: "69"; latitude: "10"; height: "107"; }
+ ListElement{ longitude: "69"; latitude: "11"; height: "109"; }
+ ListElement{ longitude: "69"; latitude: "12"; height: "108"; }
+ ListElement{ longitude: "69"; latitude: "13"; height: "108"; }
+ ListElement{ longitude: "69"; latitude: "14"; height: "109"; }
+ ListElement{ longitude: "69"; latitude: "15"; height: "109"; }
+ ListElement{ longitude: "69"; latitude: "16"; height: "109"; }
+ ListElement{ longitude: "69"; latitude: "17"; height: "108"; }
+ ListElement{ longitude: "69"; latitude: "18"; height: "109"; }
+ ListElement{ longitude: "69"; latitude: "19"; height: "112"; }
+ ListElement{ longitude: "69"; latitude: "20"; height: "114"; }
+ ListElement{ longitude: "69"; latitude: "21"; height: "114"; }
+ ListElement{ longitude: "69"; latitude: "22"; height: "111"; }
+ ListElement{ longitude: "69"; latitude: "23"; height: "110"; }
+ ListElement{ longitude: "69"; latitude: "24"; height: "112"; }
+ ListElement{ longitude: "69"; latitude: "25"; height: "109"; }
+ ListElement{ longitude: "69"; latitude: "26"; height: "109"; }
+ ListElement{ longitude: "69"; latitude: "27"; height: "107"; }
+ ListElement{ longitude: "69"; latitude: "28"; height: "105"; }
+ ListElement{ longitude: "69"; latitude: "29"; height: "101"; }
+ ListElement{ longitude: "69"; latitude: "30"; height: "100"; }
+ ListElement{ longitude: "69"; latitude: "31"; height: "98"; }
+ ListElement{ longitude: "69"; latitude: "32"; height: "99"; }
+ ListElement{ longitude: "69"; latitude: "33"; height: "101"; }
+ ListElement{ longitude: "69"; latitude: "34"; height: "104"; }
+ ListElement{ longitude: "69"; latitude: "35"; height: "105"; }
+ ListElement{ longitude: "69"; latitude: "36"; height: "109"; }
+ ListElement{ longitude: "69"; latitude: "37"; height: "112"; }
+ ListElement{ longitude: "69"; latitude: "38"; height: "116"; }
+ ListElement{ longitude: "69"; latitude: "39"; height: "121"; }
+ ListElement{ longitude: "69"; latitude: "40"; height: "125"; }
+ ListElement{ longitude: "69"; latitude: "41"; height: "130"; }
+ ListElement{ longitude: "69"; latitude: "42"; height: "131"; }
+ ListElement{ longitude: "69"; latitude: "43"; height: "130"; }
+ ListElement{ longitude: "69"; latitude: "44"; height: "131"; }
+ ListElement{ longitude: "69"; latitude: "45"; height: "127"; }
+ ListElement{ longitude: "69"; latitude: "46"; height: "128"; }
+ ListElement{ longitude: "69"; latitude: "47"; height: "126"; }
+ ListElement{ longitude: "69"; latitude: "48"; height: "126"; }
+ ListElement{ longitude: "69"; latitude: "49"; height: "129"; }
+ ListElement{ longitude: "69"; latitude: "50"; height: "130"; }
+ ListElement{ longitude: "69"; latitude: "51"; height: "131"; }
+ ListElement{ longitude: "69"; latitude: "52"; height: "130"; }
+ ListElement{ longitude: "69"; latitude: "53"; height: "126"; }
+ ListElement{ longitude: "69"; latitude: "54"; height: "119"; }
+ ListElement{ longitude: "69"; latitude: "55"; height: "126"; }
+ ListElement{ longitude: "69"; latitude: "56"; height: "123"; }
+ ListElement{ longitude: "69"; latitude: "57"; height: "124"; }
+ ListElement{ longitude: "69"; latitude: "58"; height: "122"; }
+ ListElement{ longitude: "69"; latitude: "59"; height: "122"; }
+ ListElement{ longitude: "69"; latitude: "60"; height: "123"; }
+ ListElement{ longitude: "69"; latitude: "61"; height: "121"; }
+ ListElement{ longitude: "69"; latitude: "62"; height: "119"; }
+ ListElement{ longitude: "69"; latitude: "63"; height: "120"; }
+ ListElement{ longitude: "69"; latitude: "64"; height: "118"; }
+ ListElement{ longitude: "69"; latitude: "65"; height: "113"; }
+ ListElement{ longitude: "69"; latitude: "66"; height: "112"; }
+ ListElement{ longitude: "69"; latitude: "67"; height: "116"; }
+ ListElement{ longitude: "69"; latitude: "68"; height: "121"; }
+ ListElement{ longitude: "69"; latitude: "69"; height: "121"; }
+ ListElement{ longitude: "69"; latitude: "70"; height: "123"; }
+ ListElement{ longitude: "69"; latitude: "71"; height: "120"; }
+ ListElement{ longitude: "69"; latitude: "72"; height: "121"; }
+ ListElement{ longitude: "69"; latitude: "73"; height: "118"; }
+ ListElement{ longitude: "69"; latitude: "74"; height: "119"; }
+ ListElement{ longitude: "69"; latitude: "75"; height: "124"; }
+ ListElement{ longitude: "69"; latitude: "76"; height: "127"; }
+ ListElement{ longitude: "69"; latitude: "77"; height: "129"; }
+ ListElement{ longitude: "69"; latitude: "78"; height: "131"; }
+ ListElement{ longitude: "69"; latitude: "79"; height: "133"; }
+ ListElement{ longitude: "69"; latitude: "80"; height: "127"; }
+ ListElement{ longitude: "69"; latitude: "81"; height: "127"; }
+ ListElement{ longitude: "69"; latitude: "82"; height: "126"; }
+ ListElement{ longitude: "69"; latitude: "83"; height: "125"; }
+ ListElement{ longitude: "69"; latitude: "84"; height: "125"; }
+ ListElement{ longitude: "69"; latitude: "85"; height: "127"; }
+ ListElement{ longitude: "69"; latitude: "86"; height: "127"; }
+ ListElement{ longitude: "69"; latitude: "87"; height: "125"; }
+ ListElement{ longitude: "69"; latitude: "88"; height: "120"; }
+ ListElement{ longitude: "69"; latitude: "89"; height: "115"; }
+ ListElement{ longitude: "69"; latitude: "90"; height: "115"; }
+ ListElement{ longitude: "69"; latitude: "91"; height: "114"; }
+ ListElement{ longitude: "69"; latitude: "92"; height: "118"; }
+ ListElement{ longitude: "69"; latitude: "93"; height: "122"; }
+ ListElement{ longitude: "69"; latitude: "94"; height: "125"; }
+ ListElement{ longitude: "69"; latitude: "95"; height: "130"; }
+ ListElement{ longitude: "69"; latitude: "96"; height: "133"; }
+ ListElement{ longitude: "69"; latitude: "97"; height: "136"; }
+ ListElement{ longitude: "69"; latitude: "98"; height: "128"; }
+ ListElement{ longitude: "69"; latitude: "99"; height: "125"; }
+ ListElement{ longitude: "70"; latitude: "0"; height: "125"; }
+ ListElement{ longitude: "70"; latitude: "1"; height: "124"; }
+ ListElement{ longitude: "70"; latitude: "2"; height: "125"; }
+ ListElement{ longitude: "70"; latitude: "3"; height: "123"; }
+ ListElement{ longitude: "70"; latitude: "4"; height: "120"; }
+ ListElement{ longitude: "70"; latitude: "5"; height: "116"; }
+ ListElement{ longitude: "70"; latitude: "6"; height: "115"; }
+ ListElement{ longitude: "70"; latitude: "7"; height: "110"; }
+ ListElement{ longitude: "70"; latitude: "8"; height: "112"; }
+ ListElement{ longitude: "70"; latitude: "9"; height: "108"; }
+ ListElement{ longitude: "70"; latitude: "10"; height: "106"; }
+ ListElement{ longitude: "70"; latitude: "11"; height: "105"; }
+ ListElement{ longitude: "70"; latitude: "12"; height: "105"; }
+ ListElement{ longitude: "70"; latitude: "13"; height: "105"; }
+ ListElement{ longitude: "70"; latitude: "14"; height: "108"; }
+ ListElement{ longitude: "70"; latitude: "15"; height: "108"; }
+ ListElement{ longitude: "70"; latitude: "16"; height: "107"; }
+ ListElement{ longitude: "70"; latitude: "17"; height: "110"; }
+ ListElement{ longitude: "70"; latitude: "18"; height: "109"; }
+ ListElement{ longitude: "70"; latitude: "19"; height: "110"; }
+ ListElement{ longitude: "70"; latitude: "20"; height: "112"; }
+ ListElement{ longitude: "70"; latitude: "21"; height: "110"; }
+ ListElement{ longitude: "70"; latitude: "22"; height: "110"; }
+ ListElement{ longitude: "70"; latitude: "23"; height: "109"; }
+ ListElement{ longitude: "70"; latitude: "24"; height: "109"; }
+ ListElement{ longitude: "70"; latitude: "25"; height: "109"; }
+ ListElement{ longitude: "70"; latitude: "26"; height: "107"; }
+ ListElement{ longitude: "70"; latitude: "27"; height: "106"; }
+ ListElement{ longitude: "70"; latitude: "28"; height: "104"; }
+ ListElement{ longitude: "70"; latitude: "29"; height: "101"; }
+ ListElement{ longitude: "70"; latitude: "30"; height: "100"; }
+ ListElement{ longitude: "70"; latitude: "31"; height: "97"; }
+ ListElement{ longitude: "70"; latitude: "32"; height: "98"; }
+ ListElement{ longitude: "70"; latitude: "33"; height: "99"; }
+ ListElement{ longitude: "70"; latitude: "34"; height: "101"; }
+ ListElement{ longitude: "70"; latitude: "35"; height: "104"; }
+ ListElement{ longitude: "70"; latitude: "36"; height: "106"; }
+ ListElement{ longitude: "70"; latitude: "37"; height: "108"; }
+ ListElement{ longitude: "70"; latitude: "38"; height: "116"; }
+ ListElement{ longitude: "70"; latitude: "39"; height: "119"; }
+ ListElement{ longitude: "70"; latitude: "40"; height: "127"; }
+ ListElement{ longitude: "70"; latitude: "41"; height: "131"; }
+ ListElement{ longitude: "70"; latitude: "42"; height: "130"; }
+ ListElement{ longitude: "70"; latitude: "43"; height: "129"; }
+ ListElement{ longitude: "70"; latitude: "44"; height: "126"; }
+ ListElement{ longitude: "70"; latitude: "45"; height: "125"; }
+ ListElement{ longitude: "70"; latitude: "46"; height: "124"; }
+ ListElement{ longitude: "70"; latitude: "47"; height: "124"; }
+ ListElement{ longitude: "70"; latitude: "48"; height: "123"; }
+ ListElement{ longitude: "70"; latitude: "49"; height: "127"; }
+ ListElement{ longitude: "70"; latitude: "50"; height: "129"; }
+ ListElement{ longitude: "70"; latitude: "51"; height: "132"; }
+ ListElement{ longitude: "70"; latitude: "52"; height: "133"; }
+ ListElement{ longitude: "70"; latitude: "53"; height: "130"; }
+ ListElement{ longitude: "70"; latitude: "54"; height: "129"; }
+ ListElement{ longitude: "70"; latitude: "55"; height: "128"; }
+ ListElement{ longitude: "70"; latitude: "56"; height: "126"; }
+ ListElement{ longitude: "70"; latitude: "57"; height: "127"; }
+ ListElement{ longitude: "70"; latitude: "58"; height: "127"; }
+ ListElement{ longitude: "70"; latitude: "59"; height: "128"; }
+ ListElement{ longitude: "70"; latitude: "60"; height: "126"; }
+ ListElement{ longitude: "70"; latitude: "61"; height: "125"; }
+ ListElement{ longitude: "70"; latitude: "62"; height: "123"; }
+ ListElement{ longitude: "70"; latitude: "63"; height: "122"; }
+ ListElement{ longitude: "70"; latitude: "64"; height: "122"; }
+ ListElement{ longitude: "70"; latitude: "65"; height: "115"; }
+ ListElement{ longitude: "70"; latitude: "66"; height: "110"; }
+ ListElement{ longitude: "70"; latitude: "67"; height: "117"; }
+ ListElement{ longitude: "70"; latitude: "68"; height: "126"; }
+ ListElement{ longitude: "70"; latitude: "69"; height: "108"; }
+ ListElement{ longitude: "70"; latitude: "70"; height: "102"; }
+ ListElement{ longitude: "70"; latitude: "71"; height: "98"; }
+ ListElement{ longitude: "70"; latitude: "72"; height: "98"; }
+ ListElement{ longitude: "70"; latitude: "73"; height: "115"; }
+ ListElement{ longitude: "70"; latitude: "74"; height: "120"; }
+ ListElement{ longitude: "70"; latitude: "75"; height: "121"; }
+ ListElement{ longitude: "70"; latitude: "76"; height: "124"; }
+ ListElement{ longitude: "70"; latitude: "77"; height: "127"; }
+ ListElement{ longitude: "70"; latitude: "78"; height: "121"; }
+ ListElement{ longitude: "70"; latitude: "79"; height: "135"; }
+ ListElement{ longitude: "70"; latitude: "80"; height: "131"; }
+ ListElement{ longitude: "70"; latitude: "81"; height: "134"; }
+ ListElement{ longitude: "70"; latitude: "82"; height: "129"; }
+ ListElement{ longitude: "70"; latitude: "83"; height: "128"; }
+ ListElement{ longitude: "70"; latitude: "84"; height: "129"; }
+ ListElement{ longitude: "70"; latitude: "85"; height: "129"; }
+ ListElement{ longitude: "70"; latitude: "86"; height: "129"; }
+ ListElement{ longitude: "70"; latitude: "87"; height: "127"; }
+ ListElement{ longitude: "70"; latitude: "88"; height: "124"; }
+ ListElement{ longitude: "70"; latitude: "89"; height: "119"; }
+ ListElement{ longitude: "70"; latitude: "90"; height: "117"; }
+ ListElement{ longitude: "70"; latitude: "91"; height: "117"; }
+ ListElement{ longitude: "70"; latitude: "92"; height: "118"; }
+ ListElement{ longitude: "70"; latitude: "93"; height: "121"; }
+ ListElement{ longitude: "70"; latitude: "94"; height: "124"; }
+ ListElement{ longitude: "70"; latitude: "95"; height: "129"; }
+ ListElement{ longitude: "70"; latitude: "96"; height: "132"; }
+ ListElement{ longitude: "70"; latitude: "97"; height: "138"; }
+ ListElement{ longitude: "70"; latitude: "98"; height: "134"; }
+ ListElement{ longitude: "70"; latitude: "99"; height: "126"; }
+ ListElement{ longitude: "71"; latitude: "0"; height: "126"; }
+ ListElement{ longitude: "71"; latitude: "1"; height: "126"; }
+ ListElement{ longitude: "71"; latitude: "2"; height: "127"; }
+ ListElement{ longitude: "71"; latitude: "3"; height: "123"; }
+ ListElement{ longitude: "71"; latitude: "4"; height: "116"; }
+ ListElement{ longitude: "71"; latitude: "5"; height: "114"; }
+ ListElement{ longitude: "71"; latitude: "6"; height: "110"; }
+ ListElement{ longitude: "71"; latitude: "7"; height: "110"; }
+ ListElement{ longitude: "71"; latitude: "8"; height: "111"; }
+ ListElement{ longitude: "71"; latitude: "9"; height: "108"; }
+ ListElement{ longitude: "71"; latitude: "10"; height: "106"; }
+ ListElement{ longitude: "71"; latitude: "11"; height: "104"; }
+ ListElement{ longitude: "71"; latitude: "12"; height: "104"; }
+ ListElement{ longitude: "71"; latitude: "13"; height: "104"; }
+ ListElement{ longitude: "71"; latitude: "14"; height: "104"; }
+ ListElement{ longitude: "71"; latitude: "15"; height: "104"; }
+ ListElement{ longitude: "71"; latitude: "16"; height: "107"; }
+ ListElement{ longitude: "71"; latitude: "17"; height: "108"; }
+ ListElement{ longitude: "71"; latitude: "18"; height: "110"; }
+ ListElement{ longitude: "71"; latitude: "19"; height: "111"; }
+ ListElement{ longitude: "71"; latitude: "20"; height: "111"; }
+ ListElement{ longitude: "71"; latitude: "21"; height: "110"; }
+ ListElement{ longitude: "71"; latitude: "22"; height: "111"; }
+ ListElement{ longitude: "71"; latitude: "23"; height: "111"; }
+ ListElement{ longitude: "71"; latitude: "24"; height: "111"; }
+ ListElement{ longitude: "71"; latitude: "25"; height: "111"; }
+ ListElement{ longitude: "71"; latitude: "26"; height: "112"; }
+ ListElement{ longitude: "71"; latitude: "27"; height: "109"; }
+ ListElement{ longitude: "71"; latitude: "28"; height: "105"; }
+ ListElement{ longitude: "71"; latitude: "29"; height: "101"; }
+ ListElement{ longitude: "71"; latitude: "30"; height: "102"; }
+ ListElement{ longitude: "71"; latitude: "31"; height: "102"; }
+ ListElement{ longitude: "71"; latitude: "32"; height: "102"; }
+ ListElement{ longitude: "71"; latitude: "33"; height: "103"; }
+ ListElement{ longitude: "71"; latitude: "34"; height: "106"; }
+ ListElement{ longitude: "71"; latitude: "35"; height: "105"; }
+ ListElement{ longitude: "71"; latitude: "36"; height: "108"; }
+ ListElement{ longitude: "71"; latitude: "37"; height: "109"; }
+ ListElement{ longitude: "71"; latitude: "38"; height: "114"; }
+ ListElement{ longitude: "71"; latitude: "39"; height: "119"; }
+ ListElement{ longitude: "71"; latitude: "40"; height: "124"; }
+ ListElement{ longitude: "71"; latitude: "41"; height: "130"; }
+ ListElement{ longitude: "71"; latitude: "42"; height: "130"; }
+ ListElement{ longitude: "71"; latitude: "43"; height: "127"; }
+ ListElement{ longitude: "71"; latitude: "44"; height: "126"; }
+ ListElement{ longitude: "71"; latitude: "45"; height: "126"; }
+ ListElement{ longitude: "71"; latitude: "46"; height: "123"; }
+ ListElement{ longitude: "71"; latitude: "47"; height: "121"; }
+ ListElement{ longitude: "71"; latitude: "48"; height: "124"; }
+ ListElement{ longitude: "71"; latitude: "49"; height: "127"; }
+ ListElement{ longitude: "71"; latitude: "50"; height: "131"; }
+ ListElement{ longitude: "71"; latitude: "51"; height: "131"; }
+ ListElement{ longitude: "71"; latitude: "52"; height: "131"; }
+ ListElement{ longitude: "71"; latitude: "53"; height: "130"; }
+ ListElement{ longitude: "71"; latitude: "54"; height: "131"; }
+ ListElement{ longitude: "71"; latitude: "55"; height: "131"; }
+ ListElement{ longitude: "71"; latitude: "56"; height: "130"; }
+ ListElement{ longitude: "71"; latitude: "57"; height: "131"; }
+ ListElement{ longitude: "71"; latitude: "58"; height: "128"; }
+ ListElement{ longitude: "71"; latitude: "59"; height: "129"; }
+ ListElement{ longitude: "71"; latitude: "60"; height: "125"; }
+ ListElement{ longitude: "71"; latitude: "61"; height: "127"; }
+ ListElement{ longitude: "71"; latitude: "62"; height: "125"; }
+ ListElement{ longitude: "71"; latitude: "63"; height: "121"; }
+ ListElement{ longitude: "71"; latitude: "64"; height: "123"; }
+ ListElement{ longitude: "71"; latitude: "65"; height: "119"; }
+ ListElement{ longitude: "71"; latitude: "66"; height: "118"; }
+ ListElement{ longitude: "71"; latitude: "67"; height: "121"; }
+ ListElement{ longitude: "71"; latitude: "68"; height: "118"; }
+ ListElement{ longitude: "71"; latitude: "69"; height: "93"; }
+ ListElement{ longitude: "71"; latitude: "70"; height: "94"; }
+ ListElement{ longitude: "71"; latitude: "71"; height: "95"; }
+ ListElement{ longitude: "71"; latitude: "72"; height: "92"; }
+ ListElement{ longitude: "71"; latitude: "73"; height: "100"; }
+ ListElement{ longitude: "71"; latitude: "74"; height: "120"; }
+ ListElement{ longitude: "71"; latitude: "75"; height: "120"; }
+ ListElement{ longitude: "71"; latitude: "76"; height: "126"; }
+ ListElement{ longitude: "71"; latitude: "77"; height: "130"; }
+ ListElement{ longitude: "71"; latitude: "78"; height: "131"; }
+ ListElement{ longitude: "71"; latitude: "79"; height: "135"; }
+ ListElement{ longitude: "71"; latitude: "80"; height: "138"; }
+ ListElement{ longitude: "71"; latitude: "81"; height: "134"; }
+ ListElement{ longitude: "71"; latitude: "82"; height: "135"; }
+ ListElement{ longitude: "71"; latitude: "83"; height: "133"; }
+ ListElement{ longitude: "71"; latitude: "84"; height: "130"; }
+ ListElement{ longitude: "71"; latitude: "85"; height: "131"; }
+ ListElement{ longitude: "71"; latitude: "86"; height: "131"; }
+ ListElement{ longitude: "71"; latitude: "87"; height: "131"; }
+ ListElement{ longitude: "71"; latitude: "88"; height: "127"; }
+ ListElement{ longitude: "71"; latitude: "89"; height: "124"; }
+ ListElement{ longitude: "71"; latitude: "90"; height: "120"; }
+ ListElement{ longitude: "71"; latitude: "91"; height: "119"; }
+ ListElement{ longitude: "71"; latitude: "92"; height: "119"; }
+ ListElement{ longitude: "71"; latitude: "93"; height: "122"; }
+ ListElement{ longitude: "71"; latitude: "94"; height: "125"; }
+ ListElement{ longitude: "71"; latitude: "95"; height: "126"; }
+ ListElement{ longitude: "71"; latitude: "96"; height: "132"; }
+ ListElement{ longitude: "71"; latitude: "97"; height: "138"; }
+ ListElement{ longitude: "71"; latitude: "98"; height: "136"; }
+ ListElement{ longitude: "71"; latitude: "99"; height: "126"; }
+ ListElement{ longitude: "72"; latitude: "0"; height: "127"; }
+ ListElement{ longitude: "72"; latitude: "1"; height: "127"; }
+ ListElement{ longitude: "72"; latitude: "2"; height: "124"; }
+ ListElement{ longitude: "72"; latitude: "3"; height: "124"; }
+ ListElement{ longitude: "72"; latitude: "4"; height: "120"; }
+ ListElement{ longitude: "72"; latitude: "5"; height: "116"; }
+ ListElement{ longitude: "72"; latitude: "6"; height: "111"; }
+ ListElement{ longitude: "72"; latitude: "7"; height: "108"; }
+ ListElement{ longitude: "72"; latitude: "8"; height: "111"; }
+ ListElement{ longitude: "72"; latitude: "9"; height: "108"; }
+ ListElement{ longitude: "72"; latitude: "10"; height: "108"; }
+ ListElement{ longitude: "72"; latitude: "11"; height: "104"; }
+ ListElement{ longitude: "72"; latitude: "12"; height: "103"; }
+ ListElement{ longitude: "72"; latitude: "13"; height: "105"; }
+ ListElement{ longitude: "72"; latitude: "14"; height: "105"; }
+ ListElement{ longitude: "72"; latitude: "15"; height: "105"; }
+ ListElement{ longitude: "72"; latitude: "16"; height: "102"; }
+ ListElement{ longitude: "72"; latitude: "17"; height: "105"; }
+ ListElement{ longitude: "72"; latitude: "18"; height: "107"; }
+ ListElement{ longitude: "72"; latitude: "19"; height: "108"; }
+ ListElement{ longitude: "72"; latitude: "20"; height: "111"; }
+ ListElement{ longitude: "72"; latitude: "21"; height: "111"; }
+ ListElement{ longitude: "72"; latitude: "22"; height: "111"; }
+ ListElement{ longitude: "72"; latitude: "23"; height: "110"; }
+ ListElement{ longitude: "72"; latitude: "24"; height: "110"; }
+ ListElement{ longitude: "72"; latitude: "25"; height: "110"; }
+ ListElement{ longitude: "72"; latitude: "26"; height: "111"; }
+ ListElement{ longitude: "72"; latitude: "27"; height: "110"; }
+ ListElement{ longitude: "72"; latitude: "28"; height: "109"; }
+ ListElement{ longitude: "72"; latitude: "29"; height: "110"; }
+ ListElement{ longitude: "72"; latitude: "30"; height: "107"; }
+ ListElement{ longitude: "72"; latitude: "31"; height: "105"; }
+ ListElement{ longitude: "72"; latitude: "32"; height: "107"; }
+ ListElement{ longitude: "72"; latitude: "33"; height: "108"; }
+ ListElement{ longitude: "72"; latitude: "34"; height: "110"; }
+ ListElement{ longitude: "72"; latitude: "35"; height: "110"; }
+ ListElement{ longitude: "72"; latitude: "36"; height: "108"; }
+ ListElement{ longitude: "72"; latitude: "37"; height: "107"; }
+ ListElement{ longitude: "72"; latitude: "38"; height: "110"; }
+ ListElement{ longitude: "72"; latitude: "39"; height: "115"; }
+ ListElement{ longitude: "72"; latitude: "40"; height: "122"; }
+ ListElement{ longitude: "72"; latitude: "41"; height: "127"; }
+ ListElement{ longitude: "72"; latitude: "42"; height: "131"; }
+ ListElement{ longitude: "72"; latitude: "43"; height: "132"; }
+ ListElement{ longitude: "72"; latitude: "44"; height: "127"; }
+ ListElement{ longitude: "72"; latitude: "45"; height: "125"; }
+ ListElement{ longitude: "72"; latitude: "46"; height: "122"; }
+ ListElement{ longitude: "72"; latitude: "47"; height: "123"; }
+ ListElement{ longitude: "72"; latitude: "48"; height: "125"; }
+ ListElement{ longitude: "72"; latitude: "49"; height: "128"; }
+ ListElement{ longitude: "72"; latitude: "50"; height: "132"; }
+ ListElement{ longitude: "72"; latitude: "51"; height: "134"; }
+ ListElement{ longitude: "72"; latitude: "52"; height: "134"; }
+ ListElement{ longitude: "72"; latitude: "53"; height: "133"; }
+ ListElement{ longitude: "72"; latitude: "54"; height: "133"; }
+ ListElement{ longitude: "72"; latitude: "55"; height: "133"; }
+ ListElement{ longitude: "72"; latitude: "56"; height: "136"; }
+ ListElement{ longitude: "72"; latitude: "57"; height: "127"; }
+ ListElement{ longitude: "72"; latitude: "58"; height: "115"; }
+ ListElement{ longitude: "72"; latitude: "59"; height: "129"; }
+ ListElement{ longitude: "72"; latitude: "60"; height: "128"; }
+ ListElement{ longitude: "72"; latitude: "61"; height: "128"; }
+ ListElement{ longitude: "72"; latitude: "62"; height: "126"; }
+ ListElement{ longitude: "72"; latitude: "63"; height: "122"; }
+ ListElement{ longitude: "72"; latitude: "64"; height: "121"; }
+ ListElement{ longitude: "72"; latitude: "65"; height: "116"; }
+ ListElement{ longitude: "72"; latitude: "66"; height: "117"; }
+ ListElement{ longitude: "72"; latitude: "67"; height: "121"; }
+ ListElement{ longitude: "72"; latitude: "68"; height: "109"; }
+ ListElement{ longitude: "72"; latitude: "69"; height: "101"; }
+ ListElement{ longitude: "72"; latitude: "70"; height: "106"; }
+ ListElement{ longitude: "72"; latitude: "71"; height: "100"; }
+ ListElement{ longitude: "72"; latitude: "72"; height: "91"; }
+ ListElement{ longitude: "72"; latitude: "73"; height: "101"; }
+ ListElement{ longitude: "72"; latitude: "74"; height: "119"; }
+ ListElement{ longitude: "72"; latitude: "75"; height: "121"; }
+ ListElement{ longitude: "72"; latitude: "76"; height: "129"; }
+ ListElement{ longitude: "72"; latitude: "77"; height: "131"; }
+ ListElement{ longitude: "72"; latitude: "78"; height: "135"; }
+ ListElement{ longitude: "72"; latitude: "79"; height: "138"; }
+ ListElement{ longitude: "72"; latitude: "80"; height: "141"; }
+ ListElement{ longitude: "72"; latitude: "81"; height: "139"; }
+ ListElement{ longitude: "72"; latitude: "82"; height: "138"; }
+ ListElement{ longitude: "72"; latitude: "83"; height: "136"; }
+ ListElement{ longitude: "72"; latitude: "84"; height: "134"; }
+ ListElement{ longitude: "72"; latitude: "85"; height: "133"; }
+ ListElement{ longitude: "72"; latitude: "86"; height: "132"; }
+ ListElement{ longitude: "72"; latitude: "87"; height: "131"; }
+ ListElement{ longitude: "72"; latitude: "88"; height: "129"; }
+ ListElement{ longitude: "72"; latitude: "89"; height: "127"; }
+ ListElement{ longitude: "72"; latitude: "90"; height: "122"; }
+ ListElement{ longitude: "72"; latitude: "91"; height: "122"; }
+ ListElement{ longitude: "72"; latitude: "92"; height: "121"; }
+ ListElement{ longitude: "72"; latitude: "93"; height: "120"; }
+ ListElement{ longitude: "72"; latitude: "94"; height: "123"; }
+ ListElement{ longitude: "72"; latitude: "95"; height: "126"; }
+ ListElement{ longitude: "72"; latitude: "96"; height: "130"; }
+ ListElement{ longitude: "72"; latitude: "97"; height: "137"; }
+ ListElement{ longitude: "72"; latitude: "98"; height: "138"; }
+ ListElement{ longitude: "72"; latitude: "99"; height: "125"; }
+ ListElement{ longitude: "73"; latitude: "0"; height: "129"; }
+ ListElement{ longitude: "73"; latitude: "1"; height: "128"; }
+ ListElement{ longitude: "73"; latitude: "2"; height: "127"; }
+ ListElement{ longitude: "73"; latitude: "3"; height: "127"; }
+ ListElement{ longitude: "73"; latitude: "4"; height: "120"; }
+ ListElement{ longitude: "73"; latitude: "5"; height: "116"; }
+ ListElement{ longitude: "73"; latitude: "6"; height: "110"; }
+ ListElement{ longitude: "73"; latitude: "7"; height: "110"; }
+ ListElement{ longitude: "73"; latitude: "8"; height: "111"; }
+ ListElement{ longitude: "73"; latitude: "9"; height: "108"; }
+ ListElement{ longitude: "73"; latitude: "10"; height: "108"; }
+ ListElement{ longitude: "73"; latitude: "11"; height: "106"; }
+ ListElement{ longitude: "73"; latitude: "12"; height: "105"; }
+ ListElement{ longitude: "73"; latitude: "13"; height: "105"; }
+ ListElement{ longitude: "73"; latitude: "14"; height: "103"; }
+ ListElement{ longitude: "73"; latitude: "15"; height: "103"; }
+ ListElement{ longitude: "73"; latitude: "16"; height: "101"; }
+ ListElement{ longitude: "73"; latitude: "17"; height: "104"; }
+ ListElement{ longitude: "73"; latitude: "18"; height: "106"; }
+ ListElement{ longitude: "73"; latitude: "19"; height: "109"; }
+ ListElement{ longitude: "73"; latitude: "20"; height: "111"; }
+ ListElement{ longitude: "73"; latitude: "21"; height: "111"; }
+ ListElement{ longitude: "73"; latitude: "22"; height: "110"; }
+ ListElement{ longitude: "73"; latitude: "23"; height: "110"; }
+ ListElement{ longitude: "73"; latitude: "24"; height: "112"; }
+ ListElement{ longitude: "73"; latitude: "25"; height: "112"; }
+ ListElement{ longitude: "73"; latitude: "26"; height: "112"; }
+ ListElement{ longitude: "73"; latitude: "27"; height: "108"; }
+ ListElement{ longitude: "73"; latitude: "28"; height: "113"; }
+ ListElement{ longitude: "73"; latitude: "29"; height: "111"; }
+ ListElement{ longitude: "73"; latitude: "30"; height: "110"; }
+ ListElement{ longitude: "73"; latitude: "31"; height: "107"; }
+ ListElement{ longitude: "73"; latitude: "32"; height: "108"; }
+ ListElement{ longitude: "73"; latitude: "33"; height: "109"; }
+ ListElement{ longitude: "73"; latitude: "34"; height: "110"; }
+ ListElement{ longitude: "73"; latitude: "35"; height: "106"; }
+ ListElement{ longitude: "73"; latitude: "36"; height: "107"; }
+ ListElement{ longitude: "73"; latitude: "37"; height: "106"; }
+ ListElement{ longitude: "73"; latitude: "38"; height: "107"; }
+ ListElement{ longitude: "73"; latitude: "39"; height: "112"; }
+ ListElement{ longitude: "73"; latitude: "40"; height: "119"; }
+ ListElement{ longitude: "73"; latitude: "41"; height: "126"; }
+ ListElement{ longitude: "73"; latitude: "42"; height: "131"; }
+ ListElement{ longitude: "73"; latitude: "43"; height: "126"; }
+ ListElement{ longitude: "73"; latitude: "44"; height: "122"; }
+ ListElement{ longitude: "73"; latitude: "45"; height: "122"; }
+ ListElement{ longitude: "73"; latitude: "46"; height: "122"; }
+ ListElement{ longitude: "73"; latitude: "47"; height: "123"; }
+ ListElement{ longitude: "73"; latitude: "48"; height: "127"; }
+ ListElement{ longitude: "73"; latitude: "49"; height: "132"; }
+ ListElement{ longitude: "73"; latitude: "50"; height: "135"; }
+ ListElement{ longitude: "73"; latitude: "51"; height: "135"; }
+ ListElement{ longitude: "73"; latitude: "52"; height: "135"; }
+ ListElement{ longitude: "73"; latitude: "53"; height: "133"; }
+ ListElement{ longitude: "73"; latitude: "54"; height: "133"; }
+ ListElement{ longitude: "73"; latitude: "55"; height: "135"; }
+ ListElement{ longitude: "73"; latitude: "56"; height: "138"; }
+ ListElement{ longitude: "73"; latitude: "57"; height: "127"; }
+ ListElement{ longitude: "73"; latitude: "58"; height: "119"; }
+ ListElement{ longitude: "73"; latitude: "59"; height: "129"; }
+ ListElement{ longitude: "73"; latitude: "60"; height: "129"; }
+ ListElement{ longitude: "73"; latitude: "61"; height: "128"; }
+ ListElement{ longitude: "73"; latitude: "62"; height: "126"; }
+ ListElement{ longitude: "73"; latitude: "63"; height: "122"; }
+ ListElement{ longitude: "73"; latitude: "64"; height: "121"; }
+ ListElement{ longitude: "73"; latitude: "65"; height: "117"; }
+ ListElement{ longitude: "73"; latitude: "66"; height: "118"; }
+ ListElement{ longitude: "73"; latitude: "67"; height: "119"; }
+ ListElement{ longitude: "73"; latitude: "68"; height: "108"; }
+ ListElement{ longitude: "73"; latitude: "69"; height: "97"; }
+ ListElement{ longitude: "73"; latitude: "70"; height: "104"; }
+ ListElement{ longitude: "73"; latitude: "71"; height: "102"; }
+ ListElement{ longitude: "73"; latitude: "72"; height: "92"; }
+ ListElement{ longitude: "73"; latitude: "73"; height: "109"; }
+ ListElement{ longitude: "73"; latitude: "74"; height: "123"; }
+ ListElement{ longitude: "73"; latitude: "75"; height: "125"; }
+ ListElement{ longitude: "73"; latitude: "76"; height: "126"; }
+ ListElement{ longitude: "73"; latitude: "77"; height: "132"; }
+ ListElement{ longitude: "73"; latitude: "78"; height: "137"; }
+ ListElement{ longitude: "73"; latitude: "79"; height: "140"; }
+ ListElement{ longitude: "73"; latitude: "80"; height: "143"; }
+ ListElement{ longitude: "73"; latitude: "81"; height: "141"; }
+ ListElement{ longitude: "73"; latitude: "82"; height: "140"; }
+ ListElement{ longitude: "73"; latitude: "83"; height: "136"; }
+ ListElement{ longitude: "73"; latitude: "84"; height: "134"; }
+ ListElement{ longitude: "73"; latitude: "85"; height: "134"; }
+ ListElement{ longitude: "73"; latitude: "86"; height: "133"; }
+ ListElement{ longitude: "73"; latitude: "87"; height: "130"; }
+ ListElement{ longitude: "73"; latitude: "88"; height: "130"; }
+ ListElement{ longitude: "73"; latitude: "89"; height: "128"; }
+ ListElement{ longitude: "73"; latitude: "90"; height: "125"; }
+ ListElement{ longitude: "73"; latitude: "91"; height: "122"; }
+ ListElement{ longitude: "73"; latitude: "92"; height: "119"; }
+ ListElement{ longitude: "73"; latitude: "93"; height: "120"; }
+ ListElement{ longitude: "73"; latitude: "94"; height: "119"; }
+ ListElement{ longitude: "73"; latitude: "95"; height: "120"; }
+ ListElement{ longitude: "73"; latitude: "96"; height: "122"; }
+ ListElement{ longitude: "73"; latitude: "97"; height: "131"; }
+ ListElement{ longitude: "73"; latitude: "98"; height: "137"; }
+ ListElement{ longitude: "73"; latitude: "99"; height: "123"; }
+ ListElement{ longitude: "74"; latitude: "0"; height: "128"; }
+ ListElement{ longitude: "74"; latitude: "1"; height: "128"; }
+ ListElement{ longitude: "74"; latitude: "2"; height: "128"; }
+ ListElement{ longitude: "74"; latitude: "3"; height: "127"; }
+ ListElement{ longitude: "74"; latitude: "4"; height: "124"; }
+ ListElement{ longitude: "74"; latitude: "5"; height: "117"; }
+ ListElement{ longitude: "74"; latitude: "6"; height: "113"; }
+ ListElement{ longitude: "74"; latitude: "7"; height: "111"; }
+ ListElement{ longitude: "74"; latitude: "8"; height: "111"; }
+ ListElement{ longitude: "74"; latitude: "9"; height: "108"; }
+ ListElement{ longitude: "74"; latitude: "10"; height: "106"; }
+ ListElement{ longitude: "74"; latitude: "11"; height: "106"; }
+ ListElement{ longitude: "74"; latitude: "12"; height: "105"; }
+ ListElement{ longitude: "74"; latitude: "13"; height: "104"; }
+ ListElement{ longitude: "74"; latitude: "14"; height: "104"; }
+ ListElement{ longitude: "74"; latitude: "15"; height: "104"; }
+ ListElement{ longitude: "74"; latitude: "16"; height: "106"; }
+ ListElement{ longitude: "74"; latitude: "17"; height: "105"; }
+ ListElement{ longitude: "74"; latitude: "18"; height: "107"; }
+ ListElement{ longitude: "74"; latitude: "19"; height: "107"; }
+ ListElement{ longitude: "74"; latitude: "20"; height: "110"; }
+ ListElement{ longitude: "74"; latitude: "21"; height: "111"; }
+ ListElement{ longitude: "74"; latitude: "22"; height: "112"; }
+ ListElement{ longitude: "74"; latitude: "23"; height: "113"; }
+ ListElement{ longitude: "74"; latitude: "24"; height: "113"; }
+ ListElement{ longitude: "74"; latitude: "25"; height: "113"; }
+ ListElement{ longitude: "74"; latitude: "26"; height: "113"; }
+ ListElement{ longitude: "74"; latitude: "27"; height: "113"; }
+ ListElement{ longitude: "74"; latitude: "28"; height: "114"; }
+ ListElement{ longitude: "74"; latitude: "29"; height: "110"; }
+ ListElement{ longitude: "74"; latitude: "30"; height: "112"; }
+ ListElement{ longitude: "74"; latitude: "31"; height: "111"; }
+ ListElement{ longitude: "74"; latitude: "32"; height: "108"; }
+ ListElement{ longitude: "74"; latitude: "33"; height: "109"; }
+ ListElement{ longitude: "74"; latitude: "34"; height: "106"; }
+ ListElement{ longitude: "74"; latitude: "35"; height: "102"; }
+ ListElement{ longitude: "74"; latitude: "36"; height: "104"; }
+ ListElement{ longitude: "74"; latitude: "37"; height: "105"; }
+ ListElement{ longitude: "74"; latitude: "38"; height: "109"; }
+ ListElement{ longitude: "74"; latitude: "39"; height: "114"; }
+ ListElement{ longitude: "74"; latitude: "40"; height: "121"; }
+ ListElement{ longitude: "74"; latitude: "41"; height: "128"; }
+ ListElement{ longitude: "74"; latitude: "42"; height: "123"; }
+ ListElement{ longitude: "74"; latitude: "43"; height: "117"; }
+ ListElement{ longitude: "74"; latitude: "44"; height: "119"; }
+ ListElement{ longitude: "74"; latitude: "45"; height: "121"; }
+ ListElement{ longitude: "74"; latitude: "46"; height: "121"; }
+ ListElement{ longitude: "74"; latitude: "47"; height: "122"; }
+ ListElement{ longitude: "74"; latitude: "48"; height: "125"; }
+ ListElement{ longitude: "74"; latitude: "49"; height: "129"; }
+ ListElement{ longitude: "74"; latitude: "50"; height: "134"; }
+ ListElement{ longitude: "74"; latitude: "51"; height: "136"; }
+ ListElement{ longitude: "74"; latitude: "52"; height: "136"; }
+ ListElement{ longitude: "74"; latitude: "53"; height: "134"; }
+ ListElement{ longitude: "74"; latitude: "54"; height: "134"; }
+ ListElement{ longitude: "74"; latitude: "55"; height: "137"; }
+ ListElement{ longitude: "74"; latitude: "56"; height: "138"; }
+ ListElement{ longitude: "74"; latitude: "57"; height: "136"; }
+ ListElement{ longitude: "74"; latitude: "58"; height: "135"; }
+ ListElement{ longitude: "74"; latitude: "59"; height: "134"; }
+ ListElement{ longitude: "74"; latitude: "60"; height: "130"; }
+ ListElement{ longitude: "74"; latitude: "61"; height: "128"; }
+ ListElement{ longitude: "74"; latitude: "62"; height: "126"; }
+ ListElement{ longitude: "74"; latitude: "63"; height: "123"; }
+ ListElement{ longitude: "74"; latitude: "64"; height: "120"; }
+ ListElement{ longitude: "74"; latitude: "65"; height: "116"; }
+ ListElement{ longitude: "74"; latitude: "66"; height: "117"; }
+ ListElement{ longitude: "74"; latitude: "67"; height: "119"; }
+ ListElement{ longitude: "74"; latitude: "68"; height: "120"; }
+ ListElement{ longitude: "74"; latitude: "69"; height: "103"; }
+ ListElement{ longitude: "74"; latitude: "70"; height: "100"; }
+ ListElement{ longitude: "74"; latitude: "71"; height: "97"; }
+ ListElement{ longitude: "74"; latitude: "72"; height: "96"; }
+ ListElement{ longitude: "74"; latitude: "73"; height: "121"; }
+ ListElement{ longitude: "74"; latitude: "74"; height: "123"; }
+ ListElement{ longitude: "74"; latitude: "75"; height: "128"; }
+ ListElement{ longitude: "74"; latitude: "76"; height: "121"; }
+ ListElement{ longitude: "74"; latitude: "77"; height: "133"; }
+ ListElement{ longitude: "74"; latitude: "78"; height: "138"; }
+ ListElement{ longitude: "74"; latitude: "79"; height: "142"; }
+ ListElement{ longitude: "74"; latitude: "80"; height: "143"; }
+ ListElement{ longitude: "74"; latitude: "81"; height: "143"; }
+ ListElement{ longitude: "74"; latitude: "82"; height: "141"; }
+ ListElement{ longitude: "74"; latitude: "83"; height: "137"; }
+ ListElement{ longitude: "74"; latitude: "84"; height: "135"; }
+ ListElement{ longitude: "74"; latitude: "85"; height: "135"; }
+ ListElement{ longitude: "74"; latitude: "86"; height: "134"; }
+ ListElement{ longitude: "74"; latitude: "87"; height: "132"; }
+ ListElement{ longitude: "74"; latitude: "88"; height: "130"; }
+ ListElement{ longitude: "74"; latitude: "89"; height: "128"; }
+ ListElement{ longitude: "74"; latitude: "90"; height: "123"; }
+ ListElement{ longitude: "74"; latitude: "91"; height: "120"; }
+ ListElement{ longitude: "74"; latitude: "92"; height: "118"; }
+ ListElement{ longitude: "74"; latitude: "93"; height: "117"; }
+ ListElement{ longitude: "74"; latitude: "94"; height: "116"; }
+ ListElement{ longitude: "74"; latitude: "95"; height: "116"; }
+ ListElement{ longitude: "74"; latitude: "96"; height: "119"; }
+ ListElement{ longitude: "74"; latitude: "97"; height: "125"; }
+ ListElement{ longitude: "74"; latitude: "98"; height: "131"; }
+ ListElement{ longitude: "74"; latitude: "99"; height: "119"; }
+ ListElement{ longitude: "75"; latitude: "0"; height: "128"; }
+ ListElement{ longitude: "75"; latitude: "1"; height: "128"; }
+ ListElement{ longitude: "75"; latitude: "2"; height: "128"; }
+ ListElement{ longitude: "75"; latitude: "3"; height: "128"; }
+ ListElement{ longitude: "75"; latitude: "4"; height: "126"; }
+ ListElement{ longitude: "75"; latitude: "5"; height: "120"; }
+ ListElement{ longitude: "75"; latitude: "6"; height: "116"; }
+ ListElement{ longitude: "75"; latitude: "7"; height: "113"; }
+ ListElement{ longitude: "75"; latitude: "8"; height: "110"; }
+ ListElement{ longitude: "75"; latitude: "9"; height: "108"; }
+ ListElement{ longitude: "75"; latitude: "10"; height: "107"; }
+ ListElement{ longitude: "75"; latitude: "11"; height: "105"; }
+ ListElement{ longitude: "75"; latitude: "12"; height: "102"; }
+ ListElement{ longitude: "75"; latitude: "13"; height: "101"; }
+ ListElement{ longitude: "75"; latitude: "14"; height: "101"; }
+ ListElement{ longitude: "75"; latitude: "15"; height: "101"; }
+ ListElement{ longitude: "75"; latitude: "16"; height: "103"; }
+ ListElement{ longitude: "75"; latitude: "17"; height: "102"; }
+ ListElement{ longitude: "75"; latitude: "18"; height: "106"; }
+ ListElement{ longitude: "75"; latitude: "19"; height: "108"; }
+ ListElement{ longitude: "75"; latitude: "20"; height: "110"; }
+ ListElement{ longitude: "75"; latitude: "21"; height: "111"; }
+ ListElement{ longitude: "75"; latitude: "22"; height: "112"; }
+ ListElement{ longitude: "75"; latitude: "23"; height: "113"; }
+ ListElement{ longitude: "75"; latitude: "24"; height: "113"; }
+ ListElement{ longitude: "75"; latitude: "25"; height: "113"; }
+ ListElement{ longitude: "75"; latitude: "26"; height: "113"; }
+ ListElement{ longitude: "75"; latitude: "27"; height: "113"; }
+ ListElement{ longitude: "75"; latitude: "28"; height: "114"; }
+ ListElement{ longitude: "75"; latitude: "29"; height: "111"; }
+ ListElement{ longitude: "75"; latitude: "30"; height: "108"; }
+ ListElement{ longitude: "75"; latitude: "31"; height: "108"; }
+ ListElement{ longitude: "75"; latitude: "32"; height: "105"; }
+ ListElement{ longitude: "75"; latitude: "33"; height: "104"; }
+ ListElement{ longitude: "75"; latitude: "34"; height: "101"; }
+ ListElement{ longitude: "75"; latitude: "35"; height: "102"; }
+ ListElement{ longitude: "75"; latitude: "36"; height: "102"; }
+ ListElement{ longitude: "75"; latitude: "37"; height: "104"; }
+ ListElement{ longitude: "75"; latitude: "38"; height: "110"; }
+ ListElement{ longitude: "75"; latitude: "39"; height: "115"; }
+ ListElement{ longitude: "75"; latitude: "40"; height: "123"; }
+ ListElement{ longitude: "75"; latitude: "41"; height: "126"; }
+ ListElement{ longitude: "75"; latitude: "42"; height: "118"; }
+ ListElement{ longitude: "75"; latitude: "43"; height: "119"; }
+ ListElement{ longitude: "75"; latitude: "44"; height: "122"; }
+ ListElement{ longitude: "75"; latitude: "45"; height: "124"; }
+ ListElement{ longitude: "75"; latitude: "46"; height: "122"; }
+ ListElement{ longitude: "75"; latitude: "47"; height: "121"; }
+ ListElement{ longitude: "75"; latitude: "48"; height: "126"; }
+ ListElement{ longitude: "75"; latitude: "49"; height: "130"; }
+ ListElement{ longitude: "75"; latitude: "50"; height: "134"; }
+ ListElement{ longitude: "75"; latitude: "51"; height: "138"; }
+ ListElement{ longitude: "75"; latitude: "52"; height: "139"; }
+ ListElement{ longitude: "75"; latitude: "53"; height: "137"; }
+ ListElement{ longitude: "75"; latitude: "54"; height: "137"; }
+ ListElement{ longitude: "75"; latitude: "55"; height: "137"; }
+ ListElement{ longitude: "75"; latitude: "56"; height: "137"; }
+ ListElement{ longitude: "75"; latitude: "57"; height: "136"; }
+ ListElement{ longitude: "75"; latitude: "58"; height: "137"; }
+ ListElement{ longitude: "75"; latitude: "59"; height: "133"; }
+ ListElement{ longitude: "75"; latitude: "60"; height: "130"; }
+ ListElement{ longitude: "75"; latitude: "61"; height: "128"; }
+ ListElement{ longitude: "75"; latitude: "62"; height: "125"; }
+ ListElement{ longitude: "75"; latitude: "63"; height: "120"; }
+ ListElement{ longitude: "75"; latitude: "64"; height: "117"; }
+ ListElement{ longitude: "75"; latitude: "65"; height: "114"; }
+ ListElement{ longitude: "75"; latitude: "66"; height: "113"; }
+ ListElement{ longitude: "75"; latitude: "67"; height: "115"; }
+ ListElement{ longitude: "75"; latitude: "68"; height: "119"; }
+ ListElement{ longitude: "75"; latitude: "69"; height: "121"; }
+ ListElement{ longitude: "75"; latitude: "70"; height: "119"; }
+ ListElement{ longitude: "75"; latitude: "71"; height: "110"; }
+ ListElement{ longitude: "75"; latitude: "72"; height: "122"; }
+ ListElement{ longitude: "75"; latitude: "73"; height: "126"; }
+ ListElement{ longitude: "75"; latitude: "74"; height: "127"; }
+ ListElement{ longitude: "75"; latitude: "75"; height: "128"; }
+ ListElement{ longitude: "75"; latitude: "76"; height: "127"; }
+ ListElement{ longitude: "75"; latitude: "77"; height: "135"; }
+ ListElement{ longitude: "75"; latitude: "78"; height: "140"; }
+ ListElement{ longitude: "75"; latitude: "79"; height: "144"; }
+ ListElement{ longitude: "75"; latitude: "80"; height: "146"; }
+ ListElement{ longitude: "75"; latitude: "81"; height: "147"; }
+ ListElement{ longitude: "75"; latitude: "82"; height: "140"; }
+ ListElement{ longitude: "75"; latitude: "83"; height: "141"; }
+ ListElement{ longitude: "75"; latitude: "84"; height: "137"; }
+ ListElement{ longitude: "75"; latitude: "85"; height: "134"; }
+ ListElement{ longitude: "75"; latitude: "86"; height: "134"; }
+ ListElement{ longitude: "75"; latitude: "87"; height: "132"; }
+ ListElement{ longitude: "75"; latitude: "88"; height: "130"; }
+ ListElement{ longitude: "75"; latitude: "89"; height: "128"; }
+ ListElement{ longitude: "75"; latitude: "90"; height: "123"; }
+ ListElement{ longitude: "75"; latitude: "91"; height: "120"; }
+ ListElement{ longitude: "75"; latitude: "92"; height: "119"; }
+ ListElement{ longitude: "75"; latitude: "93"; height: "117"; }
+ ListElement{ longitude: "75"; latitude: "94"; height: "112"; }
+ ListElement{ longitude: "75"; latitude: "95"; height: "112"; }
+ ListElement{ longitude: "75"; latitude: "96"; height: "114"; }
+ ListElement{ longitude: "75"; latitude: "97"; height: "120"; }
+ ListElement{ longitude: "75"; latitude: "98"; height: "127"; }
+ ListElement{ longitude: "75"; latitude: "99"; height: "114"; }
+ ListElement{ longitude: "76"; latitude: "0"; height: "127"; }
+ ListElement{ longitude: "76"; latitude: "1"; height: "127"; }
+ ListElement{ longitude: "76"; latitude: "2"; height: "128"; }
+ ListElement{ longitude: "76"; latitude: "3"; height: "128"; }
+ ListElement{ longitude: "76"; latitude: "4"; height: "130"; }
+ ListElement{ longitude: "76"; latitude: "5"; height: "125"; }
+ ListElement{ longitude: "76"; latitude: "6"; height: "121"; }
+ ListElement{ longitude: "76"; latitude: "7"; height: "115"; }
+ ListElement{ longitude: "76"; latitude: "8"; height: "113"; }
+ ListElement{ longitude: "76"; latitude: "9"; height: "108"; }
+ ListElement{ longitude: "76"; latitude: "10"; height: "105"; }
+ ListElement{ longitude: "76"; latitude: "11"; height: "102"; }
+ ListElement{ longitude: "76"; latitude: "12"; height: "99"; }
+ ListElement{ longitude: "76"; latitude: "13"; height: "100"; }
+ ListElement{ longitude: "76"; latitude: "14"; height: "100"; }
+ ListElement{ longitude: "76"; latitude: "15"; height: "100"; }
+ ListElement{ longitude: "76"; latitude: "16"; height: "100"; }
+ ListElement{ longitude: "76"; latitude: "17"; height: "102"; }
+ ListElement{ longitude: "76"; latitude: "18"; height: "103"; }
+ ListElement{ longitude: "76"; latitude: "19"; height: "107"; }
+ ListElement{ longitude: "76"; latitude: "20"; height: "109"; }
+ ListElement{ longitude: "76"; latitude: "21"; height: "110"; }
+ ListElement{ longitude: "76"; latitude: "22"; height: "111"; }
+ ListElement{ longitude: "76"; latitude: "23"; height: "114"; }
+ ListElement{ longitude: "76"; latitude: "24"; height: "113"; }
+ ListElement{ longitude: "76"; latitude: "25"; height: "113"; }
+ ListElement{ longitude: "76"; latitude: "26"; height: "113"; }
+ ListElement{ longitude: "76"; latitude: "27"; height: "111"; }
+ ListElement{ longitude: "76"; latitude: "28"; height: "110"; }
+ ListElement{ longitude: "76"; latitude: "29"; height: "110"; }
+ ListElement{ longitude: "76"; latitude: "30"; height: "106"; }
+ ListElement{ longitude: "76"; latitude: "31"; height: "104"; }
+ ListElement{ longitude: "76"; latitude: "32"; height: "103"; }
+ ListElement{ longitude: "76"; latitude: "33"; height: "102"; }
+ ListElement{ longitude: "76"; latitude: "34"; height: "102"; }
+ ListElement{ longitude: "76"; latitude: "35"; height: "102"; }
+ ListElement{ longitude: "76"; latitude: "36"; height: "102"; }
+ ListElement{ longitude: "76"; latitude: "37"; height: "104"; }
+ ListElement{ longitude: "76"; latitude: "38"; height: "107"; }
+ ListElement{ longitude: "76"; latitude: "39"; height: "114"; }
+ ListElement{ longitude: "76"; latitude: "40"; height: "120"; }
+ ListElement{ longitude: "76"; latitude: "41"; height: "129"; }
+ ListElement{ longitude: "76"; latitude: "42"; height: "126"; }
+ ListElement{ longitude: "76"; latitude: "43"; height: "123"; }
+ ListElement{ longitude: "76"; latitude: "44"; height: "123"; }
+ ListElement{ longitude: "76"; latitude: "45"; height: "120"; }
+ ListElement{ longitude: "76"; latitude: "46"; height: "119"; }
+ ListElement{ longitude: "76"; latitude: "47"; height: "118"; }
+ ListElement{ longitude: "76"; latitude: "48"; height: "123"; }
+ ListElement{ longitude: "76"; latitude: "49"; height: "129"; }
+ ListElement{ longitude: "76"; latitude: "50"; height: "133"; }
+ ListElement{ longitude: "76"; latitude: "51"; height: "136"; }
+ ListElement{ longitude: "76"; latitude: "52"; height: "137"; }
+ ListElement{ longitude: "76"; latitude: "53"; height: "137"; }
+ ListElement{ longitude: "76"; latitude: "54"; height: "137"; }
+ ListElement{ longitude: "76"; latitude: "55"; height: "137"; }
+ ListElement{ longitude: "76"; latitude: "56"; height: "136"; }
+ ListElement{ longitude: "76"; latitude: "57"; height: "136"; }
+ ListElement{ longitude: "76"; latitude: "58"; height: "134"; }
+ ListElement{ longitude: "76"; latitude: "59"; height: "132"; }
+ ListElement{ longitude: "76"; latitude: "60"; height: "127"; }
+ ListElement{ longitude: "76"; latitude: "61"; height: "126"; }
+ ListElement{ longitude: "76"; latitude: "62"; height: "123"; }
+ ListElement{ longitude: "76"; latitude: "63"; height: "120"; }
+ ListElement{ longitude: "76"; latitude: "64"; height: "117"; }
+ ListElement{ longitude: "76"; latitude: "65"; height: "112"; }
+ ListElement{ longitude: "76"; latitude: "66"; height: "110"; }
+ ListElement{ longitude: "76"; latitude: "67"; height: "110"; }
+ ListElement{ longitude: "76"; latitude: "68"; height: "111"; }
+ ListElement{ longitude: "76"; latitude: "69"; height: "115"; }
+ ListElement{ longitude: "76"; latitude: "70"; height: "121"; }
+ ListElement{ longitude: "76"; latitude: "71"; height: "122"; }
+ ListElement{ longitude: "76"; latitude: "72"; height: "125"; }
+ ListElement{ longitude: "76"; latitude: "73"; height: "127"; }
+ ListElement{ longitude: "76"; latitude: "74"; height: "127"; }
+ ListElement{ longitude: "76"; latitude: "75"; height: "131"; }
+ ListElement{ longitude: "76"; latitude: "76"; height: "134"; }
+ ListElement{ longitude: "76"; latitude: "77"; height: "137"; }
+ ListElement{ longitude: "76"; latitude: "78"; height: "140"; }
+ ListElement{ longitude: "76"; latitude: "79"; height: "143"; }
+ ListElement{ longitude: "76"; latitude: "80"; height: "143"; }
+ ListElement{ longitude: "76"; latitude: "81"; height: "144"; }
+ ListElement{ longitude: "76"; latitude: "82"; height: "141"; }
+ ListElement{ longitude: "76"; latitude: "83"; height: "137"; }
+ ListElement{ longitude: "76"; latitude: "84"; height: "136"; }
+ ListElement{ longitude: "76"; latitude: "85"; height: "136"; }
+ ListElement{ longitude: "76"; latitude: "86"; height: "133"; }
+ ListElement{ longitude: "76"; latitude: "87"; height: "131"; }
+ ListElement{ longitude: "76"; latitude: "88"; height: "129"; }
+ ListElement{ longitude: "76"; latitude: "89"; height: "128"; }
+ ListElement{ longitude: "76"; latitude: "90"; height: "123"; }
+ ListElement{ longitude: "76"; latitude: "91"; height: "120"; }
+ ListElement{ longitude: "76"; latitude: "92"; height: "117"; }
+ ListElement{ longitude: "76"; latitude: "93"; height: "115"; }
+ ListElement{ longitude: "76"; latitude: "94"; height: "112"; }
+ ListElement{ longitude: "76"; latitude: "95"; height: "112"; }
+ ListElement{ longitude: "76"; latitude: "96"; height: "116"; }
+ ListElement{ longitude: "76"; latitude: "97"; height: "116"; }
+ ListElement{ longitude: "76"; latitude: "98"; height: "122"; }
+ ListElement{ longitude: "76"; latitude: "99"; height: "114"; }
+ ListElement{ longitude: "77"; latitude: "0"; height: "124"; }
+ ListElement{ longitude: "77"; latitude: "1"; height: "124"; }
+ ListElement{ longitude: "77"; latitude: "2"; height: "125"; }
+ ListElement{ longitude: "77"; latitude: "3"; height: "127"; }
+ ListElement{ longitude: "77"; latitude: "4"; height: "130"; }
+ ListElement{ longitude: "77"; latitude: "5"; height: "131"; }
+ ListElement{ longitude: "77"; latitude: "6"; height: "123"; }
+ ListElement{ longitude: "77"; latitude: "7"; height: "119"; }
+ ListElement{ longitude: "77"; latitude: "8"; height: "115"; }
+ ListElement{ longitude: "77"; latitude: "9"; height: "110"; }
+ ListElement{ longitude: "77"; latitude: "10"; height: "106"; }
+ ListElement{ longitude: "77"; latitude: "11"; height: "103"; }
+ ListElement{ longitude: "77"; latitude: "12"; height: "99"; }
+ ListElement{ longitude: "77"; latitude: "13"; height: "98"; }
+ ListElement{ longitude: "77"; latitude: "14"; height: "98"; }
+ ListElement{ longitude: "77"; latitude: "15"; height: "100"; }
+ ListElement{ longitude: "77"; latitude: "16"; height: "99"; }
+ ListElement{ longitude: "77"; latitude: "17"; height: "102"; }
+ ListElement{ longitude: "77"; latitude: "18"; height: "104"; }
+ ListElement{ longitude: "77"; latitude: "19"; height: "106"; }
+ ListElement{ longitude: "77"; latitude: "20"; height: "108"; }
+ ListElement{ longitude: "77"; latitude: "21"; height: "104"; }
+ ListElement{ longitude: "77"; latitude: "22"; height: "107"; }
+ ListElement{ longitude: "77"; latitude: "23"; height: "112"; }
+ ListElement{ longitude: "77"; latitude: "24"; height: "111"; }
+ ListElement{ longitude: "77"; latitude: "25"; height: "113"; }
+ ListElement{ longitude: "77"; latitude: "26"; height: "113"; }
+ ListElement{ longitude: "77"; latitude: "27"; height: "112"; }
+ ListElement{ longitude: "77"; latitude: "28"; height: "111"; }
+ ListElement{ longitude: "77"; latitude: "29"; height: "108"; }
+ ListElement{ longitude: "77"; latitude: "30"; height: "104"; }
+ ListElement{ longitude: "77"; latitude: "31"; height: "102"; }
+ ListElement{ longitude: "77"; latitude: "32"; height: "101"; }
+ ListElement{ longitude: "77"; latitude: "33"; height: "101"; }
+ ListElement{ longitude: "77"; latitude: "34"; height: "104"; }
+ ListElement{ longitude: "77"; latitude: "35"; height: "102"; }
+ ListElement{ longitude: "77"; latitude: "36"; height: "102"; }
+ ListElement{ longitude: "77"; latitude: "37"; height: "105"; }
+ ListElement{ longitude: "77"; latitude: "38"; height: "106"; }
+ ListElement{ longitude: "77"; latitude: "39"; height: "112"; }
+ ListElement{ longitude: "77"; latitude: "40"; height: "117"; }
+ ListElement{ longitude: "77"; latitude: "41"; height: "125"; }
+ ListElement{ longitude: "77"; latitude: "42"; height: "125"; }
+ ListElement{ longitude: "77"; latitude: "43"; height: "125"; }
+ ListElement{ longitude: "77"; latitude: "44"; height: "122"; }
+ ListElement{ longitude: "77"; latitude: "45"; height: "119"; }
+ ListElement{ longitude: "77"; latitude: "46"; height: "118"; }
+ ListElement{ longitude: "77"; latitude: "47"; height: "118"; }
+ ListElement{ longitude: "77"; latitude: "48"; height: "123"; }
+ ListElement{ longitude: "77"; latitude: "49"; height: "127"; }
+ ListElement{ longitude: "77"; latitude: "50"; height: "131"; }
+ ListElement{ longitude: "77"; latitude: "51"; height: "136"; }
+ ListElement{ longitude: "77"; latitude: "52"; height: "136"; }
+ ListElement{ longitude: "77"; latitude: "53"; height: "137"; }
+ ListElement{ longitude: "77"; latitude: "54"; height: "135"; }
+ ListElement{ longitude: "77"; latitude: "55"; height: "136"; }
+ ListElement{ longitude: "77"; latitude: "56"; height: "134"; }
+ ListElement{ longitude: "77"; latitude: "57"; height: "134"; }
+ ListElement{ longitude: "77"; latitude: "58"; height: "133"; }
+ ListElement{ longitude: "77"; latitude: "59"; height: "130"; }
+ ListElement{ longitude: "77"; latitude: "60"; height: "125"; }
+ ListElement{ longitude: "77"; latitude: "61"; height: "124"; }
+ ListElement{ longitude: "77"; latitude: "62"; height: "120"; }
+ ListElement{ longitude: "77"; latitude: "63"; height: "117"; }
+ ListElement{ longitude: "77"; latitude: "64"; height: "114"; }
+ ListElement{ longitude: "77"; latitude: "65"; height: "111"; }
+ ListElement{ longitude: "77"; latitude: "66"; height: "109"; }
+ ListElement{ longitude: "77"; latitude: "67"; height: "107"; }
+ ListElement{ longitude: "77"; latitude: "68"; height: "106"; }
+ ListElement{ longitude: "77"; latitude: "69"; height: "110"; }
+ ListElement{ longitude: "77"; latitude: "70"; height: "116"; }
+ ListElement{ longitude: "77"; latitude: "71"; height: "119"; }
+ ListElement{ longitude: "77"; latitude: "72"; height: "125"; }
+ ListElement{ longitude: "77"; latitude: "73"; height: "129"; }
+ ListElement{ longitude: "77"; latitude: "74"; height: "132"; }
+ ListElement{ longitude: "77"; latitude: "75"; height: "133"; }
+ ListElement{ longitude: "77"; latitude: "76"; height: "135"; }
+ ListElement{ longitude: "77"; latitude: "77"; height: "137"; }
+ ListElement{ longitude: "77"; latitude: "78"; height: "142"; }
+ ListElement{ longitude: "77"; latitude: "79"; height: "143"; }
+ ListElement{ longitude: "77"; latitude: "80"; height: "141"; }
+ ListElement{ longitude: "77"; latitude: "81"; height: "140"; }
+ ListElement{ longitude: "77"; latitude: "82"; height: "138"; }
+ ListElement{ longitude: "77"; latitude: "83"; height: "138"; }
+ ListElement{ longitude: "77"; latitude: "84"; height: "137"; }
+ ListElement{ longitude: "77"; latitude: "85"; height: "136"; }
+ ListElement{ longitude: "77"; latitude: "86"; height: "135"; }
+ ListElement{ longitude: "77"; latitude: "87"; height: "133"; }
+ ListElement{ longitude: "77"; latitude: "88"; height: "129"; }
+ ListElement{ longitude: "77"; latitude: "89"; height: "128"; }
+ ListElement{ longitude: "77"; latitude: "90"; height: "123"; }
+ ListElement{ longitude: "77"; latitude: "91"; height: "120"; }
+ ListElement{ longitude: "77"; latitude: "92"; height: "118"; }
+ ListElement{ longitude: "77"; latitude: "93"; height: "116"; }
+ ListElement{ longitude: "77"; latitude: "94"; height: "115"; }
+ ListElement{ longitude: "77"; latitude: "95"; height: "116"; }
+ ListElement{ longitude: "77"; latitude: "96"; height: "117"; }
+ ListElement{ longitude: "77"; latitude: "97"; height: "120"; }
+ ListElement{ longitude: "77"; latitude: "98"; height: "125"; }
+ ListElement{ longitude: "77"; latitude: "99"; height: "117"; }
+ ListElement{ longitude: "78"; latitude: "0"; height: "120"; }
+ ListElement{ longitude: "78"; latitude: "1"; height: "118"; }
+ ListElement{ longitude: "78"; latitude: "2"; height: "120"; }
+ ListElement{ longitude: "78"; latitude: "3"; height: "125"; }
+ ListElement{ longitude: "78"; latitude: "4"; height: "129"; }
+ ListElement{ longitude: "78"; latitude: "5"; height: "129"; }
+ ListElement{ longitude: "78"; latitude: "6"; height: "126"; }
+ ListElement{ longitude: "78"; latitude: "7"; height: "119"; }
+ ListElement{ longitude: "78"; latitude: "8"; height: "115"; }
+ ListElement{ longitude: "78"; latitude: "9"; height: "112"; }
+ ListElement{ longitude: "78"; latitude: "10"; height: "110"; }
+ ListElement{ longitude: "78"; latitude: "11"; height: "105"; }
+ ListElement{ longitude: "78"; latitude: "12"; height: "100"; }
+ ListElement{ longitude: "78"; latitude: "13"; height: "101"; }
+ ListElement{ longitude: "78"; latitude: "14"; height: "102"; }
+ ListElement{ longitude: "78"; latitude: "15"; height: "104"; }
+ ListElement{ longitude: "78"; latitude: "16"; height: "105"; }
+ ListElement{ longitude: "78"; latitude: "17"; height: "106"; }
+ ListElement{ longitude: "78"; latitude: "18"; height: "106"; }
+ ListElement{ longitude: "78"; latitude: "19"; height: "106"; }
+ ListElement{ longitude: "78"; latitude: "20"; height: "99"; }
+ ListElement{ longitude: "78"; latitude: "21"; height: "92"; }
+ ListElement{ longitude: "78"; latitude: "22"; height: "96"; }
+ ListElement{ longitude: "78"; latitude: "23"; height: "110"; }
+ ListElement{ longitude: "78"; latitude: "24"; height: "112"; }
+ ListElement{ longitude: "78"; latitude: "25"; height: "113"; }
+ ListElement{ longitude: "78"; latitude: "26"; height: "114"; }
+ ListElement{ longitude: "78"; latitude: "27"; height: "112"; }
+ ListElement{ longitude: "78"; latitude: "28"; height: "110"; }
+ ListElement{ longitude: "78"; latitude: "29"; height: "105"; }
+ ListElement{ longitude: "78"; latitude: "30"; height: "100"; }
+ ListElement{ longitude: "78"; latitude: "31"; height: "98"; }
+ ListElement{ longitude: "78"; latitude: "32"; height: "99"; }
+ ListElement{ longitude: "78"; latitude: "33"; height: "102"; }
+ ListElement{ longitude: "78"; latitude: "34"; height: "105"; }
+ ListElement{ longitude: "78"; latitude: "35"; height: "106"; }
+ ListElement{ longitude: "78"; latitude: "36"; height: "106"; }
+ ListElement{ longitude: "78"; latitude: "37"; height: "103"; }
+ ListElement{ longitude: "78"; latitude: "38"; height: "104"; }
+ ListElement{ longitude: "78"; latitude: "39"; height: "108"; }
+ ListElement{ longitude: "78"; latitude: "40"; height: "114"; }
+ ListElement{ longitude: "78"; latitude: "41"; height: "118"; }
+ ListElement{ longitude: "78"; latitude: "42"; height: "119"; }
+ ListElement{ longitude: "78"; latitude: "43"; height: "121"; }
+ ListElement{ longitude: "78"; latitude: "44"; height: "121"; }
+ ListElement{ longitude: "78"; latitude: "45"; height: "116"; }
+ ListElement{ longitude: "78"; latitude: "46"; height: "115"; }
+ ListElement{ longitude: "78"; latitude: "47"; height: "116"; }
+ ListElement{ longitude: "78"; latitude: "48"; height: "120"; }
+ ListElement{ longitude: "78"; latitude: "49"; height: "124"; }
+ ListElement{ longitude: "78"; latitude: "50"; height: "127"; }
+ ListElement{ longitude: "78"; latitude: "51"; height: "132"; }
+ ListElement{ longitude: "78"; latitude: "52"; height: "134"; }
+ ListElement{ longitude: "78"; latitude: "53"; height: "135"; }
+ ListElement{ longitude: "78"; latitude: "54"; height: "137"; }
+ ListElement{ longitude: "78"; latitude: "55"; height: "135"; }
+ ListElement{ longitude: "78"; latitude: "56"; height: "133"; }
+ ListElement{ longitude: "78"; latitude: "57"; height: "133"; }
+ ListElement{ longitude: "78"; latitude: "58"; height: "130"; }
+ ListElement{ longitude: "78"; latitude: "59"; height: "127"; }
+ ListElement{ longitude: "78"; latitude: "60"; height: "124"; }
+ ListElement{ longitude: "78"; latitude: "61"; height: "121"; }
+ ListElement{ longitude: "78"; latitude: "62"; height: "119"; }
+ ListElement{ longitude: "78"; latitude: "63"; height: "117"; }
+ ListElement{ longitude: "78"; latitude: "64"; height: "114"; }
+ ListElement{ longitude: "78"; latitude: "65"; height: "110"; }
+ ListElement{ longitude: "78"; latitude: "66"; height: "109"; }
+ ListElement{ longitude: "78"; latitude: "67"; height: "103"; }
+ ListElement{ longitude: "78"; latitude: "68"; height: "104"; }
+ ListElement{ longitude: "78"; latitude: "69"; height: "106"; }
+ ListElement{ longitude: "78"; latitude: "70"; height: "111"; }
+ ListElement{ longitude: "78"; latitude: "71"; height: "120"; }
+ ListElement{ longitude: "78"; latitude: "72"; height: "124"; }
+ ListElement{ longitude: "78"; latitude: "73"; height: "131"; }
+ ListElement{ longitude: "78"; latitude: "74"; height: "135"; }
+ ListElement{ longitude: "78"; latitude: "75"; height: "139"; }
+ ListElement{ longitude: "78"; latitude: "76"; height: "141"; }
+ ListElement{ longitude: "78"; latitude: "77"; height: "140"; }
+ ListElement{ longitude: "78"; latitude: "78"; height: "139"; }
+ ListElement{ longitude: "78"; latitude: "79"; height: "138"; }
+ ListElement{ longitude: "78"; latitude: "80"; height: "137"; }
+ ListElement{ longitude: "78"; latitude: "81"; height: "133"; }
+ ListElement{ longitude: "78"; latitude: "82"; height: "133"; }
+ ListElement{ longitude: "78"; latitude: "83"; height: "135"; }
+ ListElement{ longitude: "78"; latitude: "84"; height: "136"; }
+ ListElement{ longitude: "78"; latitude: "85"; height: "136"; }
+ ListElement{ longitude: "78"; latitude: "86"; height: "136"; }
+ ListElement{ longitude: "78"; latitude: "87"; height: "136"; }
+ ListElement{ longitude: "78"; latitude: "88"; height: "132"; }
+ ListElement{ longitude: "78"; latitude: "89"; height: "129"; }
+ ListElement{ longitude: "78"; latitude: "90"; height: "126"; }
+ ListElement{ longitude: "78"; latitude: "91"; height: "122"; }
+ ListElement{ longitude: "78"; latitude: "92"; height: "121"; }
+ ListElement{ longitude: "78"; latitude: "93"; height: "119"; }
+ ListElement{ longitude: "78"; latitude: "94"; height: "115"; }
+ ListElement{ longitude: "78"; latitude: "95"; height: "120"; }
+ ListElement{ longitude: "78"; latitude: "96"; height: "124"; }
+ ListElement{ longitude: "78"; latitude: "97"; height: "125"; }
+ ListElement{ longitude: "78"; latitude: "98"; height: "130"; }
+ ListElement{ longitude: "78"; latitude: "99"; height: "121"; }
+ ListElement{ longitude: "79"; latitude: "0"; height: "115"; }
+ ListElement{ longitude: "79"; latitude: "1"; height: "114"; }
+ ListElement{ longitude: "79"; latitude: "2"; height: "116"; }
+ ListElement{ longitude: "79"; latitude: "3"; height: "119"; }
+ ListElement{ longitude: "79"; latitude: "4"; height: "125"; }
+ ListElement{ longitude: "79"; latitude: "5"; height: "126"; }
+ ListElement{ longitude: "79"; latitude: "6"; height: "123"; }
+ ListElement{ longitude: "79"; latitude: "7"; height: "121"; }
+ ListElement{ longitude: "79"; latitude: "8"; height: "119"; }
+ ListElement{ longitude: "79"; latitude: "9"; height: "115"; }
+ ListElement{ longitude: "79"; latitude: "10"; height: "113"; }
+ ListElement{ longitude: "79"; latitude: "11"; height: "108"; }
+ ListElement{ longitude: "79"; latitude: "12"; height: "105"; }
+ ListElement{ longitude: "79"; latitude: "13"; height: "104"; }
+ ListElement{ longitude: "79"; latitude: "14"; height: "106"; }
+ ListElement{ longitude: "79"; latitude: "15"; height: "109"; }
+ ListElement{ longitude: "79"; latitude: "16"; height: "107"; }
+ ListElement{ longitude: "79"; latitude: "17"; height: "107"; }
+ ListElement{ longitude: "79"; latitude: "18"; height: "107"; }
+ ListElement{ longitude: "79"; latitude: "19"; height: "107"; }
+ ListElement{ longitude: "79"; latitude: "20"; height: "100"; }
+ ListElement{ longitude: "79"; latitude: "21"; height: "94"; }
+ ListElement{ longitude: "79"; latitude: "22"; height: "96"; }
+ ListElement{ longitude: "79"; latitude: "23"; height: "107"; }
+ ListElement{ longitude: "79"; latitude: "24"; height: "111"; }
+ ListElement{ longitude: "79"; latitude: "25"; height: "113"; }
+ ListElement{ longitude: "79"; latitude: "26"; height: "114"; }
+ ListElement{ longitude: "79"; latitude: "27"; height: "113"; }
+ ListElement{ longitude: "79"; latitude: "28"; height: "109"; }
+ ListElement{ longitude: "79"; latitude: "29"; height: "104"; }
+ ListElement{ longitude: "79"; latitude: "30"; height: "102"; }
+ ListElement{ longitude: "79"; latitude: "31"; height: "98"; }
+ ListElement{ longitude: "79"; latitude: "32"; height: "98"; }
+ ListElement{ longitude: "79"; latitude: "33"; height: "99"; }
+ ListElement{ longitude: "79"; latitude: "34"; height: "102"; }
+ ListElement{ longitude: "79"; latitude: "35"; height: "103"; }
+ ListElement{ longitude: "79"; latitude: "36"; height: "102"; }
+ ListElement{ longitude: "79"; latitude: "37"; height: "102"; }
+ ListElement{ longitude: "79"; latitude: "38"; height: "103"; }
+ ListElement{ longitude: "79"; latitude: "39"; height: "104"; }
+ ListElement{ longitude: "79"; latitude: "40"; height: "110"; }
+ ListElement{ longitude: "79"; latitude: "41"; height: "115"; }
+ ListElement{ longitude: "79"; latitude: "42"; height: "118"; }
+ ListElement{ longitude: "79"; latitude: "43"; height: "118"; }
+ ListElement{ longitude: "79"; latitude: "44"; height: "120"; }
+ ListElement{ longitude: "79"; latitude: "45"; height: "117"; }
+ ListElement{ longitude: "79"; latitude: "46"; height: "118"; }
+ ListElement{ longitude: "79"; latitude: "47"; height: "117"; }
+ ListElement{ longitude: "79"; latitude: "48"; height: "119"; }
+ ListElement{ longitude: "79"; latitude: "49"; height: "124"; }
+ ListElement{ longitude: "79"; latitude: "50"; height: "127"; }
+ ListElement{ longitude: "79"; latitude: "51"; height: "128"; }
+ ListElement{ longitude: "79"; latitude: "52"; height: "131"; }
+ ListElement{ longitude: "79"; latitude: "53"; height: "131"; }
+ ListElement{ longitude: "79"; latitude: "54"; height: "133"; }
+ ListElement{ longitude: "79"; latitude: "55"; height: "134"; }
+ ListElement{ longitude: "79"; latitude: "56"; height: "134"; }
+ ListElement{ longitude: "79"; latitude: "57"; height: "133"; }
+ ListElement{ longitude: "79"; latitude: "58"; height: "129"; }
+ ListElement{ longitude: "79"; latitude: "59"; height: "127"; }
+ ListElement{ longitude: "79"; latitude: "60"; height: "124"; }
+ ListElement{ longitude: "79"; latitude: "61"; height: "121"; }
+ ListElement{ longitude: "79"; latitude: "62"; height: "120"; }
+ ListElement{ longitude: "79"; latitude: "63"; height: "120"; }
+ ListElement{ longitude: "79"; latitude: "64"; height: "118"; }
+ ListElement{ longitude: "79"; latitude: "65"; height: "114"; }
+ ListElement{ longitude: "79"; latitude: "66"; height: "111"; }
+ ListElement{ longitude: "79"; latitude: "67"; height: "106"; }
+ ListElement{ longitude: "79"; latitude: "68"; height: "107"; }
+ ListElement{ longitude: "79"; latitude: "69"; height: "106"; }
+ ListElement{ longitude: "79"; latitude: "70"; height: "112"; }
+ ListElement{ longitude: "79"; latitude: "71"; height: "119"; }
+ ListElement{ longitude: "79"; latitude: "72"; height: "124"; }
+ ListElement{ longitude: "79"; latitude: "73"; height: "132"; }
+ ListElement{ longitude: "79"; latitude: "74"; height: "137"; }
+ ListElement{ longitude: "79"; latitude: "75"; height: "138"; }
+ ListElement{ longitude: "79"; latitude: "76"; height: "141"; }
+ ListElement{ longitude: "79"; latitude: "77"; height: "140"; }
+ ListElement{ longitude: "79"; latitude: "78"; height: "137"; }
+ ListElement{ longitude: "79"; latitude: "79"; height: "132"; }
+ ListElement{ longitude: "79"; latitude: "80"; height: "130"; }
+ ListElement{ longitude: "79"; latitude: "81"; height: "125"; }
+ ListElement{ longitude: "79"; latitude: "82"; height: "125"; }
+ ListElement{ longitude: "79"; latitude: "83"; height: "132"; }
+ ListElement{ longitude: "79"; latitude: "84"; height: "136"; }
+ ListElement{ longitude: "79"; latitude: "85"; height: "136"; }
+ ListElement{ longitude: "79"; latitude: "86"; height: "136"; }
+ ListElement{ longitude: "79"; latitude: "87"; height: "134"; }
+ ListElement{ longitude: "79"; latitude: "88"; height: "132"; }
+ ListElement{ longitude: "79"; latitude: "89"; height: "129"; }
+ ListElement{ longitude: "79"; latitude: "90"; height: "127"; }
+ ListElement{ longitude: "79"; latitude: "91"; height: "125"; }
+ ListElement{ longitude: "79"; latitude: "92"; height: "122"; }
+ ListElement{ longitude: "79"; latitude: "93"; height: "119"; }
+ ListElement{ longitude: "79"; latitude: "94"; height: "120"; }
+ ListElement{ longitude: "79"; latitude: "95"; height: "123"; }
+ ListElement{ longitude: "79"; latitude: "96"; height: "123"; }
+ ListElement{ longitude: "79"; latitude: "97"; height: "122"; }
+ ListElement{ longitude: "79"; latitude: "98"; height: "124"; }
+ ListElement{ longitude: "79"; latitude: "99"; height: "118"; }
+ ListElement{ longitude: "80"; latitude: "0"; height: "111"; }
+ ListElement{ longitude: "80"; latitude: "1"; height: "108"; }
+ ListElement{ longitude: "80"; latitude: "2"; height: "111"; }
+ ListElement{ longitude: "80"; latitude: "3"; height: "114"; }
+ ListElement{ longitude: "80"; latitude: "4"; height: "119"; }
+ ListElement{ longitude: "80"; latitude: "5"; height: "123"; }
+ ListElement{ longitude: "80"; latitude: "6"; height: "120"; }
+ ListElement{ longitude: "80"; latitude: "7"; height: "120"; }
+ ListElement{ longitude: "80"; latitude: "8"; height: "122"; }
+ ListElement{ longitude: "80"; latitude: "9"; height: "118"; }
+ ListElement{ longitude: "80"; latitude: "10"; height: "117"; }
+ ListElement{ longitude: "80"; latitude: "11"; height: "113"; }
+ ListElement{ longitude: "80"; latitude: "12"; height: "108"; }
+ ListElement{ longitude: "80"; latitude: "13"; height: "106"; }
+ ListElement{ longitude: "80"; latitude: "14"; height: "106"; }
+ ListElement{ longitude: "80"; latitude: "15"; height: "108"; }
+ ListElement{ longitude: "80"; latitude: "16"; height: "108"; }
+ ListElement{ longitude: "80"; latitude: "17"; height: "108"; }
+ ListElement{ longitude: "80"; latitude: "18"; height: "107"; }
+ ListElement{ longitude: "80"; latitude: "19"; height: "105"; }
+ ListElement{ longitude: "80"; latitude: "20"; height: "103"; }
+ ListElement{ longitude: "80"; latitude: "21"; height: "100"; }
+ ListElement{ longitude: "80"; latitude: "22"; height: "101"; }
+ ListElement{ longitude: "80"; latitude: "23"; height: "106"; }
+ ListElement{ longitude: "80"; latitude: "24"; height: "110"; }
+ ListElement{ longitude: "80"; latitude: "25"; height: "113"; }
+ ListElement{ longitude: "80"; latitude: "26"; height: "116"; }
+ ListElement{ longitude: "80"; latitude: "27"; height: "111"; }
+ ListElement{ longitude: "80"; latitude: "28"; height: "109"; }
+ ListElement{ longitude: "80"; latitude: "29"; height: "102"; }
+ ListElement{ longitude: "80"; latitude: "30"; height: "100"; }
+ ListElement{ longitude: "80"; latitude: "31"; height: "98"; }
+ ListElement{ longitude: "80"; latitude: "32"; height: "95"; }
+ ListElement{ longitude: "80"; latitude: "33"; height: "97"; }
+ ListElement{ longitude: "80"; latitude: "34"; height: "100"; }
+ ListElement{ longitude: "80"; latitude: "35"; height: "101"; }
+ ListElement{ longitude: "80"; latitude: "36"; height: "103"; }
+ ListElement{ longitude: "80"; latitude: "37"; height: "101"; }
+ ListElement{ longitude: "80"; latitude: "38"; height: "103"; }
+ ListElement{ longitude: "80"; latitude: "39"; height: "106"; }
+ ListElement{ longitude: "80"; latitude: "40"; height: "109"; }
+ ListElement{ longitude: "80"; latitude: "41"; height: "112"; }
+ ListElement{ longitude: "80"; latitude: "42"; height: "115"; }
+ ListElement{ longitude: "80"; latitude: "43"; height: "117"; }
+ ListElement{ longitude: "80"; latitude: "44"; height: "119"; }
+ ListElement{ longitude: "80"; latitude: "45"; height: "119"; }
+ ListElement{ longitude: "80"; latitude: "46"; height: "117"; }
+ ListElement{ longitude: "80"; latitude: "47"; height: "116"; }
+ ListElement{ longitude: "80"; latitude: "48"; height: "119"; }
+ ListElement{ longitude: "80"; latitude: "49"; height: "122"; }
+ ListElement{ longitude: "80"; latitude: "50"; height: "126"; }
+ ListElement{ longitude: "80"; latitude: "51"; height: "126"; }
+ ListElement{ longitude: "80"; latitude: "52"; height: "127"; }
+ ListElement{ longitude: "80"; latitude: "53"; height: "128"; }
+ ListElement{ longitude: "80"; latitude: "54"; height: "131"; }
+ ListElement{ longitude: "80"; latitude: "55"; height: "131"; }
+ ListElement{ longitude: "80"; latitude: "56"; height: "134"; }
+ ListElement{ longitude: "80"; latitude: "57"; height: "133"; }
+ ListElement{ longitude: "80"; latitude: "58"; height: "130"; }
+ ListElement{ longitude: "80"; latitude: "59"; height: "129"; }
+ ListElement{ longitude: "80"; latitude: "60"; height: "125"; }
+ ListElement{ longitude: "80"; latitude: "61"; height: "123"; }
+ ListElement{ longitude: "80"; latitude: "62"; height: "121"; }
+ ListElement{ longitude: "80"; latitude: "63"; height: "122"; }
+ ListElement{ longitude: "80"; latitude: "64"; height: "121"; }
+ ListElement{ longitude: "80"; latitude: "65"; height: "119"; }
+ ListElement{ longitude: "80"; latitude: "66"; height: "116"; }
+ ListElement{ longitude: "80"; latitude: "67"; height: "111"; }
+ ListElement{ longitude: "80"; latitude: "68"; height: "108"; }
+ ListElement{ longitude: "80"; latitude: "69"; height: "110"; }
+ ListElement{ longitude: "80"; latitude: "70"; height: "112"; }
+ ListElement{ longitude: "80"; latitude: "71"; height: "117"; }
+ ListElement{ longitude: "80"; latitude: "72"; height: "125"; }
+ ListElement{ longitude: "80"; latitude: "73"; height: "132"; }
+ ListElement{ longitude: "80"; latitude: "74"; height: "139"; }
+ ListElement{ longitude: "80"; latitude: "75"; height: "144"; }
+ ListElement{ longitude: "80"; latitude: "76"; height: "144"; }
+ ListElement{ longitude: "80"; latitude: "77"; height: "141"; }
+ ListElement{ longitude: "80"; latitude: "78"; height: "136"; }
+ ListElement{ longitude: "80"; latitude: "79"; height: "127"; }
+ ListElement{ longitude: "80"; latitude: "80"; height: "128"; }
+ ListElement{ longitude: "80"; latitude: "81"; height: "125"; }
+ ListElement{ longitude: "80"; latitude: "82"; height: "129"; }
+ ListElement{ longitude: "80"; latitude: "83"; height: "131"; }
+ ListElement{ longitude: "80"; latitude: "84"; height: "135"; }
+ ListElement{ longitude: "80"; latitude: "85"; height: "136"; }
+ ListElement{ longitude: "80"; latitude: "86"; height: "135"; }
+ ListElement{ longitude: "80"; latitude: "87"; height: "131"; }
+ ListElement{ longitude: "80"; latitude: "88"; height: "129"; }
+ ListElement{ longitude: "80"; latitude: "89"; height: "129"; }
+ ListElement{ longitude: "80"; latitude: "90"; height: "127"; }
+ ListElement{ longitude: "80"; latitude: "91"; height: "125"; }
+ ListElement{ longitude: "80"; latitude: "92"; height: "121"; }
+ ListElement{ longitude: "80"; latitude: "93"; height: "120"; }
+ ListElement{ longitude: "80"; latitude: "94"; height: "120"; }
+ ListElement{ longitude: "80"; latitude: "95"; height: "119"; }
+ ListElement{ longitude: "80"; latitude: "96"; height: "120"; }
+ ListElement{ longitude: "80"; latitude: "97"; height: "117"; }
+ ListElement{ longitude: "80"; latitude: "98"; height: "116"; }
+ ListElement{ longitude: "80"; latitude: "99"; height: "112"; }
+ ListElement{ longitude: "81"; latitude: "0"; height: "107"; }
+ ListElement{ longitude: "81"; latitude: "1"; height: "105"; }
+ ListElement{ longitude: "81"; latitude: "2"; height: "106"; }
+ ListElement{ longitude: "81"; latitude: "3"; height: "109"; }
+ ListElement{ longitude: "81"; latitude: "4"; height: "114"; }
+ ListElement{ longitude: "81"; latitude: "5"; height: "117"; }
+ ListElement{ longitude: "81"; latitude: "6"; height: "121"; }
+ ListElement{ longitude: "81"; latitude: "7"; height: "123"; }
+ ListElement{ longitude: "81"; latitude: "8"; height: "126"; }
+ ListElement{ longitude: "81"; latitude: "9"; height: "129"; }
+ ListElement{ longitude: "81"; latitude: "10"; height: "120"; }
+ ListElement{ longitude: "81"; latitude: "11"; height: "120"; }
+ ListElement{ longitude: "81"; latitude: "12"; height: "113"; }
+ ListElement{ longitude: "81"; latitude: "13"; height: "108"; }
+ ListElement{ longitude: "81"; latitude: "14"; height: "107"; }
+ ListElement{ longitude: "81"; latitude: "15"; height: "108"; }
+ ListElement{ longitude: "81"; latitude: "16"; height: "108"; }
+ ListElement{ longitude: "81"; latitude: "17"; height: "109"; }
+ ListElement{ longitude: "81"; latitude: "18"; height: "106"; }
+ ListElement{ longitude: "81"; latitude: "19"; height: "104"; }
+ ListElement{ longitude: "81"; latitude: "20"; height: "101"; }
+ ListElement{ longitude: "81"; latitude: "21"; height: "102"; }
+ ListElement{ longitude: "81"; latitude: "22"; height: "103"; }
+ ListElement{ longitude: "81"; latitude: "23"; height: "106"; }
+ ListElement{ longitude: "81"; latitude: "24"; height: "110"; }
+ ListElement{ longitude: "81"; latitude: "25"; height: "114"; }
+ ListElement{ longitude: "81"; latitude: "26"; height: "117"; }
+ ListElement{ longitude: "81"; latitude: "27"; height: "112"; }
+ ListElement{ longitude: "81"; latitude: "28"; height: "110"; }
+ ListElement{ longitude: "81"; latitude: "29"; height: "103"; }
+ ListElement{ longitude: "81"; latitude: "30"; height: "103"; }
+ ListElement{ longitude: "81"; latitude: "31"; height: "99"; }
+ ListElement{ longitude: "81"; latitude: "32"; height: "97"; }
+ ListElement{ longitude: "81"; latitude: "33"; height: "93"; }
+ ListElement{ longitude: "81"; latitude: "34"; height: "95"; }
+ ListElement{ longitude: "81"; latitude: "35"; height: "94"; }
+ ListElement{ longitude: "81"; latitude: "36"; height: "95"; }
+ ListElement{ longitude: "81"; latitude: "37"; height: "99"; }
+ ListElement{ longitude: "81"; latitude: "38"; height: "103"; }
+ ListElement{ longitude: "81"; latitude: "39"; height: "108"; }
+ ListElement{ longitude: "81"; latitude: "40"; height: "112"; }
+ ListElement{ longitude: "81"; latitude: "41"; height: "112"; }
+ ListElement{ longitude: "81"; latitude: "42"; height: "116"; }
+ ListElement{ longitude: "81"; latitude: "43"; height: "118"; }
+ ListElement{ longitude: "81"; latitude: "44"; height: "119"; }
+ ListElement{ longitude: "81"; latitude: "45"; height: "118"; }
+ ListElement{ longitude: "81"; latitude: "46"; height: "120"; }
+ ListElement{ longitude: "81"; latitude: "47"; height: "119"; }
+ ListElement{ longitude: "81"; latitude: "48"; height: "122"; }
+ ListElement{ longitude: "81"; latitude: "49"; height: "122"; }
+ ListElement{ longitude: "81"; latitude: "50"; height: "124"; }
+ ListElement{ longitude: "81"; latitude: "51"; height: "125"; }
+ ListElement{ longitude: "81"; latitude: "52"; height: "125"; }
+ ListElement{ longitude: "81"; latitude: "53"; height: "125"; }
+ ListElement{ longitude: "81"; latitude: "54"; height: "128"; }
+ ListElement{ longitude: "81"; latitude: "55"; height: "132"; }
+ ListElement{ longitude: "81"; latitude: "56"; height: "134"; }
+ ListElement{ longitude: "81"; latitude: "57"; height: "134"; }
+ ListElement{ longitude: "81"; latitude: "58"; height: "133"; }
+ ListElement{ longitude: "81"; latitude: "59"; height: "131"; }
+ ListElement{ longitude: "81"; latitude: "60"; height: "126"; }
+ ListElement{ longitude: "81"; latitude: "61"; height: "126"; }
+ ListElement{ longitude: "81"; latitude: "62"; height: "123"; }
+ ListElement{ longitude: "81"; latitude: "63"; height: "124"; }
+ ListElement{ longitude: "81"; latitude: "64"; height: "125"; }
+ ListElement{ longitude: "81"; latitude: "65"; height: "124"; }
+ ListElement{ longitude: "81"; latitude: "66"; height: "116"; }
+ ListElement{ longitude: "81"; latitude: "67"; height: "120"; }
+ ListElement{ longitude: "81"; latitude: "68"; height: "113"; }
+ ListElement{ longitude: "81"; latitude: "69"; height: "110"; }
+ ListElement{ longitude: "81"; latitude: "70"; height: "113"; }
+ ListElement{ longitude: "81"; latitude: "71"; height: "117"; }
+ ListElement{ longitude: "81"; latitude: "72"; height: "123"; }
+ ListElement{ longitude: "81"; latitude: "73"; height: "130"; }
+ ListElement{ longitude: "81"; latitude: "74"; height: "141"; }
+ ListElement{ longitude: "81"; latitude: "75"; height: "140"; }
+ ListElement{ longitude: "81"; latitude: "76"; height: "141"; }
+ ListElement{ longitude: "81"; latitude: "77"; height: "138"; }
+ ListElement{ longitude: "81"; latitude: "78"; height: "115"; }
+ ListElement{ longitude: "81"; latitude: "79"; height: "118"; }
+ ListElement{ longitude: "81"; latitude: "80"; height: "127"; }
+ ListElement{ longitude: "81"; latitude: "81"; height: "127"; }
+ ListElement{ longitude: "81"; latitude: "82"; height: "131"; }
+ ListElement{ longitude: "81"; latitude: "83"; height: "133"; }
+ ListElement{ longitude: "81"; latitude: "84"; height: "136"; }
+ ListElement{ longitude: "81"; latitude: "85"; height: "136"; }
+ ListElement{ longitude: "81"; latitude: "86"; height: "134"; }
+ ListElement{ longitude: "81"; latitude: "87"; height: "129"; }
+ ListElement{ longitude: "81"; latitude: "88"; height: "127"; }
+ ListElement{ longitude: "81"; latitude: "89"; height: "127"; }
+ ListElement{ longitude: "81"; latitude: "90"; height: "124"; }
+ ListElement{ longitude: "81"; latitude: "91"; height: "125"; }
+ ListElement{ longitude: "81"; latitude: "92"; height: "124"; }
+ ListElement{ longitude: "81"; latitude: "93"; height: "122"; }
+ ListElement{ longitude: "81"; latitude: "94"; height: "120"; }
+ ListElement{ longitude: "81"; latitude: "95"; height: "115"; }
+ ListElement{ longitude: "81"; latitude: "96"; height: "112"; }
+ ListElement{ longitude: "81"; latitude: "97"; height: "108"; }
+ ListElement{ longitude: "81"; latitude: "98"; height: "110"; }
+ ListElement{ longitude: "81"; latitude: "99"; height: "108"; }
+ ListElement{ longitude: "82"; latitude: "0"; height: "107"; }
+ ListElement{ longitude: "82"; latitude: "1"; height: "105"; }
+ ListElement{ longitude: "82"; latitude: "2"; height: "108"; }
+ ListElement{ longitude: "82"; latitude: "3"; height: "109"; }
+ ListElement{ longitude: "82"; latitude: "4"; height: "112"; }
+ ListElement{ longitude: "82"; latitude: "5"; height: "115"; }
+ ListElement{ longitude: "82"; latitude: "6"; height: "119"; }
+ ListElement{ longitude: "82"; latitude: "7"; height: "124"; }
+ ListElement{ longitude: "82"; latitude: "8"; height: "128"; }
+ ListElement{ longitude: "82"; latitude: "9"; height: "127"; }
+ ListElement{ longitude: "82"; latitude: "10"; height: "88"; }
+ ListElement{ longitude: "82"; latitude: "11"; height: "118"; }
+ ListElement{ longitude: "82"; latitude: "12"; height: "115"; }
+ ListElement{ longitude: "82"; latitude: "13"; height: "111"; }
+ ListElement{ longitude: "82"; latitude: "14"; height: "108"; }
+ ListElement{ longitude: "82"; latitude: "15"; height: "107"; }
+ ListElement{ longitude: "82"; latitude: "16"; height: "106"; }
+ ListElement{ longitude: "82"; latitude: "17"; height: "105"; }
+ ListElement{ longitude: "82"; latitude: "18"; height: "104"; }
+ ListElement{ longitude: "82"; latitude: "19"; height: "102"; }
+ ListElement{ longitude: "82"; latitude: "20"; height: "99"; }
+ ListElement{ longitude: "82"; latitude: "21"; height: "99"; }
+ ListElement{ longitude: "82"; latitude: "22"; height: "99"; }
+ ListElement{ longitude: "82"; latitude: "23"; height: "104"; }
+ ListElement{ longitude: "82"; latitude: "24"; height: "107"; }
+ ListElement{ longitude: "82"; latitude: "25"; height: "114"; }
+ ListElement{ longitude: "82"; latitude: "26"; height: "118"; }
+ ListElement{ longitude: "82"; latitude: "27"; height: "115"; }
+ ListElement{ longitude: "82"; latitude: "28"; height: "112"; }
+ ListElement{ longitude: "82"; latitude: "29"; height: "107"; }
+ ListElement{ longitude: "82"; latitude: "30"; height: "105"; }
+ ListElement{ longitude: "82"; latitude: "31"; height: "102"; }
+ ListElement{ longitude: "82"; latitude: "32"; height: "97"; }
+ ListElement{ longitude: "82"; latitude: "33"; height: "95"; }
+ ListElement{ longitude: "82"; latitude: "34"; height: "92"; }
+ ListElement{ longitude: "82"; latitude: "35"; height: "94"; }
+ ListElement{ longitude: "82"; latitude: "36"; height: "96"; }
+ ListElement{ longitude: "82"; latitude: "37"; height: "99"; }
+ ListElement{ longitude: "82"; latitude: "38"; height: "103"; }
+ ListElement{ longitude: "82"; latitude: "39"; height: "108"; }
+ ListElement{ longitude: "82"; latitude: "40"; height: "113"; }
+ ListElement{ longitude: "82"; latitude: "41"; height: "116"; }
+ ListElement{ longitude: "82"; latitude: "42"; height: "117"; }
+ ListElement{ longitude: "82"; latitude: "43"; height: "116"; }
+ ListElement{ longitude: "82"; latitude: "44"; height: "117"; }
+ ListElement{ longitude: "82"; latitude: "45"; height: "120"; }
+ ListElement{ longitude: "82"; latitude: "46"; height: "119"; }
+ ListElement{ longitude: "82"; latitude: "47"; height: "121"; }
+ ListElement{ longitude: "82"; latitude: "48"; height: "122"; }
+ ListElement{ longitude: "82"; latitude: "49"; height: "125"; }
+ ListElement{ longitude: "82"; latitude: "50"; height: "126"; }
+ ListElement{ longitude: "82"; latitude: "51"; height: "125"; }
+ ListElement{ longitude: "82"; latitude: "52"; height: "126"; }
+ ListElement{ longitude: "82"; latitude: "53"; height: "127"; }
+ ListElement{ longitude: "82"; latitude: "54"; height: "130"; }
+ ListElement{ longitude: "82"; latitude: "55"; height: "130"; }
+ ListElement{ longitude: "82"; latitude: "56"; height: "132"; }
+ ListElement{ longitude: "82"; latitude: "57"; height: "134"; }
+ ListElement{ longitude: "82"; latitude: "58"; height: "132"; }
+ ListElement{ longitude: "82"; latitude: "59"; height: "132"; }
+ ListElement{ longitude: "82"; latitude: "60"; height: "128"; }
+ ListElement{ longitude: "82"; latitude: "61"; height: "128"; }
+ ListElement{ longitude: "82"; latitude: "62"; height: "125"; }
+ ListElement{ longitude: "82"; latitude: "63"; height: "127"; }
+ ListElement{ longitude: "82"; latitude: "64"; height: "123"; }
+ ListElement{ longitude: "82"; latitude: "65"; height: "119"; }
+ ListElement{ longitude: "82"; latitude: "66"; height: "112"; }
+ ListElement{ longitude: "82"; latitude: "67"; height: "117"; }
+ ListElement{ longitude: "82"; latitude: "68"; height: "119"; }
+ ListElement{ longitude: "82"; latitude: "69"; height: "117"; }
+ ListElement{ longitude: "82"; latitude: "70"; height: "113"; }
+ ListElement{ longitude: "82"; latitude: "71"; height: "115"; }
+ ListElement{ longitude: "82"; latitude: "72"; height: "122"; }
+ ListElement{ longitude: "82"; latitude: "73"; height: "131"; }
+ ListElement{ longitude: "82"; latitude: "74"; height: "132"; }
+ ListElement{ longitude: "82"; latitude: "75"; height: "108"; }
+ ListElement{ longitude: "82"; latitude: "76"; height: "114"; }
+ ListElement{ longitude: "82"; latitude: "77"; height: "126"; }
+ ListElement{ longitude: "82"; latitude: "78"; height: "100"; }
+ ListElement{ longitude: "82"; latitude: "79"; height: "109"; }
+ ListElement{ longitude: "82"; latitude: "80"; height: "133"; }
+ ListElement{ longitude: "82"; latitude: "81"; height: "132"; }
+ ListElement{ longitude: "82"; latitude: "82"; height: "135"; }
+ ListElement{ longitude: "82"; latitude: "83"; height: "139"; }
+ ListElement{ longitude: "82"; latitude: "84"; height: "139"; }
+ ListElement{ longitude: "82"; latitude: "85"; height: "135"; }
+ ListElement{ longitude: "82"; latitude: "86"; height: "131"; }
+ ListElement{ longitude: "82"; latitude: "87"; height: "128"; }
+ ListElement{ longitude: "82"; latitude: "88"; height: "123"; }
+ ListElement{ longitude: "82"; latitude: "89"; height: "121"; }
+ ListElement{ longitude: "82"; latitude: "90"; height: "122"; }
+ ListElement{ longitude: "82"; latitude: "91"; height: "122"; }
+ ListElement{ longitude: "82"; latitude: "92"; height: "122"; }
+ ListElement{ longitude: "82"; latitude: "93"; height: "123"; }
+ ListElement{ longitude: "82"; latitude: "94"; height: "120"; }
+ ListElement{ longitude: "82"; latitude: "95"; height: "114"; }
+ ListElement{ longitude: "82"; latitude: "96"; height: "106"; }
+ ListElement{ longitude: "82"; latitude: "97"; height: "102"; }
+ ListElement{ longitude: "82"; latitude: "98"; height: "105"; }
+ ListElement{ longitude: "82"; latitude: "99"; height: "106"; }
+ ListElement{ longitude: "83"; latitude: "0"; height: "110"; }
+ ListElement{ longitude: "83"; latitude: "1"; height: "108"; }
+ ListElement{ longitude: "83"; latitude: "2"; height: "110"; }
+ ListElement{ longitude: "83"; latitude: "3"; height: "111"; }
+ ListElement{ longitude: "83"; latitude: "4"; height: "111"; }
+ ListElement{ longitude: "83"; latitude: "5"; height: "116"; }
+ ListElement{ longitude: "83"; latitude: "6"; height: "120"; }
+ ListElement{ longitude: "83"; latitude: "7"; height: "126"; }
+ ListElement{ longitude: "83"; latitude: "8"; height: "131"; }
+ ListElement{ longitude: "83"; latitude: "9"; height: "131"; }
+ ListElement{ longitude: "83"; latitude: "10"; height: "121"; }
+ ListElement{ longitude: "83"; latitude: "11"; height: "126"; }
+ ListElement{ longitude: "83"; latitude: "12"; height: "114"; }
+ ListElement{ longitude: "83"; latitude: "13"; height: "109"; }
+ ListElement{ longitude: "83"; latitude: "14"; height: "105"; }
+ ListElement{ longitude: "83"; latitude: "15"; height: "102"; }
+ ListElement{ longitude: "83"; latitude: "16"; height: "101"; }
+ ListElement{ longitude: "83"; latitude: "17"; height: "102"; }
+ ListElement{ longitude: "83"; latitude: "18"; height: "100"; }
+ ListElement{ longitude: "83"; latitude: "19"; height: "97"; }
+ ListElement{ longitude: "83"; latitude: "20"; height: "98"; }
+ ListElement{ longitude: "83"; latitude: "21"; height: "97"; }
+ ListElement{ longitude: "83"; latitude: "22"; height: "99"; }
+ ListElement{ longitude: "83"; latitude: "23"; height: "105"; }
+ ListElement{ longitude: "83"; latitude: "24"; height: "112"; }
+ ListElement{ longitude: "83"; latitude: "25"; height: "116"; }
+ ListElement{ longitude: "83"; latitude: "26"; height: "118"; }
+ ListElement{ longitude: "83"; latitude: "27"; height: "117"; }
+ ListElement{ longitude: "83"; latitude: "28"; height: "114"; }
+ ListElement{ longitude: "83"; latitude: "29"; height: "109"; }
+ ListElement{ longitude: "83"; latitude: "30"; height: "107"; }
+ ListElement{ longitude: "83"; latitude: "31"; height: "102"; }
+ ListElement{ longitude: "83"; latitude: "32"; height: "98"; }
+ ListElement{ longitude: "83"; latitude: "33"; height: "96"; }
+ ListElement{ longitude: "83"; latitude: "34"; height: "93"; }
+ ListElement{ longitude: "83"; latitude: "35"; height: "93"; }
+ ListElement{ longitude: "83"; latitude: "36"; height: "95"; }
+ ListElement{ longitude: "83"; latitude: "37"; height: "100"; }
+ ListElement{ longitude: "83"; latitude: "38"; height: "105"; }
+ ListElement{ longitude: "83"; latitude: "39"; height: "111"; }
+ ListElement{ longitude: "83"; latitude: "40"; height: "115"; }
+ ListElement{ longitude: "83"; latitude: "41"; height: "118"; }
+ ListElement{ longitude: "83"; latitude: "42"; height: "117"; }
+ ListElement{ longitude: "83"; latitude: "43"; height: "117"; }
+ ListElement{ longitude: "83"; latitude: "44"; height: "118"; }
+ ListElement{ longitude: "83"; latitude: "45"; height: "121"; }
+ ListElement{ longitude: "83"; latitude: "46"; height: "121"; }
+ ListElement{ longitude: "83"; latitude: "47"; height: "123"; }
+ ListElement{ longitude: "83"; latitude: "48"; height: "126"; }
+ ListElement{ longitude: "83"; latitude: "49"; height: "127"; }
+ ListElement{ longitude: "83"; latitude: "50"; height: "126"; }
+ ListElement{ longitude: "83"; latitude: "51"; height: "126"; }
+ ListElement{ longitude: "83"; latitude: "52"; height: "127"; }
+ ListElement{ longitude: "83"; latitude: "53"; height: "128"; }
+ ListElement{ longitude: "83"; latitude: "54"; height: "131"; }
+ ListElement{ longitude: "83"; latitude: "55"; height: "131"; }
+ ListElement{ longitude: "83"; latitude: "56"; height: "134"; }
+ ListElement{ longitude: "83"; latitude: "57"; height: "133"; }
+ ListElement{ longitude: "83"; latitude: "58"; height: "136"; }
+ ListElement{ longitude: "83"; latitude: "59"; height: "133"; }
+ ListElement{ longitude: "83"; latitude: "60"; height: "129"; }
+ ListElement{ longitude: "83"; latitude: "61"; height: "129"; }
+ ListElement{ longitude: "83"; latitude: "62"; height: "126"; }
+ ListElement{ longitude: "83"; latitude: "63"; height: "128"; }
+ ListElement{ longitude: "83"; latitude: "64"; height: "116"; }
+ ListElement{ longitude: "83"; latitude: "65"; height: "118"; }
+ ListElement{ longitude: "83"; latitude: "66"; height: "120"; }
+ ListElement{ longitude: "83"; latitude: "67"; height: "124"; }
+ ListElement{ longitude: "83"; latitude: "68"; height: "120"; }
+ ListElement{ longitude: "83"; latitude: "69"; height: "120"; }
+ ListElement{ longitude: "83"; latitude: "70"; height: "117"; }
+ ListElement{ longitude: "83"; latitude: "71"; height: "118"; }
+ ListElement{ longitude: "83"; latitude: "72"; height: "120"; }
+ ListElement{ longitude: "83"; latitude: "73"; height: "129"; }
+ ListElement{ longitude: "83"; latitude: "74"; height: "130"; }
+ ListElement{ longitude: "83"; latitude: "75"; height: "94"; }
+ ListElement{ longitude: "83"; latitude: "76"; height: "111"; }
+ ListElement{ longitude: "83"; latitude: "77"; height: "131"; }
+ ListElement{ longitude: "83"; latitude: "78"; height: "120"; }
+ ListElement{ longitude: "83"; latitude: "79"; height: "128"; }
+ ListElement{ longitude: "83"; latitude: "80"; height: "135"; }
+ ListElement{ longitude: "83"; latitude: "81"; height: "140"; }
+ ListElement{ longitude: "83"; latitude: "82"; height: "142"; }
+ ListElement{ longitude: "83"; latitude: "83"; height: "143"; }
+ ListElement{ longitude: "83"; latitude: "84"; height: "140"; }
+ ListElement{ longitude: "83"; latitude: "85"; height: "137"; }
+ ListElement{ longitude: "83"; latitude: "86"; height: "133"; }
+ ListElement{ longitude: "83"; latitude: "87"; height: "127"; }
+ ListElement{ longitude: "83"; latitude: "88"; height: "125"; }
+ ListElement{ longitude: "83"; latitude: "89"; height: "121"; }
+ ListElement{ longitude: "83"; latitude: "90"; height: "121"; }
+ ListElement{ longitude: "83"; latitude: "91"; height: "121"; }
+ ListElement{ longitude: "83"; latitude: "92"; height: "123"; }
+ ListElement{ longitude: "83"; latitude: "93"; height: "124"; }
+ ListElement{ longitude: "83"; latitude: "94"; height: "122"; }
+ ListElement{ longitude: "83"; latitude: "95"; height: "117"; }
+ ListElement{ longitude: "83"; latitude: "96"; height: "104"; }
+ ListElement{ longitude: "83"; latitude: "97"; height: "97"; }
+ ListElement{ longitude: "83"; latitude: "98"; height: "103"; }
+ ListElement{ longitude: "83"; latitude: "99"; height: "104"; }
+ ListElement{ longitude: "84"; latitude: "0"; height: "111"; }
+ ListElement{ longitude: "84"; latitude: "1"; height: "108"; }
+ ListElement{ longitude: "84"; latitude: "2"; height: "110"; }
+ ListElement{ longitude: "84"; latitude: "3"; height: "111"; }
+ ListElement{ longitude: "84"; latitude: "4"; height: "111"; }
+ ListElement{ longitude: "84"; latitude: "5"; height: "116"; }
+ ListElement{ longitude: "84"; latitude: "6"; height: "118"; }
+ ListElement{ longitude: "84"; latitude: "7"; height: "124"; }
+ ListElement{ longitude: "84"; latitude: "8"; height: "128"; }
+ ListElement{ longitude: "84"; latitude: "9"; height: "99"; }
+ ListElement{ longitude: "84"; latitude: "10"; height: "115"; }
+ ListElement{ longitude: "84"; latitude: "11"; height: "126"; }
+ ListElement{ longitude: "84"; latitude: "12"; height: "116"; }
+ ListElement{ longitude: "84"; latitude: "13"; height: "109"; }
+ ListElement{ longitude: "84"; latitude: "14"; height: "104"; }
+ ListElement{ longitude: "84"; latitude: "15"; height: "100"; }
+ ListElement{ longitude: "84"; latitude: "16"; height: "97"; }
+ ListElement{ longitude: "84"; latitude: "17"; height: "98"; }
+ ListElement{ longitude: "84"; latitude: "18"; height: "99"; }
+ ListElement{ longitude: "84"; latitude: "19"; height: "97"; }
+ ListElement{ longitude: "84"; latitude: "20"; height: "98"; }
+ ListElement{ longitude: "84"; latitude: "21"; height: "100"; }
+ ListElement{ longitude: "84"; latitude: "22"; height: "103"; }
+ ListElement{ longitude: "84"; latitude: "23"; height: "109"; }
+ ListElement{ longitude: "84"; latitude: "24"; height: "114"; }
+ ListElement{ longitude: "84"; latitude: "25"; height: "119"; }
+ ListElement{ longitude: "84"; latitude: "26"; height: "120"; }
+ ListElement{ longitude: "84"; latitude: "27"; height: "119"; }
+ ListElement{ longitude: "84"; latitude: "28"; height: "116"; }
+ ListElement{ longitude: "84"; latitude: "29"; height: "111"; }
+ ListElement{ longitude: "84"; latitude: "30"; height: "109"; }
+ ListElement{ longitude: "84"; latitude: "31"; height: "104"; }
+ ListElement{ longitude: "84"; latitude: "32"; height: "100"; }
+ ListElement{ longitude: "84"; latitude: "33"; height: "100"; }
+ ListElement{ longitude: "84"; latitude: "34"; height: "97"; }
+ ListElement{ longitude: "84"; latitude: "35"; height: "97"; }
+ ListElement{ longitude: "84"; latitude: "36"; height: "99"; }
+ ListElement{ longitude: "84"; latitude: "37"; height: "103"; }
+ ListElement{ longitude: "84"; latitude: "38"; height: "109"; }
+ ListElement{ longitude: "84"; latitude: "39"; height: "114"; }
+ ListElement{ longitude: "84"; latitude: "40"; height: "118"; }
+ ListElement{ longitude: "84"; latitude: "41"; height: "120"; }
+ ListElement{ longitude: "84"; latitude: "42"; height: "121"; }
+ ListElement{ longitude: "84"; latitude: "43"; height: "121"; }
+ ListElement{ longitude: "84"; latitude: "44"; height: "120"; }
+ ListElement{ longitude: "84"; latitude: "45"; height: "122"; }
+ ListElement{ longitude: "84"; latitude: "46"; height: "124"; }
+ ListElement{ longitude: "84"; latitude: "47"; height: "127"; }
+ ListElement{ longitude: "84"; latitude: "48"; height: "129"; }
+ ListElement{ longitude: "84"; latitude: "49"; height: "129"; }
+ ListElement{ longitude: "84"; latitude: "50"; height: "129"; }
+ ListElement{ longitude: "84"; latitude: "51"; height: "129"; }
+ ListElement{ longitude: "84"; latitude: "52"; height: "130"; }
+ ListElement{ longitude: "84"; latitude: "53"; height: "131"; }
+ ListElement{ longitude: "84"; latitude: "54"; height: "131"; }
+ ListElement{ longitude: "84"; latitude: "55"; height: "132"; }
+ ListElement{ longitude: "84"; latitude: "56"; height: "135"; }
+ ListElement{ longitude: "84"; latitude: "57"; height: "136"; }
+ ListElement{ longitude: "84"; latitude: "58"; height: "135"; }
+ ListElement{ longitude: "84"; latitude: "59"; height: "132"; }
+ ListElement{ longitude: "84"; latitude: "60"; height: "132"; }
+ ListElement{ longitude: "84"; latitude: "61"; height: "129"; }
+ ListElement{ longitude: "84"; latitude: "62"; height: "128"; }
+ ListElement{ longitude: "84"; latitude: "63"; height: "128"; }
+ ListElement{ longitude: "84"; latitude: "64"; height: "123"; }
+ ListElement{ longitude: "84"; latitude: "65"; height: "126"; }
+ ListElement{ longitude: "84"; latitude: "66"; height: "130"; }
+ ListElement{ longitude: "84"; latitude: "67"; height: "126"; }
+ ListElement{ longitude: "84"; latitude: "68"; height: "123"; }
+ ListElement{ longitude: "84"; latitude: "69"; height: "123"; }
+ ListElement{ longitude: "84"; latitude: "70"; height: "120"; }
+ ListElement{ longitude: "84"; latitude: "71"; height: "120"; }
+ ListElement{ longitude: "84"; latitude: "72"; height: "122"; }
+ ListElement{ longitude: "84"; latitude: "73"; height: "126"; }
+ ListElement{ longitude: "84"; latitude: "74"; height: "128"; }
+ ListElement{ longitude: "84"; latitude: "75"; height: "114"; }
+ ListElement{ longitude: "84"; latitude: "76"; height: "109"; }
+ ListElement{ longitude: "84"; latitude: "77"; height: "111"; }
+ ListElement{ longitude: "84"; latitude: "78"; height: "119"; }
+ ListElement{ longitude: "84"; latitude: "79"; height: "129"; }
+ ListElement{ longitude: "84"; latitude: "80"; height: "136"; }
+ ListElement{ longitude: "84"; latitude: "81"; height: "142"; }
+ ListElement{ longitude: "84"; latitude: "82"; height: "148"; }
+ ListElement{ longitude: "84"; latitude: "83"; height: "149"; }
+ ListElement{ longitude: "84"; latitude: "84"; height: "145"; }
+ ListElement{ longitude: "84"; latitude: "85"; height: "142"; }
+ ListElement{ longitude: "84"; latitude: "86"; height: "138"; }
+ ListElement{ longitude: "84"; latitude: "87"; height: "132"; }
+ ListElement{ longitude: "84"; latitude: "88"; height: "128"; }
+ ListElement{ longitude: "84"; latitude: "89"; height: "123"; }
+ ListElement{ longitude: "84"; latitude: "90"; height: "122"; }
+ ListElement{ longitude: "84"; latitude: "91"; height: "121"; }
+ ListElement{ longitude: "84"; latitude: "92"; height: "120"; }
+ ListElement{ longitude: "84"; latitude: "93"; height: "121"; }
+ ListElement{ longitude: "84"; latitude: "94"; height: "119"; }
+ ListElement{ longitude: "84"; latitude: "95"; height: "115"; }
+ ListElement{ longitude: "84"; latitude: "96"; height: "110"; }
+ ListElement{ longitude: "84"; latitude: "97"; height: "107"; }
+ ListElement{ longitude: "84"; latitude: "98"; height: "113"; }
+ ListElement{ longitude: "84"; latitude: "99"; height: "111"; }
+ ListElement{ longitude: "85"; latitude: "0"; height: "112"; }
+ ListElement{ longitude: "85"; latitude: "1"; height: "110"; }
+ ListElement{ longitude: "85"; latitude: "2"; height: "108"; }
+ ListElement{ longitude: "85"; latitude: "3"; height: "110"; }
+ ListElement{ longitude: "85"; latitude: "4"; height: "112"; }
+ ListElement{ longitude: "85"; latitude: "5"; height: "115"; }
+ ListElement{ longitude: "85"; latitude: "6"; height: "119"; }
+ ListElement{ longitude: "85"; latitude: "7"; height: "122"; }
+ ListElement{ longitude: "85"; latitude: "8"; height: "128"; }
+ ListElement{ longitude: "85"; latitude: "9"; height: "117"; }
+ ListElement{ longitude: "85"; latitude: "10"; height: "126"; }
+ ListElement{ longitude: "85"; latitude: "11"; height: "124"; }
+ ListElement{ longitude: "85"; latitude: "12"; height: "116"; }
+ ListElement{ longitude: "85"; latitude: "13"; height: "108"; }
+ ListElement{ longitude: "85"; latitude: "14"; height: "103"; }
+ ListElement{ longitude: "85"; latitude: "15"; height: "98"; }
+ ListElement{ longitude: "85"; latitude: "16"; height: "98"; }
+ ListElement{ longitude: "85"; latitude: "17"; height: "98"; }
+ ListElement{ longitude: "85"; latitude: "18"; height: "99"; }
+ ListElement{ longitude: "85"; latitude: "19"; height: "101"; }
+ ListElement{ longitude: "85"; latitude: "20"; height: "101"; }
+ ListElement{ longitude: "85"; latitude: "21"; height: "107"; }
+ ListElement{ longitude: "85"; latitude: "22"; height: "111"; }
+ ListElement{ longitude: "85"; latitude: "23"; height: "117"; }
+ ListElement{ longitude: "85"; latitude: "24"; height: "120"; }
+ ListElement{ longitude: "85"; latitude: "25"; height: "122"; }
+ ListElement{ longitude: "85"; latitude: "26"; height: "122"; }
+ ListElement{ longitude: "85"; latitude: "27"; height: "121"; }
+ ListElement{ longitude: "85"; latitude: "28"; height: "118"; }
+ ListElement{ longitude: "85"; latitude: "29"; height: "113"; }
+ ListElement{ longitude: "85"; latitude: "30"; height: "110"; }
+ ListElement{ longitude: "85"; latitude: "31"; height: "106"; }
+ ListElement{ longitude: "85"; latitude: "32"; height: "103"; }
+ ListElement{ longitude: "85"; latitude: "33"; height: "101"; }
+ ListElement{ longitude: "85"; latitude: "34"; height: "98"; }
+ ListElement{ longitude: "85"; latitude: "35"; height: "100"; }
+ ListElement{ longitude: "85"; latitude: "36"; height: "102"; }
+ ListElement{ longitude: "85"; latitude: "37"; height: "106"; }
+ ListElement{ longitude: "85"; latitude: "38"; height: "110"; }
+ ListElement{ longitude: "85"; latitude: "39"; height: "115"; }
+ ListElement{ longitude: "85"; latitude: "40"; height: "121"; }
+ ListElement{ longitude: "85"; latitude: "41"; height: "121"; }
+ ListElement{ longitude: "85"; latitude: "42"; height: "122"; }
+ ListElement{ longitude: "85"; latitude: "43"; height: "122"; }
+ ListElement{ longitude: "85"; latitude: "44"; height: "123"; }
+ ListElement{ longitude: "85"; latitude: "45"; height: "127"; }
+ ListElement{ longitude: "85"; latitude: "46"; height: "127"; }
+ ListElement{ longitude: "85"; latitude: "47"; height: "130"; }
+ ListElement{ longitude: "85"; latitude: "48"; height: "129"; }
+ ListElement{ longitude: "85"; latitude: "49"; height: "131"; }
+ ListElement{ longitude: "85"; latitude: "50"; height: "129"; }
+ ListElement{ longitude: "85"; latitude: "51"; height: "129"; }
+ ListElement{ longitude: "85"; latitude: "52"; height: "130"; }
+ ListElement{ longitude: "85"; latitude: "53"; height: "131"; }
+ ListElement{ longitude: "85"; latitude: "54"; height: "134"; }
+ ListElement{ longitude: "85"; latitude: "55"; height: "134"; }
+ ListElement{ longitude: "85"; latitude: "56"; height: "137"; }
+ ListElement{ longitude: "85"; latitude: "57"; height: "137"; }
+ ListElement{ longitude: "85"; latitude: "58"; height: "134"; }
+ ListElement{ longitude: "85"; latitude: "59"; height: "133"; }
+ ListElement{ longitude: "85"; latitude: "60"; height: "133"; }
+ ListElement{ longitude: "85"; latitude: "61"; height: "130"; }
+ ListElement{ longitude: "85"; latitude: "62"; height: "130"; }
+ ListElement{ longitude: "85"; latitude: "63"; height: "129"; }
+ ListElement{ longitude: "85"; latitude: "64"; height: "130"; }
+ ListElement{ longitude: "85"; latitude: "65"; height: "131"; }
+ ListElement{ longitude: "85"; latitude: "66"; height: "129"; }
+ ListElement{ longitude: "85"; latitude: "67"; height: "127"; }
+ ListElement{ longitude: "85"; latitude: "68"; height: "128"; }
+ ListElement{ longitude: "85"; latitude: "69"; height: "125"; }
+ ListElement{ longitude: "85"; latitude: "70"; height: "124"; }
+ ListElement{ longitude: "85"; latitude: "71"; height: "123"; }
+ ListElement{ longitude: "85"; latitude: "72"; height: "124"; }
+ ListElement{ longitude: "85"; latitude: "73"; height: "127"; }
+ ListElement{ longitude: "85"; latitude: "74"; height: "132"; }
+ ListElement{ longitude: "85"; latitude: "75"; height: "126"; }
+ ListElement{ longitude: "85"; latitude: "76"; height: "115"; }
+ ListElement{ longitude: "85"; latitude: "77"; height: "113"; }
+ ListElement{ longitude: "85"; latitude: "78"; height: "122"; }
+ ListElement{ longitude: "85"; latitude: "79"; height: "130"; }
+ ListElement{ longitude: "85"; latitude: "80"; height: "137"; }
+ ListElement{ longitude: "85"; latitude: "81"; height: "146"; }
+ ListElement{ longitude: "85"; latitude: "82"; height: "152"; }
+ ListElement{ longitude: "85"; latitude: "83"; height: "154"; }
+ ListElement{ longitude: "85"; latitude: "84"; height: "149"; }
+ ListElement{ longitude: "85"; latitude: "85"; height: "148"; }
+ ListElement{ longitude: "85"; latitude: "86"; height: "141"; }
+ ListElement{ longitude: "85"; latitude: "87"; height: "137"; }
+ ListElement{ longitude: "85"; latitude: "88"; height: "133"; }
+ ListElement{ longitude: "85"; latitude: "89"; height: "131"; }
+ ListElement{ longitude: "85"; latitude: "90"; height: "124"; }
+ ListElement{ longitude: "85"; latitude: "91"; height: "122"; }
+ ListElement{ longitude: "85"; latitude: "92"; height: "120"; }
+ ListElement{ longitude: "85"; latitude: "93"; height: "120"; }
+ ListElement{ longitude: "85"; latitude: "94"; height: "116"; }
+ ListElement{ longitude: "85"; latitude: "95"; height: "112"; }
+ ListElement{ longitude: "85"; latitude: "96"; height: "115"; }
+ ListElement{ longitude: "85"; latitude: "97"; height: "116"; }
+ ListElement{ longitude: "85"; latitude: "98"; height: "123"; }
+ ListElement{ longitude: "85"; latitude: "99"; height: "119"; }
+ ListElement{ longitude: "86"; latitude: "0"; height: "112"; }
+ ListElement{ longitude: "86"; latitude: "1"; height: "110"; }
+ ListElement{ longitude: "86"; latitude: "2"; height: "106"; }
+ ListElement{ longitude: "86"; latitude: "3"; height: "108"; }
+ ListElement{ longitude: "86"; latitude: "4"; height: "110"; }
+ ListElement{ longitude: "86"; latitude: "5"; height: "113"; }
+ ListElement{ longitude: "86"; latitude: "6"; height: "116"; }
+ ListElement{ longitude: "86"; latitude: "7"; height: "119"; }
+ ListElement{ longitude: "86"; latitude: "8"; height: "122"; }
+ ListElement{ longitude: "86"; latitude: "9"; height: "124"; }
+ ListElement{ longitude: "86"; latitude: "10"; height: "123"; }
+ ListElement{ longitude: "86"; latitude: "11"; height: "119"; }
+ ListElement{ longitude: "86"; latitude: "12"; height: "113"; }
+ ListElement{ longitude: "86"; latitude: "13"; height: "107"; }
+ ListElement{ longitude: "86"; latitude: "14"; height: "103"; }
+ ListElement{ longitude: "86"; latitude: "15"; height: "100"; }
+ ListElement{ longitude: "86"; latitude: "16"; height: "98"; }
+ ListElement{ longitude: "86"; latitude: "17"; height: "99"; }
+ ListElement{ longitude: "86"; latitude: "18"; height: "101"; }
+ ListElement{ longitude: "86"; latitude: "19"; height: "103"; }
+ ListElement{ longitude: "86"; latitude: "20"; height: "108"; }
+ ListElement{ longitude: "86"; latitude: "21"; height: "113"; }
+ ListElement{ longitude: "86"; latitude: "22"; height: "120"; }
+ ListElement{ longitude: "86"; latitude: "23"; height: "124"; }
+ ListElement{ longitude: "86"; latitude: "24"; height: "126"; }
+ ListElement{ longitude: "86"; latitude: "25"; height: "126"; }
+ ListElement{ longitude: "86"; latitude: "26"; height: "125"; }
+ ListElement{ longitude: "86"; latitude: "27"; height: "122"; }
+ ListElement{ longitude: "86"; latitude: "28"; height: "121"; }
+ ListElement{ longitude: "86"; latitude: "29"; height: "116"; }
+ ListElement{ longitude: "86"; latitude: "30"; height: "113"; }
+ ListElement{ longitude: "86"; latitude: "31"; height: "110"; }
+ ListElement{ longitude: "86"; latitude: "32"; height: "107"; }
+ ListElement{ longitude: "86"; latitude: "33"; height: "104"; }
+ ListElement{ longitude: "86"; latitude: "34"; height: "101"; }
+ ListElement{ longitude: "86"; latitude: "35"; height: "103"; }
+ ListElement{ longitude: "86"; latitude: "36"; height: "105"; }
+ ListElement{ longitude: "86"; latitude: "37"; height: "111"; }
+ ListElement{ longitude: "86"; latitude: "38"; height: "115"; }
+ ListElement{ longitude: "86"; latitude: "39"; height: "120"; }
+ ListElement{ longitude: "86"; latitude: "40"; height: "125"; }
+ ListElement{ longitude: "86"; latitude: "41"; height: "125"; }
+ ListElement{ longitude: "86"; latitude: "42"; height: "128"; }
+ ListElement{ longitude: "86"; latitude: "43"; height: "129"; }
+ ListElement{ longitude: "86"; latitude: "44"; height: "127"; }
+ ListElement{ longitude: "86"; latitude: "45"; height: "130"; }
+ ListElement{ longitude: "86"; latitude: "46"; height: "130"; }
+ ListElement{ longitude: "86"; latitude: "47"; height: "133"; }
+ ListElement{ longitude: "86"; latitude: "48"; height: "133"; }
+ ListElement{ longitude: "86"; latitude: "49"; height: "131"; }
+ ListElement{ longitude: "86"; latitude: "50"; height: "130"; }
+ ListElement{ longitude: "86"; latitude: "51"; height: "130"; }
+ ListElement{ longitude: "86"; latitude: "52"; height: "133"; }
+ ListElement{ longitude: "86"; latitude: "53"; height: "135"; }
+ ListElement{ longitude: "86"; latitude: "54"; height: "138"; }
+ ListElement{ longitude: "86"; latitude: "55"; height: "135"; }
+ ListElement{ longitude: "86"; latitude: "56"; height: "138"; }
+ ListElement{ longitude: "86"; latitude: "57"; height: "136"; }
+ ListElement{ longitude: "86"; latitude: "58"; height: "137"; }
+ ListElement{ longitude: "86"; latitude: "59"; height: "134"; }
+ ListElement{ longitude: "86"; latitude: "60"; height: "135"; }
+ ListElement{ longitude: "86"; latitude: "61"; height: "134"; }
+ ListElement{ longitude: "86"; latitude: "62"; height: "135"; }
+ ListElement{ longitude: "86"; latitude: "63"; height: "134"; }
+ ListElement{ longitude: "86"; latitude: "64"; height: "131"; }
+ ListElement{ longitude: "86"; latitude: "65"; height: "131"; }
+ ListElement{ longitude: "86"; latitude: "66"; height: "129"; }
+ ListElement{ longitude: "86"; latitude: "67"; height: "129"; }
+ ListElement{ longitude: "86"; latitude: "68"; height: "129"; }
+ ListElement{ longitude: "86"; latitude: "69"; height: "130"; }
+ ListElement{ longitude: "86"; latitude: "70"; height: "129"; }
+ ListElement{ longitude: "86"; latitude: "71"; height: "127"; }
+ ListElement{ longitude: "86"; latitude: "72"; height: "128"; }
+ ListElement{ longitude: "86"; latitude: "73"; height: "126"; }
+ ListElement{ longitude: "86"; latitude: "74"; height: "127"; }
+ ListElement{ longitude: "86"; latitude: "75"; height: "128"; }
+ ListElement{ longitude: "86"; latitude: "76"; height: "127"; }
+ ListElement{ longitude: "86"; latitude: "77"; height: "126"; }
+ ListElement{ longitude: "86"; latitude: "78"; height: "126"; }
+ ListElement{ longitude: "86"; latitude: "79"; height: "128"; }
+ ListElement{ longitude: "86"; latitude: "80"; height: "137"; }
+ ListElement{ longitude: "86"; latitude: "81"; height: "143"; }
+ ListElement{ longitude: "86"; latitude: "82"; height: "150"; }
+ ListElement{ longitude: "86"; latitude: "83"; height: "151"; }
+ ListElement{ longitude: "86"; latitude: "84"; height: "153"; }
+ ListElement{ longitude: "86"; latitude: "85"; height: "151"; }
+ ListElement{ longitude: "86"; latitude: "86"; height: "147"; }
+ ListElement{ longitude: "86"; latitude: "87"; height: "144"; }
+ ListElement{ longitude: "86"; latitude: "88"; height: "141"; }
+ ListElement{ longitude: "86"; latitude: "89"; height: "137"; }
+ ListElement{ longitude: "86"; latitude: "90"; height: "132"; }
+ ListElement{ longitude: "86"; latitude: "91"; height: "125"; }
+ ListElement{ longitude: "86"; latitude: "92"; height: "119"; }
+ ListElement{ longitude: "86"; latitude: "93"; height: "117"; }
+ ListElement{ longitude: "86"; latitude: "94"; height: "115"; }
+ ListElement{ longitude: "86"; latitude: "95"; height: "112"; }
+ ListElement{ longitude: "86"; latitude: "96"; height: "117"; }
+ ListElement{ longitude: "86"; latitude: "97"; height: "117"; }
+ ListElement{ longitude: "86"; latitude: "98"; height: "126"; }
+ ListElement{ longitude: "86"; latitude: "99"; height: "120"; }
+ ListElement{ longitude: "87"; latitude: "0"; height: "110"; }
+ ListElement{ longitude: "87"; latitude: "1"; height: "108"; }
+ ListElement{ longitude: "87"; latitude: "2"; height: "102"; }
+ ListElement{ longitude: "87"; latitude: "3"; height: "102"; }
+ ListElement{ longitude: "87"; latitude: "4"; height: "107"; }
+ ListElement{ longitude: "87"; latitude: "5"; height: "106"; }
+ ListElement{ longitude: "87"; latitude: "6"; height: "110"; }
+ ListElement{ longitude: "87"; latitude: "7"; height: "116"; }
+ ListElement{ longitude: "87"; latitude: "8"; height: "114"; }
+ ListElement{ longitude: "87"; latitude: "9"; height: "116"; }
+ ListElement{ longitude: "87"; latitude: "10"; height: "115"; }
+ ListElement{ longitude: "87"; latitude: "11"; height: "111"; }
+ ListElement{ longitude: "87"; latitude: "12"; height: "109"; }
+ ListElement{ longitude: "87"; latitude: "13"; height: "106"; }
+ ListElement{ longitude: "87"; latitude: "14"; height: "103"; }
+ ListElement{ longitude: "87"; latitude: "15"; height: "100"; }
+ ListElement{ longitude: "87"; latitude: "16"; height: "98"; }
+ ListElement{ longitude: "87"; latitude: "17"; height: "101"; }
+ ListElement{ longitude: "87"; latitude: "18"; height: "103"; }
+ ListElement{ longitude: "87"; latitude: "19"; height: "107"; }
+ ListElement{ longitude: "87"; latitude: "20"; height: "114"; }
+ ListElement{ longitude: "87"; latitude: "21"; height: "121"; }
+ ListElement{ longitude: "87"; latitude: "22"; height: "129"; }
+ ListElement{ longitude: "87"; latitude: "23"; height: "134"; }
+ ListElement{ longitude: "87"; latitude: "24"; height: "131"; }
+ ListElement{ longitude: "87"; latitude: "25"; height: "130"; }
+ ListElement{ longitude: "87"; latitude: "26"; height: "128"; }
+ ListElement{ longitude: "87"; latitude: "27"; height: "126"; }
+ ListElement{ longitude: "87"; latitude: "28"; height: "125"; }
+ ListElement{ longitude: "87"; latitude: "29"; height: "121"; }
+ ListElement{ longitude: "87"; latitude: "30"; height: "120"; }
+ ListElement{ longitude: "87"; latitude: "31"; height: "117"; }
+ ListElement{ longitude: "87"; latitude: "32"; height: "112"; }
+ ListElement{ longitude: "87"; latitude: "33"; height: "109"; }
+ ListElement{ longitude: "87"; latitude: "34"; height: "106"; }
+ ListElement{ longitude: "87"; latitude: "35"; height: "108"; }
+ ListElement{ longitude: "87"; latitude: "36"; height: "109"; }
+ ListElement{ longitude: "87"; latitude: "37"; height: "114"; }
+ ListElement{ longitude: "87"; latitude: "38"; height: "118"; }
+ ListElement{ longitude: "87"; latitude: "39"; height: "122"; }
+ ListElement{ longitude: "87"; latitude: "40"; height: "127"; }
+ ListElement{ longitude: "87"; latitude: "41"; height: "127"; }
+ ListElement{ longitude: "87"; latitude: "42"; height: "127"; }
+ ListElement{ longitude: "87"; latitude: "43"; height: "130"; }
+ ListElement{ longitude: "87"; latitude: "44"; height: "131"; }
+ ListElement{ longitude: "87"; latitude: "45"; height: "133"; }
+ ListElement{ longitude: "87"; latitude: "46"; height: "135"; }
+ ListElement{ longitude: "87"; latitude: "47"; height: "137"; }
+ ListElement{ longitude: "87"; latitude: "48"; height: "135"; }
+ ListElement{ longitude: "87"; latitude: "49"; height: "132"; }
+ ListElement{ longitude: "87"; latitude: "50"; height: "134"; }
+ ListElement{ longitude: "87"; latitude: "51"; height: "134"; }
+ ListElement{ longitude: "87"; latitude: "52"; height: "133"; }
+ ListElement{ longitude: "87"; latitude: "53"; height: "135"; }
+ ListElement{ longitude: "87"; latitude: "54"; height: "138"; }
+ ListElement{ longitude: "87"; latitude: "55"; height: "137"; }
+ ListElement{ longitude: "87"; latitude: "56"; height: "139"; }
+ ListElement{ longitude: "87"; latitude: "57"; height: "137"; }
+ ListElement{ longitude: "87"; latitude: "58"; height: "138"; }
+ ListElement{ longitude: "87"; latitude: "59"; height: "135"; }
+ ListElement{ longitude: "87"; latitude: "60"; height: "134"; }
+ ListElement{ longitude: "87"; latitude: "61"; height: "135"; }
+ ListElement{ longitude: "87"; latitude: "62"; height: "135"; }
+ ListElement{ longitude: "87"; latitude: "63"; height: "133"; }
+ ListElement{ longitude: "87"; latitude: "64"; height: "127"; }
+ ListElement{ longitude: "87"; latitude: "65"; height: "131"; }
+ ListElement{ longitude: "87"; latitude: "66"; height: "134"; }
+ ListElement{ longitude: "87"; latitude: "67"; height: "133"; }
+ ListElement{ longitude: "87"; latitude: "68"; height: "133"; }
+ ListElement{ longitude: "87"; latitude: "69"; height: "133"; }
+ ListElement{ longitude: "87"; latitude: "70"; height: "133"; }
+ ListElement{ longitude: "87"; latitude: "71"; height: "132"; }
+ ListElement{ longitude: "87"; latitude: "72"; height: "130"; }
+ ListElement{ longitude: "87"; latitude: "73"; height: "127"; }
+ ListElement{ longitude: "87"; latitude: "74"; height: "126"; }
+ ListElement{ longitude: "87"; latitude: "75"; height: "125"; }
+ ListElement{ longitude: "87"; latitude: "76"; height: "126"; }
+ ListElement{ longitude: "87"; latitude: "77"; height: "126"; }
+ ListElement{ longitude: "87"; latitude: "78"; height: "125"; }
+ ListElement{ longitude: "87"; latitude: "79"; height: "128"; }
+ ListElement{ longitude: "87"; latitude: "80"; height: "133"; }
+ ListElement{ longitude: "87"; latitude: "81"; height: "140"; }
+ ListElement{ longitude: "87"; latitude: "82"; height: "147"; }
+ ListElement{ longitude: "87"; latitude: "83"; height: "151"; }
+ ListElement{ longitude: "87"; latitude: "84"; height: "153"; }
+ ListElement{ longitude: "87"; latitude: "85"; height: "152"; }
+ ListElement{ longitude: "87"; latitude: "86"; height: "151"; }
+ ListElement{ longitude: "87"; latitude: "87"; height: "149"; }
+ ListElement{ longitude: "87"; latitude: "88"; height: "147"; }
+ ListElement{ longitude: "87"; latitude: "89"; height: "143"; }
+ ListElement{ longitude: "87"; latitude: "90"; height: "136"; }
+ ListElement{ longitude: "87"; latitude: "91"; height: "128"; }
+ ListElement{ longitude: "87"; latitude: "92"; height: "124"; }
+ ListElement{ longitude: "87"; latitude: "93"; height: "118"; }
+ ListElement{ longitude: "87"; latitude: "94"; height: "113"; }
+ ListElement{ longitude: "87"; latitude: "95"; height: "113"; }
+ ListElement{ longitude: "87"; latitude: "96"; height: "116"; }
+ ListElement{ longitude: "87"; latitude: "97"; height: "118"; }
+ ListElement{ longitude: "87"; latitude: "98"; height: "122"; }
+ ListElement{ longitude: "87"; latitude: "99"; height: "117"; }
+ ListElement{ longitude: "88"; latitude: "0"; height: "108"; }
+ ListElement{ longitude: "88"; latitude: "1"; height: "105"; }
+ ListElement{ longitude: "88"; latitude: "2"; height: "101"; }
+ ListElement{ longitude: "88"; latitude: "3"; height: "101"; }
+ ListElement{ longitude: "88"; latitude: "4"; height: "103"; }
+ ListElement{ longitude: "88"; latitude: "5"; height: "107"; }
+ ListElement{ longitude: "88"; latitude: "6"; height: "107"; }
+ ListElement{ longitude: "88"; latitude: "7"; height: "112"; }
+ ListElement{ longitude: "88"; latitude: "8"; height: "105"; }
+ ListElement{ longitude: "88"; latitude: "9"; height: "113"; }
+ ListElement{ longitude: "88"; latitude: "10"; height: "109"; }
+ ListElement{ longitude: "88"; latitude: "11"; height: "106"; }
+ ListElement{ longitude: "88"; latitude: "12"; height: "110"; }
+ ListElement{ longitude: "88"; latitude: "13"; height: "105"; }
+ ListElement{ longitude: "88"; latitude: "14"; height: "103"; }
+ ListElement{ longitude: "88"; latitude: "15"; height: "102"; }
+ ListElement{ longitude: "88"; latitude: "16"; height: "101"; }
+ ListElement{ longitude: "88"; latitude: "17"; height: "102"; }
+ ListElement{ longitude: "88"; latitude: "18"; height: "106"; }
+ ListElement{ longitude: "88"; latitude: "19"; height: "112"; }
+ ListElement{ longitude: "88"; latitude: "20"; height: "117"; }
+ ListElement{ longitude: "88"; latitude: "21"; height: "126"; }
+ ListElement{ longitude: "88"; latitude: "22"; height: "134"; }
+ ListElement{ longitude: "88"; latitude: "23"; height: "139"; }
+ ListElement{ longitude: "88"; latitude: "24"; height: "137"; }
+ ListElement{ longitude: "88"; latitude: "25"; height: "133"; }
+ ListElement{ longitude: "88"; latitude: "26"; height: "129"; }
+ ListElement{ longitude: "88"; latitude: "27"; height: "128"; }
+ ListElement{ longitude: "88"; latitude: "28"; height: "119"; }
+ ListElement{ longitude: "88"; latitude: "29"; height: "123"; }
+ ListElement{ longitude: "88"; latitude: "30"; height: "121"; }
+ ListElement{ longitude: "88"; latitude: "31"; height: "116"; }
+ ListElement{ longitude: "88"; latitude: "32"; height: "114"; }
+ ListElement{ longitude: "88"; latitude: "33"; height: "110"; }
+ ListElement{ longitude: "88"; latitude: "34"; height: "108"; }
+ ListElement{ longitude: "88"; latitude: "35"; height: "109"; }
+ ListElement{ longitude: "88"; latitude: "36"; height: "111"; }
+ ListElement{ longitude: "88"; latitude: "37"; height: "116"; }
+ ListElement{ longitude: "88"; latitude: "38"; height: "120"; }
+ ListElement{ longitude: "88"; latitude: "39"; height: "123"; }
+ ListElement{ longitude: "88"; latitude: "40"; height: "126"; }
+ ListElement{ longitude: "88"; latitude: "41"; height: "128"; }
+ ListElement{ longitude: "88"; latitude: "42"; height: "130"; }
+ ListElement{ longitude: "88"; latitude: "43"; height: "131"; }
+ ListElement{ longitude: "88"; latitude: "44"; height: "133"; }
+ ListElement{ longitude: "88"; latitude: "45"; height: "135"; }
+ ListElement{ longitude: "88"; latitude: "46"; height: "137"; }
+ ListElement{ longitude: "88"; latitude: "47"; height: "137"; }
+ ListElement{ longitude: "88"; latitude: "48"; height: "134"; }
+ ListElement{ longitude: "88"; latitude: "49"; height: "133"; }
+ ListElement{ longitude: "88"; latitude: "50"; height: "133"; }
+ ListElement{ longitude: "88"; latitude: "51"; height: "133"; }
+ ListElement{ longitude: "88"; latitude: "52"; height: "136"; }
+ ListElement{ longitude: "88"; latitude: "53"; height: "137"; }
+ ListElement{ longitude: "88"; latitude: "54"; height: "140"; }
+ ListElement{ longitude: "88"; latitude: "55"; height: "139"; }
+ ListElement{ longitude: "88"; latitude: "56"; height: "139"; }
+ ListElement{ longitude: "88"; latitude: "57"; height: "139"; }
+ ListElement{ longitude: "88"; latitude: "58"; height: "138"; }
+ ListElement{ longitude: "88"; latitude: "59"; height: "135"; }
+ ListElement{ longitude: "88"; latitude: "60"; height: "134"; }
+ ListElement{ longitude: "88"; latitude: "61"; height: "137"; }
+ ListElement{ longitude: "88"; latitude: "62"; height: "138"; }
+ ListElement{ longitude: "88"; latitude: "63"; height: "130"; }
+ ListElement{ longitude: "88"; latitude: "64"; height: "122"; }
+ ListElement{ longitude: "88"; latitude: "65"; height: "126"; }
+ ListElement{ longitude: "88"; latitude: "66"; height: "136"; }
+ ListElement{ longitude: "88"; latitude: "67"; height: "132"; }
+ ListElement{ longitude: "88"; latitude: "68"; height: "136"; }
+ ListElement{ longitude: "88"; latitude: "69"; height: "135"; }
+ ListElement{ longitude: "88"; latitude: "70"; height: "136"; }
+ ListElement{ longitude: "88"; latitude: "71"; height: "133"; }
+ ListElement{ longitude: "88"; latitude: "72"; height: "130"; }
+ ListElement{ longitude: "88"; latitude: "73"; height: "128"; }
+ ListElement{ longitude: "88"; latitude: "74"; height: "128"; }
+ ListElement{ longitude: "88"; latitude: "75"; height: "125"; }
+ ListElement{ longitude: "88"; latitude: "76"; height: "125"; }
+ ListElement{ longitude: "88"; latitude: "77"; height: "125"; }
+ ListElement{ longitude: "88"; latitude: "78"; height: "126"; }
+ ListElement{ longitude: "88"; latitude: "79"; height: "128"; }
+ ListElement{ longitude: "88"; latitude: "80"; height: "131"; }
+ ListElement{ longitude: "88"; latitude: "81"; height: "136"; }
+ ListElement{ longitude: "88"; latitude: "82"; height: "142"; }
+ ListElement{ longitude: "88"; latitude: "83"; height: "146"; }
+ ListElement{ longitude: "88"; latitude: "84"; height: "150"; }
+ ListElement{ longitude: "88"; latitude: "85"; height: "149"; }
+ ListElement{ longitude: "88"; latitude: "86"; height: "149"; }
+ ListElement{ longitude: "88"; latitude: "87"; height: "150"; }
+ ListElement{ longitude: "88"; latitude: "88"; height: "148"; }
+ ListElement{ longitude: "88"; latitude: "89"; height: "147"; }
+ ListElement{ longitude: "88"; latitude: "90"; height: "140"; }
+ ListElement{ longitude: "88"; latitude: "91"; height: "130"; }
+ ListElement{ longitude: "88"; latitude: "92"; height: "124"; }
+ ListElement{ longitude: "88"; latitude: "93"; height: "118"; }
+ ListElement{ longitude: "88"; latitude: "94"; height: "116"; }
+ ListElement{ longitude: "88"; latitude: "95"; height: "117"; }
+ ListElement{ longitude: "88"; latitude: "96"; height: "119"; }
+ ListElement{ longitude: "88"; latitude: "97"; height: "119"; }
+ ListElement{ longitude: "88"; latitude: "98"; height: "125"; }
+ ListElement{ longitude: "88"; latitude: "99"; height: "113"; }
+ ListElement{ longitude: "89"; latitude: "0"; height: "106"; }
+ ListElement{ longitude: "89"; latitude: "1"; height: "101"; }
+ ListElement{ longitude: "89"; latitude: "2"; height: "97"; }
+ ListElement{ longitude: "89"; latitude: "3"; height: "99"; }
+ ListElement{ longitude: "89"; latitude: "4"; height: "101"; }
+ ListElement{ longitude: "89"; latitude: "5"; height: "104"; }
+ ListElement{ longitude: "89"; latitude: "6"; height: "104"; }
+ ListElement{ longitude: "89"; latitude: "7"; height: "108"; }
+ ListElement{ longitude: "89"; latitude: "8"; height: "101"; }
+ ListElement{ longitude: "89"; latitude: "9"; height: "108"; }
+ ListElement{ longitude: "89"; latitude: "10"; height: "108"; }
+ ListElement{ longitude: "89"; latitude: "11"; height: "107"; }
+ ListElement{ longitude: "89"; latitude: "12"; height: "105"; }
+ ListElement{ longitude: "89"; latitude: "13"; height: "106"; }
+ ListElement{ longitude: "89"; latitude: "14"; height: "106"; }
+ ListElement{ longitude: "89"; latitude: "15"; height: "103"; }
+ ListElement{ longitude: "89"; latitude: "16"; height: "103"; }
+ ListElement{ longitude: "89"; latitude: "17"; height: "105"; }
+ ListElement{ longitude: "89"; latitude: "18"; height: "108"; }
+ ListElement{ longitude: "89"; latitude: "19"; height: "113"; }
+ ListElement{ longitude: "89"; latitude: "20"; height: "123"; }
+ ListElement{ longitude: "89"; latitude: "21"; height: "130"; }
+ ListElement{ longitude: "89"; latitude: "22"; height: "137"; }
+ ListElement{ longitude: "89"; latitude: "23"; height: "140"; }
+ ListElement{ longitude: "89"; latitude: "24"; height: "139"; }
+ ListElement{ longitude: "89"; latitude: "25"; height: "137"; }
+ ListElement{ longitude: "89"; latitude: "26"; height: "131"; }
+ ListElement{ longitude: "89"; latitude: "27"; height: "130"; }
+ ListElement{ longitude: "89"; latitude: "28"; height: "123"; }
+ ListElement{ longitude: "89"; latitude: "29"; height: "125"; }
+ ListElement{ longitude: "89"; latitude: "30"; height: "125"; }
+ ListElement{ longitude: "89"; latitude: "31"; height: "119"; }
+ ListElement{ longitude: "89"; latitude: "32"; height: "115"; }
+ ListElement{ longitude: "89"; latitude: "33"; height: "112"; }
+ ListElement{ longitude: "89"; latitude: "34"; height: "111"; }
+ ListElement{ longitude: "89"; latitude: "35"; height: "112"; }
+ ListElement{ longitude: "89"; latitude: "36"; height: "114"; }
+ ListElement{ longitude: "89"; latitude: "37"; height: "117"; }
+ ListElement{ longitude: "89"; latitude: "38"; height: "119"; }
+ ListElement{ longitude: "89"; latitude: "39"; height: "122"; }
+ ListElement{ longitude: "89"; latitude: "40"; height: "125"; }
+ ListElement{ longitude: "89"; latitude: "41"; height: "128"; }
+ ListElement{ longitude: "89"; latitude: "42"; height: "130"; }
+ ListElement{ longitude: "89"; latitude: "43"; height: "130"; }
+ ListElement{ longitude: "89"; latitude: "44"; height: "134"; }
+ ListElement{ longitude: "89"; latitude: "45"; height: "136"; }
+ ListElement{ longitude: "89"; latitude: "46"; height: "137"; }
+ ListElement{ longitude: "89"; latitude: "47"; height: "138"; }
+ ListElement{ longitude: "89"; latitude: "48"; height: "137"; }
+ ListElement{ longitude: "89"; latitude: "49"; height: "135"; }
+ ListElement{ longitude: "89"; latitude: "50"; height: "136"; }
+ ListElement{ longitude: "89"; latitude: "51"; height: "136"; }
+ ListElement{ longitude: "89"; latitude: "52"; height: "135"; }
+ ListElement{ longitude: "89"; latitude: "53"; height: "136"; }
+ ListElement{ longitude: "89"; latitude: "54"; height: "138"; }
+ ListElement{ longitude: "89"; latitude: "55"; height: "139"; }
+ ListElement{ longitude: "89"; latitude: "56"; height: "139"; }
+ ListElement{ longitude: "89"; latitude: "57"; height: "139"; }
+ ListElement{ longitude: "89"; latitude: "58"; height: "138"; }
+ ListElement{ longitude: "89"; latitude: "59"; height: "136"; }
+ ListElement{ longitude: "89"; latitude: "60"; height: "134"; }
+ ListElement{ longitude: "89"; latitude: "61"; height: "133"; }
+ ListElement{ longitude: "89"; latitude: "62"; height: "134"; }
+ ListElement{ longitude: "89"; latitude: "63"; height: "131"; }
+ ListElement{ longitude: "89"; latitude: "64"; height: "127"; }
+ ListElement{ longitude: "89"; latitude: "65"; height: "130"; }
+ ListElement{ longitude: "89"; latitude: "66"; height: "133"; }
+ ListElement{ longitude: "89"; latitude: "67"; height: "132"; }
+ ListElement{ longitude: "89"; latitude: "68"; height: "135"; }
+ ListElement{ longitude: "89"; latitude: "69"; height: "134"; }
+ ListElement{ longitude: "89"; latitude: "70"; height: "136"; }
+ ListElement{ longitude: "89"; latitude: "71"; height: "136"; }
+ ListElement{ longitude: "89"; latitude: "72"; height: "133"; }
+ ListElement{ longitude: "89"; latitude: "73"; height: "131"; }
+ ListElement{ longitude: "89"; latitude: "74"; height: "130"; }
+ ListElement{ longitude: "89"; latitude: "75"; height: "126"; }
+ ListElement{ longitude: "89"; latitude: "76"; height: "125"; }
+ ListElement{ longitude: "89"; latitude: "77"; height: "125"; }
+ ListElement{ longitude: "89"; latitude: "78"; height: "126"; }
+ ListElement{ longitude: "89"; latitude: "79"; height: "128"; }
+ ListElement{ longitude: "89"; latitude: "80"; height: "130"; }
+ ListElement{ longitude: "89"; latitude: "81"; height: "133"; }
+ ListElement{ longitude: "89"; latitude: "82"; height: "137"; }
+ ListElement{ longitude: "89"; latitude: "83"; height: "140"; }
+ ListElement{ longitude: "89"; latitude: "84"; height: "143"; }
+ ListElement{ longitude: "89"; latitude: "85"; height: "146"; }
+ ListElement{ longitude: "89"; latitude: "86"; height: "146"; }
+ ListElement{ longitude: "89"; latitude: "87"; height: "146"; }
+ ListElement{ longitude: "89"; latitude: "88"; height: "147"; }
+ ListElement{ longitude: "89"; latitude: "89"; height: "145"; }
+ ListElement{ longitude: "89"; latitude: "90"; height: "140"; }
+ ListElement{ longitude: "89"; latitude: "91"; height: "133"; }
+ ListElement{ longitude: "89"; latitude: "92"; height: "128"; }
+ ListElement{ longitude: "89"; latitude: "93"; height: "123"; }
+ ListElement{ longitude: "89"; latitude: "94"; height: "123"; }
+ ListElement{ longitude: "89"; latitude: "95"; height: "114"; }
+ ListElement{ longitude: "89"; latitude: "96"; height: "120"; }
+ ListElement{ longitude: "89"; latitude: "97"; height: "117"; }
+ ListElement{ longitude: "89"; latitude: "98"; height: "119"; }
+ ListElement{ longitude: "89"; latitude: "99"; height: "107"; }
+ ListElement{ longitude: "90"; latitude: "0"; height: "102"; }
+ ListElement{ longitude: "90"; latitude: "1"; height: "99"; }
+ ListElement{ longitude: "90"; latitude: "2"; height: "98"; }
+ ListElement{ longitude: "90"; latitude: "3"; height: "99"; }
+ ListElement{ longitude: "90"; latitude: "4"; height: "102"; }
+ ListElement{ longitude: "90"; latitude: "5"; height: "101"; }
+ ListElement{ longitude: "90"; latitude: "6"; height: "101"; }
+ ListElement{ longitude: "90"; latitude: "7"; height: "103"; }
+ ListElement{ longitude: "90"; latitude: "8"; height: "106"; }
+ ListElement{ longitude: "90"; latitude: "9"; height: "105"; }
+ ListElement{ longitude: "90"; latitude: "10"; height: "103"; }
+ ListElement{ longitude: "90"; latitude: "11"; height: "103"; }
+ ListElement{ longitude: "90"; latitude: "12"; height: "103"; }
+ ListElement{ longitude: "90"; latitude: "13"; height: "104"; }
+ ListElement{ longitude: "90"; latitude: "14"; height: "108"; }
+ ListElement{ longitude: "90"; latitude: "15"; height: "107"; }
+ ListElement{ longitude: "90"; latitude: "16"; height: "108"; }
+ ListElement{ longitude: "90"; latitude: "17"; height: "109"; }
+ ListElement{ longitude: "90"; latitude: "18"; height: "112"; }
+ ListElement{ longitude: "90"; latitude: "19"; height: "119"; }
+ ListElement{ longitude: "90"; latitude: "20"; height: "122"; }
+ ListElement{ longitude: "90"; latitude: "21"; height: "127"; }
+ ListElement{ longitude: "90"; latitude: "22"; height: "133"; }
+ ListElement{ longitude: "90"; latitude: "23"; height: "136"; }
+ ListElement{ longitude: "90"; latitude: "24"; height: "136"; }
+ ListElement{ longitude: "90"; latitude: "25"; height: "137"; }
+ ListElement{ longitude: "90"; latitude: "26"; height: "134"; }
+ ListElement{ longitude: "90"; latitude: "27"; height: "130"; }
+ ListElement{ longitude: "90"; latitude: "28"; height: "131"; }
+ ListElement{ longitude: "90"; latitude: "29"; height: "127"; }
+ ListElement{ longitude: "90"; latitude: "30"; height: "123"; }
+ ListElement{ longitude: "90"; latitude: "31"; height: "117"; }
+ ListElement{ longitude: "90"; latitude: "32"; height: "113"; }
+ ListElement{ longitude: "90"; latitude: "33"; height: "110"; }
+ ListElement{ longitude: "90"; latitude: "34"; height: "110"; }
+ ListElement{ longitude: "90"; latitude: "35"; height: "111"; }
+ ListElement{ longitude: "90"; latitude: "36"; height: "113"; }
+ ListElement{ longitude: "90"; latitude: "37"; height: "116"; }
+ ListElement{ longitude: "90"; latitude: "38"; height: "117"; }
+ ListElement{ longitude: "90"; latitude: "39"; height: "119"; }
+ ListElement{ longitude: "90"; latitude: "40"; height: "122"; }
+ ListElement{ longitude: "90"; latitude: "41"; height: "125"; }
+ ListElement{ longitude: "90"; latitude: "42"; height: "129"; }
+ ListElement{ longitude: "90"; latitude: "43"; height: "131"; }
+ ListElement{ longitude: "90"; latitude: "44"; height: "133"; }
+ ListElement{ longitude: "90"; latitude: "45"; height: "136"; }
+ ListElement{ longitude: "90"; latitude: "46"; height: "137"; }
+ ListElement{ longitude: "90"; latitude: "47"; height: "139"; }
+ ListElement{ longitude: "90"; latitude: "48"; height: "139"; }
+ ListElement{ longitude: "90"; latitude: "49"; height: "138"; }
+ ListElement{ longitude: "90"; latitude: "50"; height: "136"; }
+ ListElement{ longitude: "90"; latitude: "51"; height: "137"; }
+ ListElement{ longitude: "90"; latitude: "52"; height: "137"; }
+ ListElement{ longitude: "90"; latitude: "53"; height: "137"; }
+ ListElement{ longitude: "90"; latitude: "54"; height: "136"; }
+ ListElement{ longitude: "90"; latitude: "55"; height: "138"; }
+ ListElement{ longitude: "90"; latitude: "56"; height: "139"; }
+ ListElement{ longitude: "90"; latitude: "57"; height: "139"; }
+ ListElement{ longitude: "90"; latitude: "58"; height: "138"; }
+ ListElement{ longitude: "90"; latitude: "59"; height: "134"; }
+ ListElement{ longitude: "90"; latitude: "60"; height: "130"; }
+ ListElement{ longitude: "90"; latitude: "61"; height: "129"; }
+ ListElement{ longitude: "90"; latitude: "62"; height: "128"; }
+ ListElement{ longitude: "90"; latitude: "63"; height: "128"; }
+ ListElement{ longitude: "90"; latitude: "64"; height: "128"; }
+ ListElement{ longitude: "90"; latitude: "65"; height: "128"; }
+ ListElement{ longitude: "90"; latitude: "66"; height: "129"; }
+ ListElement{ longitude: "90"; latitude: "67"; height: "129"; }
+ ListElement{ longitude: "90"; latitude: "68"; height: "130"; }
+ ListElement{ longitude: "90"; latitude: "69"; height: "131"; }
+ ListElement{ longitude: "90"; latitude: "70"; height: "133"; }
+ ListElement{ longitude: "90"; latitude: "71"; height: "135"; }
+ ListElement{ longitude: "90"; latitude: "72"; height: "135"; }
+ ListElement{ longitude: "90"; latitude: "73"; height: "132"; }
+ ListElement{ longitude: "90"; latitude: "74"; height: "130"; }
+ ListElement{ longitude: "90"; latitude: "75"; height: "128"; }
+ ListElement{ longitude: "90"; latitude: "76"; height: "125"; }
+ ListElement{ longitude: "90"; latitude: "77"; height: "127"; }
+ ListElement{ longitude: "90"; latitude: "78"; height: "126"; }
+ ListElement{ longitude: "90"; latitude: "79"; height: "128"; }
+ ListElement{ longitude: "90"; latitude: "80"; height: "130"; }
+ ListElement{ longitude: "90"; latitude: "81"; height: "132"; }
+ ListElement{ longitude: "90"; latitude: "82"; height: "135"; }
+ ListElement{ longitude: "90"; latitude: "83"; height: "138"; }
+ ListElement{ longitude: "90"; latitude: "84"; height: "140"; }
+ ListElement{ longitude: "90"; latitude: "85"; height: "141"; }
+ ListElement{ longitude: "90"; latitude: "86"; height: "143"; }
+ ListElement{ longitude: "90"; latitude: "87"; height: "143"; }
+ ListElement{ longitude: "90"; latitude: "88"; height: "142"; }
+ ListElement{ longitude: "90"; latitude: "89"; height: "140"; }
+ ListElement{ longitude: "90"; latitude: "90"; height: "137"; }
+ ListElement{ longitude: "90"; latitude: "91"; height: "131"; }
+ ListElement{ longitude: "90"; latitude: "92"; height: "127"; }
+ ListElement{ longitude: "90"; latitude: "93"; height: "129"; }
+ ListElement{ longitude: "90"; latitude: "94"; height: "112"; }
+ ListElement{ longitude: "90"; latitude: "95"; height: "86"; }
+ ListElement{ longitude: "90"; latitude: "96"; height: "103"; }
+ ListElement{ longitude: "90"; latitude: "97"; height: "110"; }
+ ListElement{ longitude: "90"; latitude: "98"; height: "108"; }
+ ListElement{ longitude: "90"; latitude: "99"; height: "99"; }
+ ListElement{ longitude: "91"; latitude: "0"; height: "97"; }
+ ListElement{ longitude: "91"; latitude: "1"; height: "97"; }
+ ListElement{ longitude: "91"; latitude: "2"; height: "100"; }
+ ListElement{ longitude: "91"; latitude: "3"; height: "101"; }
+ ListElement{ longitude: "91"; latitude: "4"; height: "102"; }
+ ListElement{ longitude: "91"; latitude: "5"; height: "101"; }
+ ListElement{ longitude: "91"; latitude: "6"; height: "99"; }
+ ListElement{ longitude: "91"; latitude: "7"; height: "99"; }
+ ListElement{ longitude: "91"; latitude: "8"; height: "99"; }
+ ListElement{ longitude: "91"; latitude: "9"; height: "101"; }
+ ListElement{ longitude: "91"; latitude: "10"; height: "100"; }
+ ListElement{ longitude: "91"; latitude: "11"; height: "102"; }
+ ListElement{ longitude: "91"; latitude: "12"; height: "101"; }
+ ListElement{ longitude: "91"; latitude: "13"; height: "104"; }
+ ListElement{ longitude: "91"; latitude: "14"; height: "106"; }
+ ListElement{ longitude: "91"; latitude: "15"; height: "109"; }
+ ListElement{ longitude: "91"; latitude: "16"; height: "109"; }
+ ListElement{ longitude: "91"; latitude: "17"; height: "112"; }
+ ListElement{ longitude: "91"; latitude: "18"; height: "111"; }
+ ListElement{ longitude: "91"; latitude: "19"; height: "116"; }
+ ListElement{ longitude: "91"; latitude: "20"; height: "120"; }
+ ListElement{ longitude: "91"; latitude: "21"; height: "122"; }
+ ListElement{ longitude: "91"; latitude: "22"; height: "127"; }
+ ListElement{ longitude: "91"; latitude: "23"; height: "130"; }
+ ListElement{ longitude: "91"; latitude: "24"; height: "133"; }
+ ListElement{ longitude: "91"; latitude: "25"; height: "132"; }
+ ListElement{ longitude: "91"; latitude: "26"; height: "134"; }
+ ListElement{ longitude: "91"; latitude: "27"; height: "133"; }
+ ListElement{ longitude: "91"; latitude: "28"; height: "132"; }
+ ListElement{ longitude: "91"; latitude: "29"; height: "129"; }
+ ListElement{ longitude: "91"; latitude: "30"; height: "122"; }
+ ListElement{ longitude: "91"; latitude: "31"; height: "116"; }
+ ListElement{ longitude: "91"; latitude: "32"; height: "112"; }
+ ListElement{ longitude: "91"; latitude: "33"; height: "110"; }
+ ListElement{ longitude: "91"; latitude: "34"; height: "109"; }
+ ListElement{ longitude: "91"; latitude: "35"; height: "112"; }
+ ListElement{ longitude: "91"; latitude: "36"; height: "113"; }
+ ListElement{ longitude: "91"; latitude: "37"; height: "114"; }
+ ListElement{ longitude: "91"; latitude: "38"; height: "116"; }
+ ListElement{ longitude: "91"; latitude: "39"; height: "118"; }
+ ListElement{ longitude: "91"; latitude: "40"; height: "121"; }
+ ListElement{ longitude: "91"; latitude: "41"; height: "126"; }
+ ListElement{ longitude: "91"; latitude: "42"; height: "128"; }
+ ListElement{ longitude: "91"; latitude: "43"; height: "128"; }
+ ListElement{ longitude: "91"; latitude: "44"; height: "130"; }
+ ListElement{ longitude: "91"; latitude: "45"; height: "134"; }
+ ListElement{ longitude: "91"; latitude: "46"; height: "138"; }
+ ListElement{ longitude: "91"; latitude: "47"; height: "140"; }
+ ListElement{ longitude: "91"; latitude: "48"; height: "141"; }
+ ListElement{ longitude: "91"; latitude: "49"; height: "141"; }
+ ListElement{ longitude: "91"; latitude: "50"; height: "137"; }
+ ListElement{ longitude: "91"; latitude: "51"; height: "138"; }
+ ListElement{ longitude: "91"; latitude: "52"; height: "136"; }
+ ListElement{ longitude: "91"; latitude: "53"; height: "137"; }
+ ListElement{ longitude: "91"; latitude: "54"; height: "137"; }
+ ListElement{ longitude: "91"; latitude: "55"; height: "137"; }
+ ListElement{ longitude: "91"; latitude: "56"; height: "133"; }
+ ListElement{ longitude: "91"; latitude: "57"; height: "125"; }
+ ListElement{ longitude: "91"; latitude: "58"; height: "132"; }
+ ListElement{ longitude: "91"; latitude: "59"; height: "132"; }
+ ListElement{ longitude: "91"; latitude: "60"; height: "129"; }
+ ListElement{ longitude: "91"; latitude: "61"; height: "129"; }
+ ListElement{ longitude: "91"; latitude: "62"; height: "127"; }
+ ListElement{ longitude: "91"; latitude: "63"; height: "125"; }
+ ListElement{ longitude: "91"; latitude: "64"; height: "122"; }
+ ListElement{ longitude: "91"; latitude: "65"; height: "122"; }
+ ListElement{ longitude: "91"; latitude: "66"; height: "123"; }
+ ListElement{ longitude: "91"; latitude: "67"; height: "124"; }
+ ListElement{ longitude: "91"; latitude: "68"; height: "125"; }
+ ListElement{ longitude: "91"; latitude: "69"; height: "126"; }
+ ListElement{ longitude: "91"; latitude: "70"; height: "129"; }
+ ListElement{ longitude: "91"; latitude: "71"; height: "129"; }
+ ListElement{ longitude: "91"; latitude: "72"; height: "131"; }
+ ListElement{ longitude: "91"; latitude: "73"; height: "131"; }
+ ListElement{ longitude: "91"; latitude: "74"; height: "130"; }
+ ListElement{ longitude: "91"; latitude: "75"; height: "128"; }
+ ListElement{ longitude: "91"; latitude: "76"; height: "126"; }
+ ListElement{ longitude: "91"; latitude: "77"; height: "128"; }
+ ListElement{ longitude: "91"; latitude: "78"; height: "127"; }
+ ListElement{ longitude: "91"; latitude: "79"; height: "128"; }
+ ListElement{ longitude: "91"; latitude: "80"; height: "130"; }
+ ListElement{ longitude: "91"; latitude: "81"; height: "132"; }
+ ListElement{ longitude: "91"; latitude: "82"; height: "136"; }
+ ListElement{ longitude: "91"; latitude: "83"; height: "138"; }
+ ListElement{ longitude: "91"; latitude: "84"; height: "139"; }
+ ListElement{ longitude: "91"; latitude: "85"; height: "140"; }
+ ListElement{ longitude: "91"; latitude: "86"; height: "141"; }
+ ListElement{ longitude: "91"; latitude: "87"; height: "138"; }
+ ListElement{ longitude: "91"; latitude: "88"; height: "137"; }
+ ListElement{ longitude: "91"; latitude: "89"; height: "137"; }
+ ListElement{ longitude: "91"; latitude: "90"; height: "134"; }
+ ListElement{ longitude: "91"; latitude: "91"; height: "132"; }
+ ListElement{ longitude: "91"; latitude: "92"; height: "130"; }
+ ListElement{ longitude: "91"; latitude: "93"; height: "131"; }
+ ListElement{ longitude: "91"; latitude: "94"; height: "120"; }
+ ListElement{ longitude: "91"; latitude: "95"; height: "95"; }
+ ListElement{ longitude: "91"; latitude: "96"; height: "105"; }
+ ListElement{ longitude: "91"; latitude: "97"; height: "106"; }
+ ListElement{ longitude: "91"; latitude: "98"; height: "97"; }
+ ListElement{ longitude: "91"; latitude: "99"; height: "91"; }
+ ListElement{ longitude: "92"; latitude: "0"; height: "96"; }
+ ListElement{ longitude: "92"; latitude: "1"; height: "97"; }
+ ListElement{ longitude: "92"; latitude: "2"; height: "101"; }
+ ListElement{ longitude: "92"; latitude: "3"; height: "102"; }
+ ListElement{ longitude: "92"; latitude: "4"; height: "102"; }
+ ListElement{ longitude: "92"; latitude: "5"; height: "99"; }
+ ListElement{ longitude: "92"; latitude: "6"; height: "95"; }
+ ListElement{ longitude: "92"; latitude: "7"; height: "98"; }
+ ListElement{ longitude: "92"; latitude: "8"; height: "96"; }
+ ListElement{ longitude: "92"; latitude: "9"; height: "98"; }
+ ListElement{ longitude: "92"; latitude: "10"; height: "97"; }
+ ListElement{ longitude: "92"; latitude: "11"; height: "99"; }
+ ListElement{ longitude: "92"; latitude: "12"; height: "99"; }
+ ListElement{ longitude: "92"; latitude: "13"; height: "102"; }
+ ListElement{ longitude: "92"; latitude: "14"; height: "102"; }
+ ListElement{ longitude: "92"; latitude: "15"; height: "105"; }
+ ListElement{ longitude: "92"; latitude: "16"; height: "107"; }
+ ListElement{ longitude: "92"; latitude: "17"; height: "108"; }
+ ListElement{ longitude: "92"; latitude: "18"; height: "109"; }
+ ListElement{ longitude: "92"; latitude: "19"; height: "112"; }
+ ListElement{ longitude: "92"; latitude: "20"; height: "115"; }
+ ListElement{ longitude: "92"; latitude: "21"; height: "118"; }
+ ListElement{ longitude: "92"; latitude: "22"; height: "121"; }
+ ListElement{ longitude: "92"; latitude: "23"; height: "126"; }
+ ListElement{ longitude: "92"; latitude: "24"; height: "129"; }
+ ListElement{ longitude: "92"; latitude: "25"; height: "131"; }
+ ListElement{ longitude: "92"; latitude: "26"; height: "133"; }
+ ListElement{ longitude: "92"; latitude: "27"; height: "134"; }
+ ListElement{ longitude: "92"; latitude: "28"; height: "130"; }
+ ListElement{ longitude: "92"; latitude: "29"; height: "126"; }
+ ListElement{ longitude: "92"; latitude: "30"; height: "121"; }
+ ListElement{ longitude: "92"; latitude: "31"; height: "113"; }
+ ListElement{ longitude: "92"; latitude: "32"; height: "110"; }
+ ListElement{ longitude: "92"; latitude: "33"; height: "113"; }
+ ListElement{ longitude: "92"; latitude: "34"; height: "112"; }
+ ListElement{ longitude: "92"; latitude: "35"; height: "115"; }
+ ListElement{ longitude: "92"; latitude: "36"; height: "116"; }
+ ListElement{ longitude: "92"; latitude: "37"; height: "115"; }
+ ListElement{ longitude: "92"; latitude: "38"; height: "116"; }
+ ListElement{ longitude: "92"; latitude: "39"; height: "118"; }
+ ListElement{ longitude: "92"; latitude: "40"; height: "121"; }
+ ListElement{ longitude: "92"; latitude: "41"; height: "126"; }
+ ListElement{ longitude: "92"; latitude: "42"; height: "127"; }
+ ListElement{ longitude: "92"; latitude: "43"; height: "128"; }
+ ListElement{ longitude: "92"; latitude: "44"; height: "128"; }
+ ListElement{ longitude: "92"; latitude: "45"; height: "131"; }
+ ListElement{ longitude: "92"; latitude: "46"; height: "135"; }
+ ListElement{ longitude: "92"; latitude: "47"; height: "130"; }
+ ListElement{ longitude: "92"; latitude: "48"; height: "129"; }
+ ListElement{ longitude: "92"; latitude: "49"; height: "141"; }
+ ListElement{ longitude: "92"; latitude: "50"; height: "140"; }
+ ListElement{ longitude: "92"; latitude: "51"; height: "139"; }
+ ListElement{ longitude: "92"; latitude: "52"; height: "136"; }
+ ListElement{ longitude: "92"; latitude: "53"; height: "136"; }
+ ListElement{ longitude: "92"; latitude: "54"; height: "136"; }
+ ListElement{ longitude: "92"; latitude: "55"; height: "136"; }
+ ListElement{ longitude: "92"; latitude: "56"; height: "129"; }
+ ListElement{ longitude: "92"; latitude: "57"; height: "121"; }
+ ListElement{ longitude: "92"; latitude: "58"; height: "128"; }
+ ListElement{ longitude: "92"; latitude: "59"; height: "131"; }
+ ListElement{ longitude: "92"; latitude: "60"; height: "129"; }
+ ListElement{ longitude: "92"; latitude: "61"; height: "127"; }
+ ListElement{ longitude: "92"; latitude: "62"; height: "123"; }
+ ListElement{ longitude: "92"; latitude: "63"; height: "119"; }
+ ListElement{ longitude: "92"; latitude: "64"; height: "117"; }
+ ListElement{ longitude: "92"; latitude: "65"; height: "117"; }
+ ListElement{ longitude: "92"; latitude: "66"; height: "118"; }
+ ListElement{ longitude: "92"; latitude: "67"; height: "121"; }
+ ListElement{ longitude: "92"; latitude: "68"; height: "122"; }
+ ListElement{ longitude: "92"; latitude: "69"; height: "121"; }
+ ListElement{ longitude: "92"; latitude: "70"; height: "124"; }
+ ListElement{ longitude: "92"; latitude: "71"; height: "125"; }
+ ListElement{ longitude: "92"; latitude: "72"; height: "130"; }
+ ListElement{ longitude: "92"; latitude: "73"; height: "129"; }
+ ListElement{ longitude: "92"; latitude: "74"; height: "128"; }
+ ListElement{ longitude: "92"; latitude: "75"; height: "125"; }
+ ListElement{ longitude: "92"; latitude: "76"; height: "125"; }
+ ListElement{ longitude: "92"; latitude: "77"; height: "128"; }
+ ListElement{ longitude: "92"; latitude: "78"; height: "128"; }
+ ListElement{ longitude: "92"; latitude: "79"; height: "131"; }
+ ListElement{ longitude: "92"; latitude: "80"; height: "130"; }
+ ListElement{ longitude: "92"; latitude: "81"; height: "132"; }
+ ListElement{ longitude: "92"; latitude: "82"; height: "136"; }
+ ListElement{ longitude: "92"; latitude: "83"; height: "134"; }
+ ListElement{ longitude: "92"; latitude: "84"; height: "131"; }
+ ListElement{ longitude: "92"; latitude: "85"; height: "137"; }
+ ListElement{ longitude: "92"; latitude: "86"; height: "142"; }
+ ListElement{ longitude: "92"; latitude: "87"; height: "137"; }
+ ListElement{ longitude: "92"; latitude: "88"; height: "136"; }
+ ListElement{ longitude: "92"; latitude: "89"; height: "133"; }
+ ListElement{ longitude: "92"; latitude: "90"; height: "129"; }
+ ListElement{ longitude: "92"; latitude: "91"; height: "130"; }
+ ListElement{ longitude: "92"; latitude: "92"; height: "132"; }
+ ListElement{ longitude: "92"; latitude: "93"; height: "124"; }
+ ListElement{ longitude: "92"; latitude: "94"; height: "119"; }
+ ListElement{ longitude: "92"; latitude: "95"; height: "114"; }
+ ListElement{ longitude: "92"; latitude: "96"; height: "109"; }
+ ListElement{ longitude: "92"; latitude: "97"; height: "109"; }
+ ListElement{ longitude: "92"; latitude: "98"; height: "96"; }
+ ListElement{ longitude: "92"; latitude: "99"; height: "87"; }
+ ListElement{ longitude: "93"; latitude: "0"; height: "96"; }
+ ListElement{ longitude: "93"; latitude: "1"; height: "100"; }
+ ListElement{ longitude: "93"; latitude: "2"; height: "103"; }
+ ListElement{ longitude: "93"; latitude: "3"; height: "105"; }
+ ListElement{ longitude: "93"; latitude: "4"; height: "105"; }
+ ListElement{ longitude: "93"; latitude: "5"; height: "96"; }
+ ListElement{ longitude: "93"; latitude: "6"; height: "97"; }
+ ListElement{ longitude: "93"; latitude: "7"; height: "97"; }
+ ListElement{ longitude: "93"; latitude: "8"; height: "93"; }
+ ListElement{ longitude: "93"; latitude: "9"; height: "94"; }
+ ListElement{ longitude: "93"; latitude: "10"; height: "94"; }
+ ListElement{ longitude: "93"; latitude: "11"; height: "95"; }
+ ListElement{ longitude: "93"; latitude: "12"; height: "98"; }
+ ListElement{ longitude: "93"; latitude: "13"; height: "99"; }
+ ListElement{ longitude: "93"; latitude: "14"; height: "99"; }
+ ListElement{ longitude: "93"; latitude: "15"; height: "102"; }
+ ListElement{ longitude: "93"; latitude: "16"; height: "100"; }
+ ListElement{ longitude: "93"; latitude: "17"; height: "104"; }
+ ListElement{ longitude: "93"; latitude: "18"; height: "107"; }
+ ListElement{ longitude: "93"; latitude: "19"; height: "110"; }
+ ListElement{ longitude: "93"; latitude: "20"; height: "113"; }
+ ListElement{ longitude: "93"; latitude: "21"; height: "118"; }
+ ListElement{ longitude: "93"; latitude: "22"; height: "119"; }
+ ListElement{ longitude: "93"; latitude: "23"; height: "121"; }
+ ListElement{ longitude: "93"; latitude: "24"; height: "124"; }
+ ListElement{ longitude: "93"; latitude: "25"; height: "129"; }
+ ListElement{ longitude: "93"; latitude: "26"; height: "132"; }
+ ListElement{ longitude: "93"; latitude: "27"; height: "132"; }
+ ListElement{ longitude: "93"; latitude: "28"; height: "128"; }
+ ListElement{ longitude: "93"; latitude: "29"; height: "125"; }
+ ListElement{ longitude: "93"; latitude: "30"; height: "120"; }
+ ListElement{ longitude: "93"; latitude: "31"; height: "113"; }
+ ListElement{ longitude: "93"; latitude: "32"; height: "111"; }
+ ListElement{ longitude: "93"; latitude: "33"; height: "114"; }
+ ListElement{ longitude: "93"; latitude: "34"; height: "117"; }
+ ListElement{ longitude: "93"; latitude: "35"; height: "117"; }
+ ListElement{ longitude: "93"; latitude: "36"; height: "118"; }
+ ListElement{ longitude: "93"; latitude: "37"; height: "117"; }
+ ListElement{ longitude: "93"; latitude: "38"; height: "117"; }
+ ListElement{ longitude: "93"; latitude: "39"; height: "119"; }
+ ListElement{ longitude: "93"; latitude: "40"; height: "123"; }
+ ListElement{ longitude: "93"; latitude: "41"; height: "125"; }
+ ListElement{ longitude: "93"; latitude: "42"; height: "126"; }
+ ListElement{ longitude: "93"; latitude: "43"; height: "126"; }
+ ListElement{ longitude: "93"; latitude: "44"; height: "126"; }
+ ListElement{ longitude: "93"; latitude: "45"; height: "129"; }
+ ListElement{ longitude: "93"; latitude: "46"; height: "134"; }
+ ListElement{ longitude: "93"; latitude: "47"; height: "129"; }
+ ListElement{ longitude: "93"; latitude: "48"; height: "132"; }
+ ListElement{ longitude: "93"; latitude: "49"; height: "142"; }
+ ListElement{ longitude: "93"; latitude: "50"; height: "140"; }
+ ListElement{ longitude: "93"; latitude: "51"; height: "137"; }
+ ListElement{ longitude: "93"; latitude: "52"; height: "138"; }
+ ListElement{ longitude: "93"; latitude: "53"; height: "137"; }
+ ListElement{ longitude: "93"; latitude: "54"; height: "138"; }
+ ListElement{ longitude: "93"; latitude: "55"; height: "138"; }
+ ListElement{ longitude: "93"; latitude: "56"; height: "137"; }
+ ListElement{ longitude: "93"; latitude: "57"; height: "131"; }
+ ListElement{ longitude: "93"; latitude: "58"; height: "132"; }
+ ListElement{ longitude: "93"; latitude: "59"; height: "129"; }
+ ListElement{ longitude: "93"; latitude: "60"; height: "128"; }
+ ListElement{ longitude: "93"; latitude: "61"; height: "125"; }
+ ListElement{ longitude: "93"; latitude: "62"; height: "121"; }
+ ListElement{ longitude: "93"; latitude: "63"; height: "119"; }
+ ListElement{ longitude: "93"; latitude: "64"; height: "117"; }
+ ListElement{ longitude: "93"; latitude: "65"; height: "117"; }
+ ListElement{ longitude: "93"; latitude: "66"; height: "120"; }
+ ListElement{ longitude: "93"; latitude: "67"; height: "123"; }
+ ListElement{ longitude: "93"; latitude: "68"; height: "122"; }
+ ListElement{ longitude: "93"; latitude: "69"; height: "122"; }
+ ListElement{ longitude: "93"; latitude: "70"; height: "122"; }
+ ListElement{ longitude: "93"; latitude: "71"; height: "123"; }
+ ListElement{ longitude: "93"; latitude: "72"; height: "124"; }
+ ListElement{ longitude: "93"; latitude: "73"; height: "124"; }
+ ListElement{ longitude: "93"; latitude: "74"; height: "126"; }
+ ListElement{ longitude: "93"; latitude: "75"; height: "124"; }
+ ListElement{ longitude: "93"; latitude: "76"; height: "126"; }
+ ListElement{ longitude: "93"; latitude: "77"; height: "128"; }
+ ListElement{ longitude: "93"; latitude: "78"; height: "130"; }
+ ListElement{ longitude: "93"; latitude: "79"; height: "132"; }
+ ListElement{ longitude: "93"; latitude: "80"; height: "133"; }
+ ListElement{ longitude: "93"; latitude: "81"; height: "133"; }
+ ListElement{ longitude: "93"; latitude: "82"; height: "138"; }
+ ListElement{ longitude: "93"; latitude: "83"; height: "135"; }
+ ListElement{ longitude: "93"; latitude: "84"; height: "130"; }
+ ListElement{ longitude: "93"; latitude: "85"; height: "136"; }
+ ListElement{ longitude: "93"; latitude: "86"; height: "144"; }
+ ListElement{ longitude: "93"; latitude: "87"; height: "139"; }
+ ListElement{ longitude: "93"; latitude: "88"; height: "132"; }
+ ListElement{ longitude: "93"; latitude: "89"; height: "126"; }
+ ListElement{ longitude: "93"; latitude: "90"; height: "126"; }
+ ListElement{ longitude: "93"; latitude: "91"; height: "128"; }
+ ListElement{ longitude: "93"; latitude: "92"; height: "128"; }
+ ListElement{ longitude: "93"; latitude: "93"; height: "118"; }
+ ListElement{ longitude: "93"; latitude: "94"; height: "112"; }
+ ListElement{ longitude: "93"; latitude: "95"; height: "111"; }
+ ListElement{ longitude: "93"; latitude: "96"; height: "110"; }
+ ListElement{ longitude: "93"; latitude: "97"; height: "109"; }
+ ListElement{ longitude: "93"; latitude: "98"; height: "98"; }
+ ListElement{ longitude: "93"; latitude: "99"; height: "85"; }
+ ListElement{ longitude: "94"; latitude: "0"; height: "91"; }
+ ListElement{ longitude: "94"; latitude: "1"; height: "93"; }
+ ListElement{ longitude: "94"; latitude: "2"; height: "98"; }
+ ListElement{ longitude: "94"; latitude: "3"; height: "101"; }
+ ListElement{ longitude: "94"; latitude: "4"; height: "106"; }
+ ListElement{ longitude: "94"; latitude: "5"; height: "106"; }
+ ListElement{ longitude: "94"; latitude: "6"; height: "89"; }
+ ListElement{ longitude: "94"; latitude: "7"; height: "98"; }
+ ListElement{ longitude: "94"; latitude: "8"; height: "95"; }
+ ListElement{ longitude: "94"; latitude: "9"; height: "91"; }
+ ListElement{ longitude: "94"; latitude: "10"; height: "90"; }
+ ListElement{ longitude: "94"; latitude: "11"; height: "92"; }
+ ListElement{ longitude: "94"; latitude: "12"; height: "94"; }
+ ListElement{ longitude: "94"; latitude: "13"; height: "95"; }
+ ListElement{ longitude: "94"; latitude: "14"; height: "98"; }
+ ListElement{ longitude: "94"; latitude: "15"; height: "99"; }
+ ListElement{ longitude: "94"; latitude: "16"; height: "97"; }
+ ListElement{ longitude: "94"; latitude: "17"; height: "101"; }
+ ListElement{ longitude: "94"; latitude: "18"; height: "105"; }
+ ListElement{ longitude: "94"; latitude: "19"; height: "109"; }
+ ListElement{ longitude: "94"; latitude: "20"; height: "113"; }
+ ListElement{ longitude: "94"; latitude: "21"; height: "118"; }
+ ListElement{ longitude: "94"; latitude: "22"; height: "120"; }
+ ListElement{ longitude: "94"; latitude: "23"; height: "120"; }
+ ListElement{ longitude: "94"; latitude: "24"; height: "122"; }
+ ListElement{ longitude: "94"; latitude: "25"; height: "124"; }
+ ListElement{ longitude: "94"; latitude: "26"; height: "128"; }
+ ListElement{ longitude: "94"; latitude: "27"; height: "128"; }
+ ListElement{ longitude: "94"; latitude: "28"; height: "128"; }
+ ListElement{ longitude: "94"; latitude: "29"; height: "121"; }
+ ListElement{ longitude: "94"; latitude: "30"; height: "119"; }
+ ListElement{ longitude: "94"; latitude: "31"; height: "116"; }
+ ListElement{ longitude: "94"; latitude: "32"; height: "114"; }
+ ListElement{ longitude: "94"; latitude: "33"; height: "118"; }
+ ListElement{ longitude: "94"; latitude: "34"; height: "110"; }
+ ListElement{ longitude: "94"; latitude: "35"; height: "113"; }
+ ListElement{ longitude: "94"; latitude: "36"; height: "122"; }
+ ListElement{ longitude: "94"; latitude: "37"; height: "121"; }
+ ListElement{ longitude: "94"; latitude: "38"; height: "121"; }
+ ListElement{ longitude: "94"; latitude: "39"; height: "122"; }
+ ListElement{ longitude: "94"; latitude: "40"; height: "123"; }
+ ListElement{ longitude: "94"; latitude: "41"; height: "122"; }
+ ListElement{ longitude: "94"; latitude: "42"; height: "122"; }
+ ListElement{ longitude: "94"; latitude: "43"; height: "122"; }
+ ListElement{ longitude: "94"; latitude: "44"; height: "124"; }
+ ListElement{ longitude: "94"; latitude: "45"; height: "130"; }
+ ListElement{ longitude: "94"; latitude: "46"; height: "136"; }
+ ListElement{ longitude: "94"; latitude: "47"; height: "141"; }
+ ListElement{ longitude: "94"; latitude: "48"; height: "145"; }
+ ListElement{ longitude: "94"; latitude: "49"; height: "145"; }
+ ListElement{ longitude: "94"; latitude: "50"; height: "136"; }
+ ListElement{ longitude: "94"; latitude: "51"; height: "129"; }
+ ListElement{ longitude: "94"; latitude: "52"; height: "138"; }
+ ListElement{ longitude: "94"; latitude: "53"; height: "140"; }
+ ListElement{ longitude: "94"; latitude: "54"; height: "138"; }
+ ListElement{ longitude: "94"; latitude: "55"; height: "139"; }
+ ListElement{ longitude: "94"; latitude: "56"; height: "131"; }
+ ListElement{ longitude: "94"; latitude: "57"; height: "124"; }
+ ListElement{ longitude: "94"; latitude: "58"; height: "129"; }
+ ListElement{ longitude: "94"; latitude: "59"; height: "125"; }
+ ListElement{ longitude: "94"; latitude: "60"; height: "124"; }
+ ListElement{ longitude: "94"; latitude: "61"; height: "125"; }
+ ListElement{ longitude: "94"; latitude: "62"; height: "126"; }
+ ListElement{ longitude: "94"; latitude: "63"; height: "123"; }
+ ListElement{ longitude: "94"; latitude: "64"; height: "122"; }
+ ListElement{ longitude: "94"; latitude: "65"; height: "121"; }
+ ListElement{ longitude: "94"; latitude: "66"; height: "123"; }
+ ListElement{ longitude: "94"; latitude: "67"; height: "124"; }
+ ListElement{ longitude: "94"; latitude: "68"; height: "125"; }
+ ListElement{ longitude: "94"; latitude: "69"; height: "123"; }
+ ListElement{ longitude: "94"; latitude: "70"; height: "123"; }
+ ListElement{ longitude: "94"; latitude: "71"; height: "121"; }
+ ListElement{ longitude: "94"; latitude: "72"; height: "122"; }
+ ListElement{ longitude: "94"; latitude: "73"; height: "122"; }
+ ListElement{ longitude: "94"; latitude: "74"; height: "122"; }
+ ListElement{ longitude: "94"; latitude: "75"; height: "122"; }
+ ListElement{ longitude: "94"; latitude: "76"; height: "120"; }
+ ListElement{ longitude: "94"; latitude: "77"; height: "128"; }
+ ListElement{ longitude: "94"; latitude: "78"; height: "129"; }
+ ListElement{ longitude: "94"; latitude: "79"; height: "133"; }
+ ListElement{ longitude: "94"; latitude: "80"; height: "134"; }
+ ListElement{ longitude: "94"; latitude: "81"; height: "133"; }
+ ListElement{ longitude: "94"; latitude: "82"; height: "137"; }
+ ListElement{ longitude: "94"; latitude: "83"; height: "137"; }
+ ListElement{ longitude: "94"; latitude: "84"; height: "142"; }
+ ListElement{ longitude: "94"; latitude: "85"; height: "148"; }
+ ListElement{ longitude: "94"; latitude: "86"; height: "146"; }
+ ListElement{ longitude: "94"; latitude: "87"; height: "137"; }
+ ListElement{ longitude: "94"; latitude: "88"; height: "124"; }
+ ListElement{ longitude: "94"; latitude: "89"; height: "117"; }
+ ListElement{ longitude: "94"; latitude: "90"; height: "120"; }
+ ListElement{ longitude: "94"; latitude: "91"; height: "121"; }
+ ListElement{ longitude: "94"; latitude: "92"; height: "122"; }
+ ListElement{ longitude: "94"; latitude: "93"; height: "115"; }
+ ListElement{ longitude: "94"; latitude: "94"; height: "112"; }
+ ListElement{ longitude: "94"; latitude: "95"; height: "115"; }
+ ListElement{ longitude: "94"; latitude: "96"; height: "111"; }
+ ListElement{ longitude: "94"; latitude: "97"; height: "106"; }
+ ListElement{ longitude: "94"; latitude: "98"; height: "94"; }
+ ListElement{ longitude: "94"; latitude: "99"; height: "84"; }
+ ListElement{ longitude: "95"; latitude: "0"; height: "87"; }
+ ListElement{ longitude: "95"; latitude: "1"; height: "89"; }
+ ListElement{ longitude: "95"; latitude: "2"; height: "92"; }
+ ListElement{ longitude: "95"; latitude: "3"; height: "96"; }
+ ListElement{ longitude: "95"; latitude: "4"; height: "100"; }
+ ListElement{ longitude: "95"; latitude: "5"; height: "107"; }
+ ListElement{ longitude: "95"; latitude: "6"; height: "101"; }
+ ListElement{ longitude: "95"; latitude: "7"; height: "102"; }
+ ListElement{ longitude: "95"; latitude: "8"; height: "96"; }
+ ListElement{ longitude: "95"; latitude: "9"; height: "93"; }
+ ListElement{ longitude: "95"; latitude: "10"; height: "91"; }
+ ListElement{ longitude: "95"; latitude: "11"; height: "91"; }
+ ListElement{ longitude: "95"; latitude: "12"; height: "92"; }
+ ListElement{ longitude: "95"; latitude: "13"; height: "93"; }
+ ListElement{ longitude: "95"; latitude: "14"; height: "94"; }
+ ListElement{ longitude: "95"; latitude: "15"; height: "95"; }
+ ListElement{ longitude: "95"; latitude: "16"; height: "99"; }
+ ListElement{ longitude: "95"; latitude: "17"; height: "99"; }
+ ListElement{ longitude: "95"; latitude: "18"; height: "103"; }
+ ListElement{ longitude: "95"; latitude: "19"; height: "111"; }
+ ListElement{ longitude: "95"; latitude: "20"; height: "115"; }
+ ListElement{ longitude: "95"; latitude: "21"; height: "118"; }
+ ListElement{ longitude: "95"; latitude: "22"; height: "122"; }
+ ListElement{ longitude: "95"; latitude: "23"; height: "121"; }
+ ListElement{ longitude: "95"; latitude: "24"; height: "120"; }
+ ListElement{ longitude: "95"; latitude: "25"; height: "121"; }
+ ListElement{ longitude: "95"; latitude: "26"; height: "125"; }
+ ListElement{ longitude: "95"; latitude: "27"; height: "126"; }
+ ListElement{ longitude: "95"; latitude: "28"; height: "126"; }
+ ListElement{ longitude: "95"; latitude: "29"; height: "119"; }
+ ListElement{ longitude: "95"; latitude: "30"; height: "116"; }
+ ListElement{ longitude: "95"; latitude: "31"; height: "111"; }
+ ListElement{ longitude: "95"; latitude: "32"; height: "113"; }
+ ListElement{ longitude: "95"; latitude: "33"; height: "118"; }
+ ListElement{ longitude: "95"; latitude: "34"; height: "110"; }
+ ListElement{ longitude: "95"; latitude: "35"; height: "112"; }
+ ListElement{ longitude: "95"; latitude: "36"; height: "126"; }
+ ListElement{ longitude: "95"; latitude: "37"; height: "125"; }
+ ListElement{ longitude: "95"; latitude: "38"; height: "123"; }
+ ListElement{ longitude: "95"; latitude: "39"; height: "121"; }
+ ListElement{ longitude: "95"; latitude: "40"; height: "123"; }
+ ListElement{ longitude: "95"; latitude: "41"; height: "119"; }
+ ListElement{ longitude: "95"; latitude: "42"; height: "120"; }
+ ListElement{ longitude: "95"; latitude: "43"; height: "120"; }
+ ListElement{ longitude: "95"; latitude: "44"; height: "122"; }
+ ListElement{ longitude: "95"; latitude: "45"; height: "128"; }
+ ListElement{ longitude: "95"; latitude: "46"; height: "132"; }
+ ListElement{ longitude: "95"; latitude: "47"; height: "141"; }
+ ListElement{ longitude: "95"; latitude: "48"; height: "139"; }
+ ListElement{ longitude: "95"; latitude: "49"; height: "136"; }
+ ListElement{ longitude: "95"; latitude: "50"; height: "143"; }
+ ListElement{ longitude: "95"; latitude: "51"; height: "138"; }
+ ListElement{ longitude: "95"; latitude: "52"; height: "145"; }
+ ListElement{ longitude: "95"; latitude: "53"; height: "143"; }
+ ListElement{ longitude: "95"; latitude: "54"; height: "140"; }
+ ListElement{ longitude: "95"; latitude: "55"; height: "140"; }
+ ListElement{ longitude: "95"; latitude: "56"; height: "125"; }
+ ListElement{ longitude: "95"; latitude: "57"; height: "120"; }
+ ListElement{ longitude: "95"; latitude: "58"; height: "128"; }
+ ListElement{ longitude: "95"; latitude: "59"; height: "128"; }
+ ListElement{ longitude: "95"; latitude: "60"; height: "128"; }
+ ListElement{ longitude: "95"; latitude: "61"; height: "126"; }
+ ListElement{ longitude: "95"; latitude: "62"; height: "129"; }
+ ListElement{ longitude: "95"; latitude: "63"; height: "129"; }
+ ListElement{ longitude: "95"; latitude: "64"; height: "129"; }
+ ListElement{ longitude: "95"; latitude: "65"; height: "130"; }
+ ListElement{ longitude: "95"; latitude: "66"; height: "130"; }
+ ListElement{ longitude: "95"; latitude: "67"; height: "127"; }
+ ListElement{ longitude: "95"; latitude: "68"; height: "126"; }
+ ListElement{ longitude: "95"; latitude: "69"; height: "126"; }
+ ListElement{ longitude: "95"; latitude: "70"; height: "129"; }
+ ListElement{ longitude: "95"; latitude: "71"; height: "126"; }
+ ListElement{ longitude: "95"; latitude: "72"; height: "121"; }
+ ListElement{ longitude: "95"; latitude: "73"; height: "122"; }
+ ListElement{ longitude: "95"; latitude: "74"; height: "120"; }
+ ListElement{ longitude: "95"; latitude: "75"; height: "122"; }
+ ListElement{ longitude: "95"; latitude: "76"; height: "124"; }
+ ListElement{ longitude: "95"; latitude: "77"; height: "128"; }
+ ListElement{ longitude: "95"; latitude: "78"; height: "129"; }
+ ListElement{ longitude: "95"; latitude: "79"; height: "133"; }
+ ListElement{ longitude: "95"; latitude: "80"; height: "134"; }
+ ListElement{ longitude: "95"; latitude: "81"; height: "133"; }
+ ListElement{ longitude: "95"; latitude: "82"; height: "137"; }
+ ListElement{ longitude: "95"; latitude: "83"; height: "139"; }
+ ListElement{ longitude: "95"; latitude: "84"; height: "146"; }
+ ListElement{ longitude: "95"; latitude: "85"; height: "146"; }
+ ListElement{ longitude: "95"; latitude: "86"; height: "139"; }
+ ListElement{ longitude: "95"; latitude: "87"; height: "124"; }
+ ListElement{ longitude: "95"; latitude: "88"; height: "112"; }
+ ListElement{ longitude: "95"; latitude: "89"; height: "105"; }
+ ListElement{ longitude: "95"; latitude: "90"; height: "110"; }
+ ListElement{ longitude: "95"; latitude: "91"; height: "116"; }
+ ListElement{ longitude: "95"; latitude: "92"; height: "116"; }
+ ListElement{ longitude: "95"; latitude: "93"; height: "114"; }
+ ListElement{ longitude: "95"; latitude: "94"; height: "112"; }
+ ListElement{ longitude: "95"; latitude: "95"; height: "107"; }
+ ListElement{ longitude: "95"; latitude: "96"; height: "103"; }
+ ListElement{ longitude: "95"; latitude: "97"; height: "101"; }
+ ListElement{ longitude: "95"; latitude: "98"; height: "91"; }
+ ListElement{ longitude: "95"; latitude: "99"; height: "83"; }
+ ListElement{ longitude: "96"; latitude: "0"; height: "87"; }
+ ListElement{ longitude: "96"; latitude: "1"; height: "84"; }
+ ListElement{ longitude: "96"; latitude: "2"; height: "87"; }
+ ListElement{ longitude: "96"; latitude: "3"; height: "91"; }
+ ListElement{ longitude: "96"; latitude: "4"; height: "91"; }
+ ListElement{ longitude: "96"; latitude: "5"; height: "102"; }
+ ListElement{ longitude: "96"; latitude: "6"; height: "107"; }
+ ListElement{ longitude: "96"; latitude: "7"; height: "107"; }
+ ListElement{ longitude: "96"; latitude: "8"; height: "101"; }
+ ListElement{ longitude: "96"; latitude: "9"; height: "95"; }
+ ListElement{ longitude: "96"; latitude: "10"; height: "91"; }
+ ListElement{ longitude: "96"; latitude: "11"; height: "91"; }
+ ListElement{ longitude: "96"; latitude: "12"; height: "92"; }
+ ListElement{ longitude: "96"; latitude: "13"; height: "92"; }
+ ListElement{ longitude: "96"; latitude: "14"; height: "93"; }
+ ListElement{ longitude: "96"; latitude: "15"; height: "96"; }
+ ListElement{ longitude: "96"; latitude: "16"; height: "97"; }
+ ListElement{ longitude: "96"; latitude: "17"; height: "97"; }
+ ListElement{ longitude: "96"; latitude: "18"; height: "93"; }
+ ListElement{ longitude: "96"; latitude: "19"; height: "109"; }
+ ListElement{ longitude: "96"; latitude: "20"; height: "114"; }
+ ListElement{ longitude: "96"; latitude: "21"; height: "119"; }
+ ListElement{ longitude: "96"; latitude: "22"; height: "121"; }
+ ListElement{ longitude: "96"; latitude: "23"; height: "120"; }
+ ListElement{ longitude: "96"; latitude: "24"; height: "120"; }
+ ListElement{ longitude: "96"; latitude: "25"; height: "121"; }
+ ListElement{ longitude: "96"; latitude: "26"; height: "124"; }
+ ListElement{ longitude: "96"; latitude: "27"; height: "125"; }
+ ListElement{ longitude: "96"; latitude: "28"; height: "124"; }
+ ListElement{ longitude: "96"; latitude: "29"; height: "119"; }
+ ListElement{ longitude: "96"; latitude: "30"; height: "117"; }
+ ListElement{ longitude: "96"; latitude: "31"; height: "115"; }
+ ListElement{ longitude: "96"; latitude: "32"; height: "119"; }
+ ListElement{ longitude: "96"; latitude: "33"; height: "123"; }
+ ListElement{ longitude: "96"; latitude: "34"; height: "126"; }
+ ListElement{ longitude: "96"; latitude: "35"; height: "128"; }
+ ListElement{ longitude: "96"; latitude: "36"; height: "128"; }
+ ListElement{ longitude: "96"; latitude: "37"; height: "124"; }
+ ListElement{ longitude: "96"; latitude: "38"; height: "124"; }
+ ListElement{ longitude: "96"; latitude: "39"; height: "124"; }
+ ListElement{ longitude: "96"; latitude: "40"; height: "125"; }
+ ListElement{ longitude: "96"; latitude: "41"; height: "123"; }
+ ListElement{ longitude: "96"; latitude: "42"; height: "122"; }
+ ListElement{ longitude: "96"; latitude: "43"; height: "122"; }
+ ListElement{ longitude: "96"; latitude: "44"; height: "120"; }
+ ListElement{ longitude: "96"; latitude: "45"; height: "125"; }
+ ListElement{ longitude: "96"; latitude: "46"; height: "133"; }
+ ListElement{ longitude: "96"; latitude: "47"; height: "139"; }
+ ListElement{ longitude: "96"; latitude: "48"; height: "134"; }
+ ListElement{ longitude: "96"; latitude: "49"; height: "136"; }
+ ListElement{ longitude: "96"; latitude: "50"; height: "147"; }
+ ListElement{ longitude: "96"; latitude: "51"; height: "149"; }
+ ListElement{ longitude: "96"; latitude: "52"; height: "148"; }
+ ListElement{ longitude: "96"; latitude: "53"; height: "149"; }
+ ListElement{ longitude: "96"; latitude: "54"; height: "146"; }
+ ListElement{ longitude: "96"; latitude: "55"; height: "144"; }
+ ListElement{ longitude: "96"; latitude: "56"; height: "137"; }
+ ListElement{ longitude: "96"; latitude: "57"; height: "133"; }
+ ListElement{ longitude: "96"; latitude: "58"; height: "133"; }
+ ListElement{ longitude: "96"; latitude: "59"; height: "128"; }
+ ListElement{ longitude: "96"; latitude: "60"; height: "128"; }
+ ListElement{ longitude: "96"; latitude: "61"; height: "130"; }
+ ListElement{ longitude: "96"; latitude: "62"; height: "132"; }
+ ListElement{ longitude: "96"; latitude: "63"; height: "132"; }
+ ListElement{ longitude: "96"; latitude: "64"; height: "133"; }
+ ListElement{ longitude: "96"; latitude: "65"; height: "134"; }
+ ListElement{ longitude: "96"; latitude: "66"; height: "136"; }
+ ListElement{ longitude: "96"; latitude: "67"; height: "131"; }
+ ListElement{ longitude: "96"; latitude: "68"; height: "129"; }
+ ListElement{ longitude: "96"; latitude: "69"; height: "130"; }
+ ListElement{ longitude: "96"; latitude: "70"; height: "130"; }
+ ListElement{ longitude: "96"; latitude: "71"; height: "130"; }
+ ListElement{ longitude: "96"; latitude: "72"; height: "123"; }
+ ListElement{ longitude: "96"; latitude: "73"; height: "127"; }
+ ListElement{ longitude: "96"; latitude: "74"; height: "122"; }
+ ListElement{ longitude: "96"; latitude: "75"; height: "124"; }
+ ListElement{ longitude: "96"; latitude: "76"; height: "126"; }
+ ListElement{ longitude: "96"; latitude: "77"; height: "130"; }
+ ListElement{ longitude: "96"; latitude: "78"; height: "132"; }
+ ListElement{ longitude: "96"; latitude: "79"; height: "135"; }
+ ListElement{ longitude: "96"; latitude: "80"; height: "135"; }
+ ListElement{ longitude: "96"; latitude: "81"; height: "132"; }
+ ListElement{ longitude: "96"; latitude: "82"; height: "136"; }
+ ListElement{ longitude: "96"; latitude: "83"; height: "138"; }
+ ListElement{ longitude: "96"; latitude: "84"; height: "144"; }
+ ListElement{ longitude: "96"; latitude: "85"; height: "143"; }
+ ListElement{ longitude: "96"; latitude: "86"; height: "135"; }
+ ListElement{ longitude: "96"; latitude: "87"; height: "122"; }
+ ListElement{ longitude: "96"; latitude: "88"; height: "113"; }
+ ListElement{ longitude: "96"; latitude: "89"; height: "107"; }
+ ListElement{ longitude: "96"; latitude: "90"; height: "106"; }
+ ListElement{ longitude: "96"; latitude: "91"; height: "112"; }
+ ListElement{ longitude: "96"; latitude: "92"; height: "119"; }
+ ListElement{ longitude: "96"; latitude: "93"; height: "117"; }
+ ListElement{ longitude: "96"; latitude: "94"; height: "106"; }
+ ListElement{ longitude: "96"; latitude: "95"; height: "95"; }
+ ListElement{ longitude: "96"; latitude: "96"; height: "87"; }
+ ListElement{ longitude: "96"; latitude: "97"; height: "85"; }
+ ListElement{ longitude: "96"; latitude: "98"; height: "81"; }
+ ListElement{ longitude: "96"; latitude: "99"; height: "75"; }
+ ListElement{ longitude: "97"; latitude: "0"; height: "92"; }
+ ListElement{ longitude: "97"; latitude: "1"; height: "92"; }
+ ListElement{ longitude: "97"; latitude: "2"; height: "90"; }
+ ListElement{ longitude: "97"; latitude: "3"; height: "86"; }
+ ListElement{ longitude: "97"; latitude: "4"; height: "78"; }
+ ListElement{ longitude: "97"; latitude: "5"; height: "86"; }
+ ListElement{ longitude: "97"; latitude: "6"; height: "94"; }
+ ListElement{ longitude: "97"; latitude: "7"; height: "93"; }
+ ListElement{ longitude: "97"; latitude: "8"; height: "92"; }
+ ListElement{ longitude: "97"; latitude: "9"; height: "90"; }
+ ListElement{ longitude: "97"; latitude: "10"; height: "86"; }
+ ListElement{ longitude: "97"; latitude: "11"; height: "86"; }
+ ListElement{ longitude: "97"; latitude: "12"; height: "90"; }
+ ListElement{ longitude: "97"; latitude: "13"; height: "94"; }
+ ListElement{ longitude: "97"; latitude: "14"; height: "95"; }
+ ListElement{ longitude: "97"; latitude: "15"; height: "94"; }
+ ListElement{ longitude: "97"; latitude: "16"; height: "95"; }
+ ListElement{ longitude: "97"; latitude: "17"; height: "99"; }
+ ListElement{ longitude: "97"; latitude: "18"; height: "104"; }
+ ListElement{ longitude: "97"; latitude: "19"; height: "108"; }
+ ListElement{ longitude: "97"; latitude: "20"; height: "115"; }
+ ListElement{ longitude: "97"; latitude: "21"; height: "118"; }
+ ListElement{ longitude: "97"; latitude: "22"; height: "118"; }
+ ListElement{ longitude: "97"; latitude: "23"; height: "118"; }
+ ListElement{ longitude: "97"; latitude: "24"; height: "118"; }
+ ListElement{ longitude: "97"; latitude: "25"; height: "117"; }
+ ListElement{ longitude: "97"; latitude: "26"; height: "117"; }
+ ListElement{ longitude: "97"; latitude: "27"; height: "118"; }
+ ListElement{ longitude: "97"; latitude: "28"; height: "117"; }
+ ListElement{ longitude: "97"; latitude: "29"; height: "116"; }
+ ListElement{ longitude: "97"; latitude: "30"; height: "116"; }
+ ListElement{ longitude: "97"; latitude: "31"; height: "118"; }
+ ListElement{ longitude: "97"; latitude: "32"; height: "122"; }
+ ListElement{ longitude: "97"; latitude: "33"; height: "124"; }
+ ListElement{ longitude: "97"; latitude: "34"; height: "126"; }
+ ListElement{ longitude: "97"; latitude: "35"; height: "125"; }
+ ListElement{ longitude: "97"; latitude: "36"; height: "119"; }
+ ListElement{ longitude: "97"; latitude: "37"; height: "115"; }
+ ListElement{ longitude: "97"; latitude: "38"; height: "117"; }
+ ListElement{ longitude: "97"; latitude: "39"; height: "116"; }
+ ListElement{ longitude: "97"; latitude: "40"; height: "116"; }
+ ListElement{ longitude: "97"; latitude: "41"; height: "114"; }
+ ListElement{ longitude: "97"; latitude: "42"; height: "114"; }
+ ListElement{ longitude: "97"; latitude: "43"; height: "114"; }
+ ListElement{ longitude: "97"; latitude: "44"; height: "114"; }
+ ListElement{ longitude: "97"; latitude: "45"; height: "119"; }
+ ListElement{ longitude: "97"; latitude: "46"; height: "126"; }
+ ListElement{ longitude: "97"; latitude: "47"; height: "132"; }
+ ListElement{ longitude: "97"; latitude: "48"; height: "134"; }
+ ListElement{ longitude: "97"; latitude: "49"; height: "137"; }
+ ListElement{ longitude: "97"; latitude: "50"; height: "141"; }
+ ListElement{ longitude: "97"; latitude: "51"; height: "143"; }
+ ListElement{ longitude: "97"; latitude: "52"; height: "143"; }
+ ListElement{ longitude: "97"; latitude: "53"; height: "143"; }
+ ListElement{ longitude: "97"; latitude: "54"; height: "139"; }
+ ListElement{ longitude: "97"; latitude: "55"; height: "136"; }
+ ListElement{ longitude: "97"; latitude: "56"; height: "132"; }
+ ListElement{ longitude: "97"; latitude: "57"; height: "127"; }
+ ListElement{ longitude: "97"; latitude: "58"; height: "122"; }
+ ListElement{ longitude: "97"; latitude: "59"; height: "117"; }
+ ListElement{ longitude: "97"; latitude: "60"; height: "117"; }
+ ListElement{ longitude: "97"; latitude: "61"; height: "124"; }
+ ListElement{ longitude: "97"; latitude: "62"; height: "130"; }
+ ListElement{ longitude: "97"; latitude: "63"; height: "134"; }
+ ListElement{ longitude: "97"; latitude: "64"; height: "137"; }
+ ListElement{ longitude: "97"; latitude: "65"; height: "139"; }
+ ListElement{ longitude: "97"; latitude: "66"; height: "139"; }
+ ListElement{ longitude: "97"; latitude: "67"; height: "137"; }
+ ListElement{ longitude: "97"; latitude: "68"; height: "133"; }
+ ListElement{ longitude: "97"; latitude: "69"; height: "136"; }
+ ListElement{ longitude: "97"; latitude: "70"; height: "131"; }
+ ListElement{ longitude: "97"; latitude: "71"; height: "130"; }
+ ListElement{ longitude: "97"; latitude: "72"; height: "129"; }
+ ListElement{ longitude: "97"; latitude: "73"; height: "129"; }
+ ListElement{ longitude: "97"; latitude: "74"; height: "126"; }
+ ListElement{ longitude: "97"; latitude: "75"; height: "123"; }
+ ListElement{ longitude: "97"; latitude: "76"; height: "126"; }
+ ListElement{ longitude: "97"; latitude: "77"; height: "127"; }
+ ListElement{ longitude: "97"; latitude: "78"; height: "128"; }
+ ListElement{ longitude: "97"; latitude: "79"; height: "123"; }
+ ListElement{ longitude: "97"; latitude: "80"; height: "123"; }
+ ListElement{ longitude: "97"; latitude: "81"; height: "126"; }
+ ListElement{ longitude: "97"; latitude: "82"; height: "129"; }
+ ListElement{ longitude: "97"; latitude: "83"; height: "137"; }
+ ListElement{ longitude: "97"; latitude: "84"; height: "140"; }
+ ListElement{ longitude: "97"; latitude: "85"; height: "138"; }
+ ListElement{ longitude: "97"; latitude: "86"; height: "132"; }
+ ListElement{ longitude: "97"; latitude: "87"; height: "124"; }
+ ListElement{ longitude: "97"; latitude: "88"; height: "111"; }
+ ListElement{ longitude: "97"; latitude: "89"; height: "102"; }
+ ListElement{ longitude: "97"; latitude: "90"; height: "99"; }
+ ListElement{ longitude: "97"; latitude: "91"; height: "109"; }
+ ListElement{ longitude: "97"; latitude: "92"; height: "110"; }
+ ListElement{ longitude: "97"; latitude: "93"; height: "96"; }
+ ListElement{ longitude: "97"; latitude: "94"; height: "76"; }
+ ListElement{ longitude: "97"; latitude: "95"; height: "68"; }
+ ListElement{ longitude: "97"; latitude: "96"; height: "68"; }
+ ListElement{ longitude: "97"; latitude: "97"; height: "72"; }
+ ListElement{ longitude: "97"; latitude: "98"; height: "70"; }
+ ListElement{ longitude: "97"; latitude: "99"; height: "65"; }
+ ListElement{ longitude: "98"; latitude: "0"; height: "93"; }
+ ListElement{ longitude: "98"; latitude: "1"; height: "90"; }
+ ListElement{ longitude: "98"; latitude: "2"; height: "85"; }
+ ListElement{ longitude: "98"; latitude: "3"; height: "78"; }
+ ListElement{ longitude: "98"; latitude: "4"; height: "74"; }
+ ListElement{ longitude: "98"; latitude: "5"; height: "71"; }
+ ListElement{ longitude: "98"; latitude: "6"; height: "80"; }
+ ListElement{ longitude: "98"; latitude: "7"; height: "78"; }
+ ListElement{ longitude: "98"; latitude: "8"; height: "83"; }
+ ListElement{ longitude: "98"; latitude: "9"; height: "85"; }
+ ListElement{ longitude: "98"; latitude: "10"; height: "81"; }
+ ListElement{ longitude: "98"; latitude: "11"; height: "82"; }
+ ListElement{ longitude: "98"; latitude: "12"; height: "87"; }
+ ListElement{ longitude: "98"; latitude: "13"; height: "90"; }
+ ListElement{ longitude: "98"; latitude: "14"; height: "91"; }
+ ListElement{ longitude: "98"; latitude: "15"; height: "86"; }
+ ListElement{ longitude: "98"; latitude: "16"; height: "88"; }
+ ListElement{ longitude: "98"; latitude: "17"; height: "91"; }
+ ListElement{ longitude: "98"; latitude: "18"; height: "94"; }
+ ListElement{ longitude: "98"; latitude: "19"; height: "97"; }
+ ListElement{ longitude: "98"; latitude: "20"; height: "108"; }
+ ListElement{ longitude: "98"; latitude: "21"; height: "111"; }
+ ListElement{ longitude: "98"; latitude: "22"; height: "108"; }
+ ListElement{ longitude: "98"; latitude: "23"; height: "108"; }
+ ListElement{ longitude: "98"; latitude: "24"; height: "107"; }
+ ListElement{ longitude: "98"; latitude: "25"; height: "104"; }
+ ListElement{ longitude: "98"; latitude: "26"; height: "110"; }
+ ListElement{ longitude: "98"; latitude: "27"; height: "111"; }
+ ListElement{ longitude: "98"; latitude: "28"; height: "109"; }
+ ListElement{ longitude: "98"; latitude: "29"; height: "106"; }
+ ListElement{ longitude: "98"; latitude: "30"; height: "110"; }
+ ListElement{ longitude: "98"; latitude: "31"; height: "115"; }
+ ListElement{ longitude: "98"; latitude: "32"; height: "119"; }
+ ListElement{ longitude: "98"; latitude: "33"; height: "116"; }
+ ListElement{ longitude: "98"; latitude: "34"; height: "117"; }
+ ListElement{ longitude: "98"; latitude: "35"; height: "114"; }
+ ListElement{ longitude: "98"; latitude: "36"; height: "109"; }
+ ListElement{ longitude: "98"; latitude: "37"; height: "105"; }
+ ListElement{ longitude: "98"; latitude: "38"; height: "106"; }
+ ListElement{ longitude: "98"; latitude: "39"; height: "111"; }
+ ListElement{ longitude: "98"; latitude: "40"; height: "112"; }
+ ListElement{ longitude: "98"; latitude: "41"; height: "110"; }
+ ListElement{ longitude: "98"; latitude: "42"; height: "114"; }
+ ListElement{ longitude: "98"; latitude: "43"; height: "114"; }
+ ListElement{ longitude: "98"; latitude: "44"; height: "111"; }
+ ListElement{ longitude: "98"; latitude: "45"; height: "112"; }
+ ListElement{ longitude: "98"; latitude: "46"; height: "116"; }
+ ListElement{ longitude: "98"; latitude: "47"; height: "121"; }
+ ListElement{ longitude: "98"; latitude: "48"; height: "124"; }
+ ListElement{ longitude: "98"; latitude: "49"; height: "125"; }
+ ListElement{ longitude: "98"; latitude: "50"; height: "125"; }
+ ListElement{ longitude: "98"; latitude: "51"; height: "127"; }
+ ListElement{ longitude: "98"; latitude: "52"; height: "126"; }
+ ListElement{ longitude: "98"; latitude: "53"; height: "127"; }
+ ListElement{ longitude: "98"; latitude: "54"; height: "126"; }
+ ListElement{ longitude: "98"; latitude: "55"; height: "122"; }
+ ListElement{ longitude: "98"; latitude: "56"; height: "121"; }
+ ListElement{ longitude: "98"; latitude: "57"; height: "119"; }
+ ListElement{ longitude: "98"; latitude: "58"; height: "114"; }
+ ListElement{ longitude: "98"; latitude: "59"; height: "111"; }
+ ListElement{ longitude: "98"; latitude: "60"; height: "110"; }
+ ListElement{ longitude: "98"; latitude: "61"; height: "115"; }
+ ListElement{ longitude: "98"; latitude: "62"; height: "123"; }
+ ListElement{ longitude: "98"; latitude: "63"; height: "131"; }
+ ListElement{ longitude: "98"; latitude: "64"; height: "138"; }
+ ListElement{ longitude: "98"; latitude: "65"; height: "140"; }
+ ListElement{ longitude: "98"; latitude: "66"; height: "139"; }
+ ListElement{ longitude: "98"; latitude: "67"; height: "136"; }
+ ListElement{ longitude: "98"; latitude: "68"; height: "134"; }
+ ListElement{ longitude: "98"; latitude: "69"; height: "133"; }
+ ListElement{ longitude: "98"; latitude: "70"; height: "129"; }
+ ListElement{ longitude: "98"; latitude: "71"; height: "127"; }
+ ListElement{ longitude: "98"; latitude: "72"; height: "122"; }
+ ListElement{ longitude: "98"; latitude: "73"; height: "119"; }
+ ListElement{ longitude: "98"; latitude: "74"; height: "116"; }
+ ListElement{ longitude: "98"; latitude: "75"; height: "115"; }
+ ListElement{ longitude: "98"; latitude: "76"; height: "116"; }
+ ListElement{ longitude: "98"; latitude: "77"; height: "116"; }
+ ListElement{ longitude: "98"; latitude: "78"; height: "117"; }
+ ListElement{ longitude: "98"; latitude: "79"; height: "114"; }
+ ListElement{ longitude: "98"; latitude: "80"; height: "113"; }
+ ListElement{ longitude: "98"; latitude: "81"; height: "115"; }
+ ListElement{ longitude: "98"; latitude: "82"; height: "119"; }
+ ListElement{ longitude: "98"; latitude: "83"; height: "127"; }
+ ListElement{ longitude: "98"; latitude: "84"; height: "130"; }
+ ListElement{ longitude: "98"; latitude: "85"; height: "125"; }
+ ListElement{ longitude: "98"; latitude: "86"; height: "116"; }
+ ListElement{ longitude: "98"; latitude: "87"; height: "103"; }
+ ListElement{ longitude: "98"; latitude: "88"; height: "89"; }
+ ListElement{ longitude: "98"; latitude: "89"; height: "81"; }
+ ListElement{ longitude: "98"; latitude: "90"; height: "79"; }
+ ListElement{ longitude: "98"; latitude: "91"; height: "84"; }
+ ListElement{ longitude: "98"; latitude: "92"; height: "86"; }
+ ListElement{ longitude: "98"; latitude: "93"; height: "79"; }
+ ListElement{ longitude: "98"; latitude: "94"; height: "69"; }
+ ListElement{ longitude: "98"; latitude: "95"; height: "66"; }
+ ListElement{ longitude: "98"; latitude: "96"; height: "73"; }
+ ListElement{ longitude: "98"; latitude: "97"; height: "80"; }
+ ListElement{ longitude: "98"; latitude: "98"; height: "71"; }
+ ListElement{ longitude: "98"; latitude: "99"; height: "64"; }
+ ListElement{ longitude: "99"; latitude: "0"; height: "93"; }
+ ListElement{ longitude: "99"; latitude: "1"; height: "90"; }
+ ListElement{ longitude: "99"; latitude: "2"; height: "86"; }
+ ListElement{ longitude: "99"; latitude: "3"; height: "80"; }
+ ListElement{ longitude: "99"; latitude: "4"; height: "74"; }
+ ListElement{ longitude: "99"; latitude: "5"; height: "74"; }
+ ListElement{ longitude: "99"; latitude: "6"; height: "80"; }
+ ListElement{ longitude: "99"; latitude: "7"; height: "85"; }
+ ListElement{ longitude: "99"; latitude: "8"; height: "85"; }
+ ListElement{ longitude: "99"; latitude: "9"; height: "84"; }
+ ListElement{ longitude: "99"; latitude: "10"; height: "83"; }
+ ListElement{ longitude: "99"; latitude: "11"; height: "79"; }
+ ListElement{ longitude: "99"; latitude: "12"; height: "77"; }
+ ListElement{ longitude: "99"; latitude: "13"; height: "80"; }
+ ListElement{ longitude: "99"; latitude: "14"; height: "86"; }
+ ListElement{ longitude: "99"; latitude: "15"; height: "86"; }
+ ListElement{ longitude: "99"; latitude: "16"; height: "84"; }
+ ListElement{ longitude: "99"; latitude: "17"; height: "85"; }
+ ListElement{ longitude: "99"; latitude: "18"; height: "90"; }
+ ListElement{ longitude: "99"; latitude: "19"; height: "95"; }
+ ListElement{ longitude: "99"; latitude: "20"; height: "99"; }
+ ListElement{ longitude: "99"; latitude: "21"; height: "101"; }
+ ListElement{ longitude: "99"; latitude: "22"; height: "102"; }
+ ListElement{ longitude: "99"; latitude: "23"; height: "103"; }
+ ListElement{ longitude: "99"; latitude: "24"; height: "106"; }
+ ListElement{ longitude: "99"; latitude: "25"; height: "110"; }
+ ListElement{ longitude: "99"; latitude: "26"; height: "113"; }
+ ListElement{ longitude: "99"; latitude: "27"; height: "115"; }
+ ListElement{ longitude: "99"; latitude: "28"; height: "115"; }
+ ListElement{ longitude: "99"; latitude: "29"; height: "113"; }
+ ListElement{ longitude: "99"; latitude: "30"; height: "112"; }
+ ListElement{ longitude: "99"; latitude: "31"; height: "115"; }
+ ListElement{ longitude: "99"; latitude: "32"; height: "117"; }
+ ListElement{ longitude: "99"; latitude: "33"; height: "118"; }
+ ListElement{ longitude: "99"; latitude: "34"; height: "117"; }
+ ListElement{ longitude: "99"; latitude: "35"; height: "115"; }
+ ListElement{ longitude: "99"; latitude: "36"; height: "112"; }
+ ListElement{ longitude: "99"; latitude: "37"; height: "110"; }
+ ListElement{ longitude: "99"; latitude: "38"; height: "114"; }
+ ListElement{ longitude: "99"; latitude: "39"; height: "120"; }
+ ListElement{ longitude: "99"; latitude: "40"; height: "123"; }
+ ListElement{ longitude: "99"; latitude: "41"; height: "124"; }
+ ListElement{ longitude: "99"; latitude: "42"; height: "122"; }
+ ListElement{ longitude: "99"; latitude: "43"; height: "121"; }
+ ListElement{ longitude: "99"; latitude: "44"; height: "118"; }
+ ListElement{ longitude: "99"; latitude: "45"; height: "117"; }
+ ListElement{ longitude: "99"; latitude: "46"; height: "119"; }
+ ListElement{ longitude: "99"; latitude: "47"; height: "123"; }
+ ListElement{ longitude: "99"; latitude: "48"; height: "125"; }
+ ListElement{ longitude: "99"; latitude: "49"; height: "125"; }
+ ListElement{ longitude: "99"; latitude: "50"; height: "124"; }
+ ListElement{ longitude: "99"; latitude: "51"; height: "124"; }
+ ListElement{ longitude: "99"; latitude: "52"; height: "124"; }
+ ListElement{ longitude: "99"; latitude: "53"; height: "124"; }
+ ListElement{ longitude: "99"; latitude: "54"; height: "124"; }
+ ListElement{ longitude: "99"; latitude: "55"; height: "122"; }
+ ListElement{ longitude: "99"; latitude: "56"; height: "122"; }
+ ListElement{ longitude: "99"; latitude: "57"; height: "121"; }
+ ListElement{ longitude: "99"; latitude: "58"; height: "120"; }
+ ListElement{ longitude: "99"; latitude: "59"; height: "116"; }
+ ListElement{ longitude: "99"; latitude: "60"; height: "112"; }
+ ListElement{ longitude: "99"; latitude: "61"; height: "113"; }
+ ListElement{ longitude: "99"; latitude: "62"; height: "121"; }
+ ListElement{ longitude: "99"; latitude: "63"; height: "128"; }
+ ListElement{ longitude: "99"; latitude: "64"; height: "132"; }
+ ListElement{ longitude: "99"; latitude: "65"; height: "130"; }
+ ListElement{ longitude: "99"; latitude: "66"; height: "130"; }
+ ListElement{ longitude: "99"; latitude: "67"; height: "128"; }
+ ListElement{ longitude: "99"; latitude: "68"; height: "126"; }
+ ListElement{ longitude: "99"; latitude: "69"; height: "127"; }
+ ListElement{ longitude: "99"; latitude: "70"; height: "126"; }
+ ListElement{ longitude: "99"; latitude: "71"; height: "122"; }
+ ListElement{ longitude: "99"; latitude: "72"; height: "120"; }
+ ListElement{ longitude: "99"; latitude: "73"; height: "120"; }
+ ListElement{ longitude: "99"; latitude: "74"; height: "121"; }
+ ListElement{ longitude: "99"; latitude: "75"; height: "121"; }
+ ListElement{ longitude: "99"; latitude: "76"; height: "121"; }
+ ListElement{ longitude: "99"; latitude: "77"; height: "120"; }
+ ListElement{ longitude: "99"; latitude: "78"; height: "120"; }
+ ListElement{ longitude: "99"; latitude: "79"; height: "119"; }
+ ListElement{ longitude: "99"; latitude: "80"; height: "116"; }
+ ListElement{ longitude: "99"; latitude: "81"; height: "113"; }
+ ListElement{ longitude: "99"; latitude: "82"; height: "111"; }
+ ListElement{ longitude: "99"; latitude: "83"; height: "107"; }
+ ListElement{ longitude: "99"; latitude: "84"; height: "109"; }
+ ListElement{ longitude: "99"; latitude: "85"; height: "107"; }
+ ListElement{ longitude: "99"; latitude: "86"; height: "98"; }
+ ListElement{ longitude: "99"; latitude: "87"; height: "87"; }
+ ListElement{ longitude: "99"; latitude: "88"; height: "75"; }
+ ListElement{ longitude: "99"; latitude: "89"; height: "68"; }
+ ListElement{ longitude: "99"; latitude: "90"; height: "70"; }
+ ListElement{ longitude: "99"; latitude: "91"; height: "81"; }
+ ListElement{ longitude: "99"; latitude: "92"; height: "88"; }
+ ListElement{ longitude: "99"; latitude: "93"; height: "89"; }
+ ListElement{ longitude: "99"; latitude: "94"; height: "87"; }
+ ListElement{ longitude: "99"; latitude: "95"; height: "87"; }
+ ListElement{ longitude: "99"; latitude: "96"; height: "88"; }
+ ListElement{ longitude: "99"; latitude: "97"; height: "84"; }
+ ListElement{ longitude: "99"; latitude: "98"; height: "75"; }
+ ListElement{ longitude: "99"; latitude: "99"; height: "67"; }
+ }
+}
diff --git a/examples/qmlsurface/qml/qmlsurface/main.qml b/examples/qmlsurface/qml/qmlsurface/main.qml
new file mode 100644
index 00000000..160fa9b6
--- /dev/null
+++ b/examples/qmlsurface/qml/qmlsurface/main.qml
@@ -0,0 +1,166 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 com.digia.QtDataVisualization 1.0
+import "."
+
+Item {
+ id: mainview
+ width: 1280
+ height: 720
+ visible: true
+
+ Data {
+ id: surfaceData
+ }
+
+ Item {
+ id: surfaceView
+ width: mainview.width - surfaceGridToggle.width
+ height: mainview.height
+ anchors.right: mainview.right;
+
+ //! [0]
+ ColorGradient {
+ id: surfaceGradient
+ ColorGradientStop { position: 0.0; color: "darkslategray" }
+ ColorGradientStop { id: middleGradient; position: 0.55; color: "peru" }
+ ColorGradientStop { position: 1.0; color: "red" }
+ }
+ //! [0]
+
+ Surface3D {
+ id: surfaceplot
+ width: surfaceView.width
+ height: surfaceView.height
+ theme: AbstractGraph3D.ThemeStoneMoss
+ shadowQuality: AbstractGraph3D.ShadowQualityMedium
+ selectionMode: AbstractGraph3D.SelectionModeSliceRow
+ smoothSurfaceEnabled: true
+ surfaceGridEnabled: false
+ font.family: "STCaiyun"
+ font.pointSize: 35
+ scene.activeCamera.cameraPreset: AbstractGraph3D.CameraPresetIsometricLeft
+ dataProxy: surfaceData.heightProxy
+ axisY.min: 0.0
+ axisY.max: 250.0
+ axisX.segmentCount: 10
+ axisX.subSegmentCount: 2
+ axisX.labelFormat: "%i"
+ axisZ.segmentCount: 10
+ axisZ.subSegmentCount: 2
+ axisZ.labelFormat: "%i"
+ axisY.segmentCount: 5
+ axisY.subSegmentCount: 2
+ axisY.labelFormat: "%i"
+ gradient: surfaceGradient
+ }
+ }
+
+ NewButton {
+ id: surfaceGridToggle
+ anchors.top: parent.top
+ anchors.left: parent.left
+ width: 200
+ text: "Show Surface Grid"
+ //! [1]
+ onClicked: {
+ if (surfaceplot.surfaceGridEnabled == false) {
+ surfaceplot.surfaceGridEnabled = true;
+ text = "Hide Surface Grid"
+ } else {
+ surfaceplot.surfaceGridEnabled = false;
+ text = "Show Surface Grid"
+ }
+ }
+ //! [1]
+ }
+
+ NewButton {
+ id: smoothSurfaceToggle
+ anchors.top: surfaceGridToggle.bottom
+ width: surfaceGridToggle.width
+ text: "Show Flat"
+ //! [2]
+ onClicked: {
+ if (surfaceplot.smoothSurfaceEnabled == true) {
+ surfaceplot.smoothSurfaceEnabled = false;
+ text = "Show Smooth"
+ } else {
+ surfaceplot.smoothSurfaceEnabled = true;
+ text = "Show Flat"
+ }
+ }
+ //! [2]
+ }
+
+ NewButton {
+ id: backgroundToggle
+ anchors.top: smoothSurfaceToggle.bottom
+ width: smoothSurfaceToggle.width
+ text: "Hide Background"
+ onClicked: {
+ if (surfaceplot.backgroundVisible == true) {
+ surfaceplot.backgroundVisible = false;
+ text = "Show Background"
+ } else {
+ surfaceplot.backgroundVisible = true;
+ text = "Hide Background"
+ }
+ }
+ }
+
+ NewButton {
+ id: gridToggle
+ anchors.top: backgroundToggle.bottom
+ width: backgroundToggle.width
+ text: "Hide Grid"
+ onClicked: {
+ if (surfaceplot.gridVisible == true) {
+ surfaceplot.gridVisible = false;
+ text = "Show Grid"
+ } else {
+ surfaceplot.gridVisible = true;
+ text = "Hide Grid"
+ }
+ }
+ }
+
+ NewButton {
+ id: proxyToggle
+ anchors.top: gridToggle.bottom
+ width: gridToggle.width
+ text: "Switch to Item Model Proxy"
+ //! [3]
+ onClicked: {
+ if (surfaceplot.dataProxy === surfaceData.heightProxy) {
+ surfaceplot.axisY.max = 500.0
+ surfaceplot.dataProxy = surfaceData.proxy
+ middleGradient.position = 0.25
+ text = "Switch to Height Map Proxy"
+ } else {
+ surfaceplot.axisY.max = 250.0
+ surfaceplot.dataProxy = surfaceData.heightProxy
+ middleGradient.position = 0.55
+ text = "Switch to Item Model Proxy"
+ }
+ }
+ //! [3]
+ }
+}
diff --git a/examples/qmlsurface/qml/qmlsurface/newbutton.qml b/examples/qmlsurface/qml/qmlsurface/newbutton.qml
new file mode 100644
index 00000000..895db183
--- /dev/null
+++ b/examples/qmlsurface/qml/qmlsurface/newbutton.qml
@@ -0,0 +1,43 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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
+
+Item {
+ id: newbutton
+
+ property alias text: buttonText.text
+
+ signal clicked
+
+ height: 80
+
+ Button {
+ width: parent.width
+ height: parent.height
+ Text {
+ id: buttonText
+ wrapMode: Text.WordWrap
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignHCenter
+ anchors.fill: parent
+ }
+ onClicked: newbutton.clicked()
+ }
+}
diff --git a/examples/qmlbarchart/qmlbarchart.desktop b/examples/qmlsurface/qmlsurface.desktop
index c01705df..66dd0a72 100644
--- a/examples/qmlbarchart/qmlbarchart.desktop
+++ b/examples/qmlsurface/qmlsurface.desktop
@@ -3,9 +3,9 @@ Encoding=UTF-8
Version=1.0
Type=Application
Terminal=false
-Name=qmlbarchart
-Exec=/opt/qmlbarchart/bin/qmlbarchart
-Icon=qmlbarchart64
+Name=qmlsurface
+Exec=/opt/qmlsurface/bin/qmlsurface
+Icon=qmlsurface64
X-Window-Icon=
X-HildonDesk-ShowInToolbar=true
X-Osso-Type=application/x-executable
diff --git a/examples/qmlsurface/qmlsurface.pro b/examples/qmlsurface/qmlsurface.pro
new file mode 100644
index 00000000..64c72cf7
--- /dev/null
+++ b/examples/qmlsurface/qmlsurface.pro
@@ -0,0 +1,25 @@
+!include( ../examples.pri ) {
+ error( "Couldn't find the examples.pri file!" )
+}
+
+QT += widgets
+
+# Add more folders to ship with the application, here
+folder_01.source = qml/qmlsurface
+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
+
+# Please do not modify the following two lines. Required for deployment.
+include(qtquick2applicationviewer/qtquick2applicationviewer.pri)
+qtcAddDeployment()
+
+RESOURCES += qmlsurface.qrc
+
+OTHER_FILES += doc/src/* \
+ doc/images/*
diff --git a/examples/qmlsurface/qmlsurface.qrc b/examples/qmlsurface/qmlsurface.qrc
new file mode 100644
index 00000000..d0745b94
--- /dev/null
+++ b/examples/qmlsurface/qmlsurface.qrc
@@ -0,0 +1,10 @@
+<RCC>
+ <qresource prefix="/qml">
+ <file alias="main.qml">qml/qmlsurface/main.qml</file>
+ <file alias="Data.qml">qml/qmlsurface/data.qml</file>
+ <file alias="NewButton.qml">qml/qmlsurface/newbutton.qml</file>
+ </qresource>
+ <qresource prefix="/heightmaps">
+ <file alias="image">heightmap.png</file>
+ </qresource>
+</RCC>
diff --git a/examples/qmlmaps/qmlmaps64.png b/examples/qmlsurface/qmlsurface64.png
index 707d5c4e..707d5c4e 100644
--- a/examples/qmlmaps/qmlmaps64.png
+++ b/examples/qmlsurface/qmlsurface64.png
Binary files differ
diff --git a/examples/qmlmaps/qtquick2applicationviewer/qtquick2applicationviewer.cpp b/examples/qmlsurface/qtquick2applicationviewer/qtquick2applicationviewer.cpp
index 10709d7a..10709d7a 100644
--- a/examples/qmlmaps/qtquick2applicationviewer/qtquick2applicationviewer.cpp
+++ b/examples/qmlsurface/qtquick2applicationviewer/qtquick2applicationviewer.cpp
diff --git a/examples/qmlmaps/qtquick2applicationviewer/qtquick2applicationviewer.h b/examples/qmlsurface/qtquick2applicationviewer/qtquick2applicationviewer.h
index cf66f140..cf66f140 100644
--- a/examples/qmlmaps/qtquick2applicationviewer/qtquick2applicationviewer.h
+++ b/examples/qmlsurface/qtquick2applicationviewer/qtquick2applicationviewer.h
diff --git a/examples/qmlsurface/qtquick2applicationviewer/qtquick2applicationviewer.pri b/examples/qmlsurface/qtquick2applicationviewer/qtquick2applicationviewer.pri
new file mode 100644
index 00000000..a071e63d
--- /dev/null
+++ b/examples/qmlsurface/qtquick2applicationviewer/qtquick2applicationviewer.pri
@@ -0,0 +1,170 @@
+# 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
+ }
+ 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
deleted file mode 100644
index 7f581bff..00000000
--- a/examples/rainfall/data/raindata.txt
+++ /dev/null
@@ -1,1358 +0,0 @@
-# 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/images/rainfall-example.png b/examples/rainfall/doc/images/rainfall-example.png
deleted file mode 100644
index f4087927..00000000
--- a/examples/rainfall/doc/images/rainfall-example.png
+++ /dev/null
Binary files differ
diff --git a/examples/rainfall/doc/src/rainfall.qdoc b/examples/rainfall/doc/src/rainfall.qdoc
deleted file mode 100644
index bfe7fc36..00000000
--- a/examples/rainfall/doc/src/rainfall.qdoc
+++ /dev/null
@@ -1,28 +0,0 @@
-/****************************************************************************
-**
-** 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 rainfall
- \title Rainfall Example
-
- The barchart example shows how to make a simple 3D bar chart using Q3DBars.
-
- \image rainfall-example.png
-
- TODO
-*/
diff --git a/examples/scatter/doc/images/scatter-example.png b/examples/scatter/doc/images/scatter-example.png
new file mode 100644
index 00000000..d5331e4d
--- /dev/null
+++ b/examples/scatter/doc/images/scatter-example.png
Binary files differ
diff --git a/examples/scatter/doc/src/scatter.qdoc b/examples/scatter/doc/src/scatter.qdoc
new file mode 100644
index 00000000..90410bc6
--- /dev/null
+++ b/examples/scatter/doc/src/scatter.qdoc
@@ -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 QtDataVisualization 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 scatter
+ \title Scatter Example
+ \ingroup qtdatavisualization_examples
+ \brief Using Q3DScatter in a widget application.
+
+ The scatter example shows how to make a simple 3D scatter graph using Q3DScatter and
+ combining the use of widgets for adjusting several adjustable qualities. The example shows
+ how to:
+
+ \list
+ \li Create an application with Q3DScatter and some widgets
+ \li Use QScatterDataProxy to set data to the graph
+ \li Adjust some graph properties using widget controls
+ \endlist
+
+ \image scatter-example.png
+
+ \section1 Creating the application
+
+ First, in main.cpp, we create a QApplication, instantiate Q3DScatter and a window container
+ for it:
+
+ \snippet ../examples/scatter/main.cpp 0
+
+ The call to QWidget::createWindowContainer is required, as all data visualization types
+ (Q3DBars, Q3DScatter, Q3DSurface) inherit QWindow. Any class inheriting QWindow cannot be used
+ as a widget any other way.
+
+ Then we'll create horizontal and vertical layouts. We'll add the graph and the vertical
+ layout into the horizontal one:
+
+ \snippet ../examples/scatter/main.cpp 1
+
+ We're not using the vertical layout for anything yet, but we'll get back to it in
+ \l {Using widgets to control the graph}
+
+ Next, let's create another class to handle the data addition and other interaction with the
+ graph. Let's call it ScatterDataModifier (See \l {Setting up the graph} and
+ \l {Adding data to the graph} for details):
+
+ \snippet ../examples/scatter/main.cpp 2
+
+ The application main is done and we can show the graph and start the event loop:
+
+ \snippet ../examples/scatter/main.cpp 3
+
+ \section1 Setting up the graph
+
+ Let's set up some visual qualities for the graph in the constructor of the ScatterDataModifier
+ class we instantiated in the application main:
+
+ \snippet ../examples/scatter/scatterdatamodifier.cpp 0
+
+ None of these are required, but are used to override graph defaults. You can try how it looks
+ with the preset defaults by commenting the block above out.
+
+ Then we'll set axes for the graph:
+
+ \snippet ../examples/scatter/scatterdatamodifier.cpp 1
+
+ And finally we create a QScatterDataProxy, set a label format for it and set it as the active
+ proxy for the graph:
+
+ \snippet ../examples/scatter/scatterdatamodifier.cpp 2
+
+ That concludes setting up the graph.
+
+ \section1 Adding data to the graph
+
+ In application main, we called \c {modifier->start()} after constructing all the necessary
+ objects. This is how it looks like:
+
+ \snippet ../examples/scatter/scatterdatamodifier.cpp 3
+
+ There is nothing in it except a call to another method. There is actually no need for a
+ separate \c start() method, but we keep it here in case we want to add some more functionality
+ in it that can be done only after all construction in application main is done.
+
+ The actual data addition is done in \c addData() method. First we configure the axes we created
+ in constructor:
+
+ \snippet ../examples/scatter/scatterdatamodifier.cpp 4
+
+ This could have been done in the ScatterDataModifier's constructor, but we added it here
+ to keep the constructor simpler and the axes configuration near the data.
+
+ Next we create a data array:
+
+ \snippet ../examples/scatter/scatterdatamodifier.cpp 5
+
+ And populate it:
+
+ \snippet ../examples/scatter/scatterdatamodifier.cpp 6
+
+ Finally we tell the proxy to start using the data we gave it:
+
+ \snippet ../examples/scatter/scatterdatamodifier.cpp 7
+
+ Now our graph has the data and is ready to be used. There isn't much interaction yet, though,
+ so let's continue by adding some widgets to play with.
+
+ \section1 Using widgets to control the graph
+
+ First, back in the application main, we'll create some widgets:
+
+ \snippet ../examples/scatter/main.cpp 4
+
+ And add them to the vertical layout we created earlier:
+
+ \snippet ../examples/scatter/main.cpp 5
+
+ Now, let's connect them to methods in ScatterDataModifier:
+
+ \snippet ../examples/scatter/main.cpp 6
+
+ Here are the methods in ScatterDataModifier the signals were connected to:
+
+ \snippet ../examples/scatter/scatterdatamodifier.cpp 8
+
+ And so we have an application in which we can control:
+
+ \list
+ \li Label style
+ \li Camera preset
+ \li Background visibility
+ \li Grid visibility
+ \li Dot shading smoothness
+ \li Dot style
+ \li Theme
+ \li Shadow quality
+ \li Font
+ \endlist
+
+ \section1 Example contents
+*/
diff --git a/examples/scatter/main.cpp b/examples/scatter/main.cpp
new file mode 100644
index 00000000..ed0adc57
--- /dev/null
+++ b/examples/scatter/main.cpp
@@ -0,0 +1,162 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 "scatterdatamodifier.h"
+
+#include <QApplication>
+#include <QWidget>
+#include <QHBoxLayout>
+#include <QVBoxLayout>
+#include <QPushButton>
+#include <QCheckBox>
+#include <QComboBox>
+#include <QFontComboBox>
+#include <QLabel>
+#include <QScreen>
+#include <QFontDatabase>
+
+int main(int argc, char **argv)
+{
+ //! [0]
+ QApplication app(argc, argv);
+ Q3DScatter *graph = new Q3DScatter();
+ QWidget *container = QWidget::createWindowContainer(graph);
+ //! [0]
+
+ QSize screenSize = graph->screen()->size();
+ container->setMinimumSize(QSize(screenSize.width() / 2, screenSize.height() / 1.5));
+ container->setMaximumSize(screenSize);
+ container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ container->setFocusPolicy(Qt::StrongFocus);
+
+ //! [1]
+ QWidget *widget = new QWidget;
+ QHBoxLayout *hLayout = new QHBoxLayout(widget);
+ QVBoxLayout *vLayout = new QVBoxLayout();
+ hLayout->addWidget(container, 1);
+ hLayout->addLayout(vLayout);
+ //! [1]
+
+ widget->setWindowTitle(QStringLiteral("A Cosine Wave"));
+
+ //! [4]
+ QComboBox *themeList = new QComboBox(widget);
+ themeList->addItem(QStringLiteral("Qt"));
+ themeList->addItem(QStringLiteral("Primary Colors"));
+ themeList->addItem(QStringLiteral("Digia"));
+ themeList->addItem(QStringLiteral("Stone Moss"));
+ themeList->addItem(QStringLiteral("Army Blue"));
+ themeList->addItem(QStringLiteral("Retro"));
+ themeList->addItem(QStringLiteral("Ebony"));
+ themeList->addItem(QStringLiteral("Isabelle"));
+ themeList->setCurrentIndex(6);
+
+ QPushButton *labelButton = new QPushButton(widget);
+ labelButton->setText(QStringLiteral("Change label style"));
+
+ QCheckBox *smoothCheckBox = new QCheckBox(widget);
+ smoothCheckBox->setText(QStringLiteral("Smooth dots"));
+ smoothCheckBox->setChecked(true);
+
+ QComboBox *barStyleList = new QComboBox(widget);
+ barStyleList->addItem(QStringLiteral("Sphere"));
+ barStyleList->addItem(QStringLiteral("Tetrahedron"));
+ barStyleList->setCurrentIndex(0);
+
+ QPushButton *cameraButton = new QPushButton(widget);
+ cameraButton->setText(QStringLiteral("Change camera preset"));
+
+ 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->addItem(QStringLiteral("Low Soft"));
+ shadowQuality->addItem(QStringLiteral("Medium Soft"));
+ shadowQuality->addItem(QStringLiteral("High Soft"));
+ shadowQuality->setCurrentIndex(3);
+
+ QFontComboBox *fontList = new QFontComboBox(widget);
+ fontList->setCurrentFont(QFont("Arial"));
+ //! [4]
+
+ //! [5]
+ vLayout->addWidget(labelButton, 0, Qt::AlignTop);
+ vLayout->addWidget(cameraButton, 0, Qt::AlignTop);
+ vLayout->addWidget(backgroundCheckBox);
+ vLayout->addWidget(gridCheckBox);
+ vLayout->addWidget(smoothCheckBox, 0, Qt::AlignTop);
+ vLayout->addWidget(new QLabel(QStringLiteral("Change dot style")));
+ vLayout->addWidget(barStyleList);
+ vLayout->addWidget(new QLabel(QStringLiteral("Change theme")));
+ vLayout->addWidget(themeList);
+ vLayout->addWidget(new QLabel(QStringLiteral("Adjust shadow quality")));
+ vLayout->addWidget(shadowQuality);
+ vLayout->addWidget(new QLabel(QStringLiteral("Change font")));
+ vLayout->addWidget(fontList, 1, Qt::AlignTop);
+ //! [5]
+
+ //! [2]
+ ScatterDataModifier *modifier = new ScatterDataModifier(graph);
+ //! [2]
+
+ //! [6]
+ QObject::connect(cameraButton, &QPushButton::clicked, modifier,
+ &ScatterDataModifier::changePresetCamera);
+ QObject::connect(labelButton, &QPushButton::clicked, modifier,
+ &ScatterDataModifier::changeLabelStyle);
+
+ QObject::connect(backgroundCheckBox, &QCheckBox::stateChanged, modifier,
+ &ScatterDataModifier::setBackgroundEnabled);
+ QObject::connect(gridCheckBox, &QCheckBox::stateChanged, modifier,
+ &ScatterDataModifier::setGridEnabled);
+ QObject::connect(smoothCheckBox, &QCheckBox::stateChanged, modifier,
+ &ScatterDataModifier::setSmoothDots);
+
+ QObject::connect(barStyleList, SIGNAL(currentIndexChanged(int)), modifier,
+ SLOT(changeStyle(int)));
+
+ QObject::connect(themeList, SIGNAL(currentIndexChanged(int)), modifier,
+ SLOT(changeTheme(int)));
+
+ QObject::connect(shadowQuality, SIGNAL(currentIndexChanged(int)), modifier,
+ SLOT(changeShadowQuality(int)));
+
+ QObject::connect(modifier, &ScatterDataModifier::shadowQualityChanged, shadowQuality,
+ &QComboBox::setCurrentIndex);
+ QObject::connect(graph, &Q3DScatter::shadowQualityChanged, modifier,
+ &ScatterDataModifier::shadowQualityUpdatedByVisual);
+
+ QObject::connect(fontList, &QFontComboBox::currentFontChanged, modifier,
+ &ScatterDataModifier::changeFont);
+ //! [6]
+
+ //! [3]
+ widget->show();
+ modifier->start();
+ return app.exec();
+ //! [3]
+}
diff --git a/examples/scatter/scatter.pro b/examples/scatter/scatter.pro
new file mode 100644
index 00000000..beff2164
--- /dev/null
+++ b/examples/scatter/scatter.pro
@@ -0,0 +1,13 @@
+!include( ../examples.pri ) {
+ error( "Couldn't find the examples.pri file!" )
+}
+
+SOURCES += main.cpp scatterdatamodifier.cpp
+HEADERS += scatterdatamodifier.h
+
+QT += widgets
+
+INSTALLS += target
+
+OTHER_FILES += doc/src/* \
+ doc/images/*
diff --git a/examples/scatter/scatterdatamodifier.cpp b/examples/scatter/scatterdatamodifier.cpp
new file mode 100644
index 00000000..1fb08c93
--- /dev/null
+++ b/examples/scatter/scatterdatamodifier.cpp
@@ -0,0 +1,188 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 "scatterdatamodifier.h"
+#include <QtDataVisualization/qscatterdataproxy.h>
+#include <QtDataVisualization/q3dvalueaxis.h>
+#include <QtDataVisualization/q3dscene.h>
+#include <QtDataVisualization/q3dcamera.h>
+#include <qmath.h>
+using namespace QtDataVisualization;
+
+//#define RANDOM_SCATTER // Uncomment this to switch to random scatter
+
+const int numberOfItems = 10000;
+
+ScatterDataModifier::ScatterDataModifier(Q3DScatter *scatter)
+ : m_graph(scatter),
+ m_fontSize(40.0f),
+ m_style(QDataVis::MeshStyleSpheres),
+ m_smooth(true)
+{
+ //! [0]
+ QFont font = m_graph->font();
+ font.setPointSize(m_fontSize);
+ m_graph->setFont(font);
+ m_graph->setObjectType(QDataVis::MeshStyleSpheres, true);
+ m_graph->setTheme(QDataVis::ThemeEbony);
+ m_graph->setShadowQuality(QDataVis::ShadowQualityHigh);
+ m_graph->scene()->activeCamera()->setCameraPreset(QDataVis::CameraPresetFront);
+ //! [0]
+
+ //! [1]
+ m_graph->setAxisX(new Q3DValueAxis);
+ m_graph->setAxisY(new Q3DValueAxis);
+ m_graph->setAxisZ(new Q3DValueAxis);
+ //! [1]
+
+ //! [2]
+ QScatterDataProxy *proxy = new QScatterDataProxy;
+ proxy->setItemLabelFormat("@xTitle: @xLabel @yTitle: @yLabel @zTitle: @zLabel");
+ m_graph->setActiveDataProxy(proxy);
+ //! [2]
+
+ changeLabelStyle();
+}
+
+ScatterDataModifier::~ScatterDataModifier()
+{
+ delete m_graph;
+}
+
+//! [3]
+void ScatterDataModifier::start()
+{
+ addData();
+}
+//! [3]
+
+void ScatterDataModifier::addData()
+{
+ //! [4]
+ // Add labels
+ m_graph->axisX()->setTitle("X");
+ m_graph->axisY()->setTitle("Y");
+ m_graph->axisZ()->setTitle("Z");
+ m_graph->axisX()->setRange(-50.0, 50.0);
+ m_graph->axisY()->setRange(-1.0, 1.0);
+ m_graph->axisZ()->setRange(-50.0, 50.0);
+ //! [4]
+
+ //! [5]
+ QScatterDataArray *dataArray = new QScatterDataArray;
+ dataArray->resize(numberOfItems);
+ QScatterDataItem *ptrToDataArray = &dataArray->first();
+ //! [5]
+
+#ifdef RANDOM_SCATTER
+ for (int i = 0; i < numberOfItems; i++) {
+ ptrToDataArray->setPosition(randVector());
+ ptrToDataArray++;
+ }
+#else
+ //! [6]
+ 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++;
+ }
+ }
+ //! [6]
+#endif
+
+ //! [7]
+ m_graph->activeDataProxy()->resetArray(dataArray);
+ //! [7]
+}
+
+//! [8]
+void ScatterDataModifier::changeStyle(int style)
+{
+ m_style = QDataVis::MeshStyle(style + 5); // skip unsupported mesh types
+ m_graph->setObjectType(m_style, m_smooth);
+}
+
+void ScatterDataModifier::setSmoothDots(int smooth)
+{
+ m_smooth = bool(smooth);
+ m_graph->setObjectType(m_style, m_smooth);
+}
+
+void ScatterDataModifier::changeTheme(int theme)
+{
+ m_graph->setTheme((QDataVis::Theme)theme);
+}
+
+void ScatterDataModifier::changePresetCamera()
+{
+ static int preset = QDataVis::CameraPresetFrontLow;
+
+ m_graph->scene()->activeCamera()->setCameraPreset((QDataVis::CameraPreset)preset);
+
+ if (++preset > QDataVis::CameraPresetDirectlyBelow)
+ preset = QDataVis::CameraPresetFrontLow;
+}
+
+void ScatterDataModifier::changeLabelStyle()
+{
+ static int style = QDataVis::LabelStyleFromTheme;
+
+ m_graph->setLabelStyle((QDataVis::LabelStyle)style);
+
+ if (++style > QDataVis::LabelStyleTransparent)
+ style = QDataVis::LabelStyleOpaque;
+}
+
+void ScatterDataModifier::changeFont(const QFont &font)
+{
+ QFont newFont = font;
+ newFont.setPointSizeF(m_fontSize);
+ m_graph->setFont(newFont);
+}
+
+void ScatterDataModifier::shadowQualityUpdatedByVisual(QDataVis::ShadowQuality sq)
+{
+ int quality = int(sq);
+ emit shadowQualityChanged(quality); // connected to a checkbox in main.cpp
+}
+
+void ScatterDataModifier::changeShadowQuality(int quality)
+{
+ QDataVis::ShadowQuality sq = QDataVis::ShadowQuality(quality);
+ m_graph->setShadowQuality(sq);
+}
+
+void ScatterDataModifier::setBackgroundEnabled(int enabled)
+{
+ m_graph->setBackgroundVisible((bool)enabled);
+}
+
+void ScatterDataModifier::setGridEnabled(int enabled)
+{
+ m_graph->setGridVisible((bool)enabled);
+}
+//! [8]
+
+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/mapdata/mapdata.h b/examples/scatter/scatterdatamodifier.h
index 8aed69fe..5cc9348b 100644
--- a/examples/mapdata/mapdata.h
+++ b/examples/scatter/scatterdatamodifier.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -16,50 +16,47 @@
**
****************************************************************************/
-#ifndef CHARTMODIFIER_H
-#define CHARTMODIFIER_H
+#ifndef SCATTERDATAMODIFIER_H
+#define SCATTERDATAMODIFIER_H
-#include <QtDataVis3D/q3dmaps.h>
+#include <QtDataVisualization/q3dscatter.h>
+#include <QtGui/QFont>
-#include <QFont>
-#include <QDebug>
+using namespace QtDataVisualization;
-using namespace QtDataVis3D;
-
-class MapsModifier : public QObject
+class ScatterDataModifier : public QObject
{
Q_OBJECT
public:
- explicit MapsModifier(Q3DMaps *maps);
- ~MapsModifier();
+ explicit ScatterDataModifier(Q3DScatter *scatter);
+ ~ScatterDataModifier();
void addData();
void changeStyle();
void changePresetCamera();
- void changeTheme();
-// void changeSelectionMode();
- void changeTransparency();
+ void changeLabelStyle();
void changeFont(const QFont &font);
void changeFontSize(int fontsize);
-// void rotateX(int rotation);
-// void rotateY(int rotation);
-// void setGridEnabled(int enabled);
-// void setSpecsX(int barwidth);
-// void setSpecsZ(int bardepth);
+ void setBackgroundEnabled(int enabled);
+ void setGridEnabled(int enabled);
+ void setSmoothDots(int smooth);
void start();
public slots:
- void changeValueDimension(int dimension);
+ void changeStyle(int style);
+ void changeTheme(int theme);
void changeShadowQuality(int quality);
+ void shadowQualityUpdatedByVisual(QDataVis::ShadowQuality shadowQuality);
signals:
- void shadowQuality(int quality);
+ void shadowQualityChanged(int quality);
private:
- Q3DMaps *m_chart;
- QRect m_imageRect;
+ QVector3D randVector();
+ Q3DScatter *m_graph;
int m_fontSize;
- QVector3D m_barSpecs;
+ QDataVis::MeshStyle m_style;
+ bool m_smooth;
};
#endif
diff --git a/examples/scatterchart/doc/src/scatterchart.qdoc b/examples/scatterchart/doc/src/scatterchart.qdoc
deleted file mode 100644
index 6e8dcd03..00000000
--- a/examples/scatterchart/doc/src/scatterchart.qdoc
+++ /dev/null
@@ -1,29 +0,0 @@
-/****************************************************************************
-**
-** 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/spectrum/doc/images/spectrum-example.png b/examples/spectrum/doc/images/spectrum-example.png
deleted file mode 100644
index 2a703948..00000000
--- a/examples/spectrum/doc/images/spectrum-example.png
+++ /dev/null
Binary files differ
diff --git a/examples/spectrum/doc/src/spectrum.qdoc b/examples/spectrum/doc/src/spectrum.qdoc
deleted file mode 100644
index 612c31cd..00000000
--- a/examples/spectrum/doc/src/spectrum.qdoc
+++ /dev/null
@@ -1,28 +0,0 @@
-/****************************************************************************
-**
-** 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 spectrum
- \title Spectrum Example
-
- The spectrum example shows how feed dynamic data to a graph using Q3DBars.
-
- \image spectrum-example.png
-
- TODO
-*/
diff --git a/examples/surface/doc/images/surface-example.png b/examples/surface/doc/images/surface-example.png
new file mode 100644
index 00000000..591f9c1e
--- /dev/null
+++ b/examples/surface/doc/images/surface-example.png
Binary files differ
diff --git a/examples/surface/doc/src/surface.qdoc b/examples/surface/doc/src/surface.qdoc
new file mode 100644
index 00000000..12271fb8
--- /dev/null
+++ b/examples/surface/doc/src/surface.qdoc
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 surface
+ \title Surface Example
+ \ingroup qtdatavisualization_examples
+ \brief Using Q3DSurface in a widget application.
+
+ The surface example shows how to make a simple 3D surface graph using Q3DSurface and
+ combining the use of widgets for adjusting several adjustable qualities. This example
+ demonstrates the following features:
+
+ \list
+ \li How to set up a basic QSurfaceDataProxy and set data for it.
+ \li How to use QHeightMapSurfaceDataProxy for showing 3D height maps.
+ \li Three different selection modes for studying the graph.
+ \li Axis range usage for selecting slices from the graph.
+ \li Theme usage on the surface graph.
+ \li How to set a custom surface gradient.
+ \endlist
+ \image surface-example.png
+
+ \section1 Creating the application
+
+ First, in \c main.cpp, we create a QApplication, instantiate Q3DSurface and a window container
+ for it:
+
+ \snippet ../examples/surface/main.cpp 0
+
+ The call to QWidget::createWindowContainer is required, as all data visualization types
+ (Q3DBars, Q3DScatter, Q3DSurface) inherit QWindow. Any class inheriting QWindow cannot be used
+ as a widget any other way.
+
+ Then we'll create horizontal and vertical layouts. We'll add the graph with the container and
+ the vertical layout into the horizontal one:
+
+ \snippet ../examples/surface/main.cpp 1
+
+ The rest of the code in \c main.cpp is creating control widgets for features in Q3DSurface. We
+ have separated code for changing these features into \c surfacegraph.cpp and only connect
+ signals from widgets into methods in \c surfacegraph.cpp. Next chapter explains more
+ about using Q3DSurface.
+
+ \section1 Setting up proxies and data
+
+ First we instantiate a new QSurfaceDataProxy:
+
+ \snippet ../examples/surface/surfacegraph.cpp 0
+
+ Then we fill it with a simple square root and sin wave data. This is done by
+ creating a new QSurfaceDataArray instance and adding QSurfaceDataRow elements.
+ The created QSurfaceDataArray is set to be a the data array for the QSurfaceDataProxy.
+
+ \snippet ../examples/surface/surfacegraph.cpp 1
+
+ The height map is created by instantiating a QHeightMapSurfaceDataProxy with
+ a QImage containing the height data. The method setValueRanges is used to define
+ the value range of the map. In our example the map is from imaginary position of
+ 34.0\unicode 0x00B0 N - 40.0\unicode 0x00B0 N and 18.0\unicode 0x00B0 E - 24.0\unicode 0x00B0 E.
+ These values are used to show and position the map to the axis.
+
+ \snippet ../examples/surface/surfacegraph.cpp 2
+
+ For demonstrating different proxies this example has two radio buttons which
+ the user can use to switch between active proxies. When the user selects the
+ Sqrt&Sin radio button the selected proxy is activated with the following
+ code. First we set the decorative issues like enable the grid for the surface and
+ select the flat surface mode. Next lines define the axis label format and value
+ ranges. Since the algorithm studies the value variation between -8.0 and 8.0 we
+ set these values for X and Z coordinates. The value itself varies between 0.0 and
+ 2.0. The method setActiveDataProxy sets the basic data proxy to be active.
+
+ \snippet ../examples/surface/surfacegraph.cpp 3
+
+ When the Height Map radio button is activated, the following code sets the proxy on.
+ First the surface grid is turned off and the smooth mode is activated. The axis label
+ format is set to show N and E letters and ranges are set to the imaginary coordinates.
+ Finally the height map proxy is set to be active.
+
+ \snippet ../examples/surface/surfacegraph.cpp 4
+
+ \section1 Selection modes
+
+ Q3Dsurface supports three different selection modes and these are demonstrated on the
+ example with radio buttons which the user can use to activate suitable selection mode.
+ Following inline methods are connected to radio buttons to activate the selected mode.
+
+ \snippet ../examples/surface/surfacegraph.h 0
+
+ \section1 Axis ranges for studying the graph
+
+ The example has four slider controls for adjusting the min and max values for X and Z
+ axis. When selecting the proxy these sliders are adjusted so that one step on the slider
+ moves the range by one segment step. The example has some code to keep the sliders on
+ valid positions, like when the X axis minimum exceeds the maximum the maximum is increased
+ and so on. Finally the ranges are set for the graph like this:
+
+ \snippet ../examples/surface/surfacegraph.cpp 5
+
+ \section1 Themes
+
+ Q3Dsurface supports all the themes QtDatavisualization has. The example has a pull
+ down menu for selecting the theme and the following code snippet is connected to the menu to
+ activate the selected theme.
+
+ \snippet ../examples/surface/surfacegraph.cpp 6
+
+ \section1 Custom surface gradients
+
+ The example demonstrates the custom surface gradients with two push buttons. The gradient
+ can be defined with QLinearGradient where the desired colors are set to positions. Following
+ snippet shows how to create an example gradient and set it to the graph.
+
+ \snippet ../examples/surface/surfacegraph.cpp 7
+*/
diff --git a/examples/surface/main.cpp b/examples/surface/main.cpp
new file mode 100644
index 00000000..69babe8a
--- /dev/null
+++ b/examples/surface/main.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 QtDataVisualization 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 "surfacegraph.h"
+
+#include <QtWidgets/QApplication>
+#include <QtWidgets/QWidget>
+#include <QtWidgets/QHBoxLayout>
+#include <QtWidgets/QVBoxLayout>
+#include <QtWidgets/QPushButton>
+#include <QtWidgets/QRadioButton>
+#include <QtWidgets/QSlider>
+#include <QtWidgets/QGroupBox>
+#include <QtWidgets/QComboBox>
+#include <QtWidgets/QLabel>
+#include <QtGui/QPainter>
+
+int main(int argc, char **argv)
+{
+ //! [0]
+ QApplication app(argc, argv);
+ Q3DSurface *graph = new Q3DSurface();
+ QWidget *container = QWidget::createWindowContainer(graph);
+ //! [0]
+
+ QSize screenSize = graph->screen()->size();
+ container->setMinimumSize(QSize(screenSize.width() / 2, screenSize.height() / 1.6));
+ container->setMaximumSize(screenSize);
+ container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ container->setFocusPolicy(Qt::StrongFocus);
+
+ //! [1]
+ QWidget *widget = new QWidget;
+ QHBoxLayout *hLayout = new QHBoxLayout(widget);
+ QVBoxLayout *vLayout = new QVBoxLayout();
+ hLayout->addWidget(container, 1);
+ hLayout->addLayout(vLayout);
+ vLayout->setAlignment(Qt::AlignTop);
+ //! [1]
+
+ widget->setWindowTitle(QStringLiteral("Surface example"));
+
+ QGroupBox *modelGroupBox = new QGroupBox(QStringLiteral("Model"));
+
+ QRadioButton *sqrtSinModelRB = new QRadioButton(widget);
+ sqrtSinModelRB->setText(QStringLiteral("Sqrt&Sin"));
+ sqrtSinModelRB->setChecked(false);
+
+ QRadioButton *heightMapModelRB = new QRadioButton(widget);
+ heightMapModelRB->setText(QStringLiteral("Height Map"));
+ heightMapModelRB->setChecked(false);
+
+ QVBoxLayout *modelVBox = new QVBoxLayout;
+ modelVBox->addWidget(sqrtSinModelRB);
+ modelVBox->addWidget(heightMapModelRB);
+ modelGroupBox->setLayout(modelVBox);
+
+ QGroupBox *selectionGroupBox = new QGroupBox(QStringLiteral("Selection Mode"));
+
+ QRadioButton *modeNoneRB = new QRadioButton(widget);
+ modeNoneRB->setText(QStringLiteral("No selection"));
+ modeNoneRB->setChecked(false);
+
+ QRadioButton *modeItemRB = new QRadioButton(widget);
+ modeItemRB->setText(QStringLiteral("Item"));
+ modeItemRB->setChecked(false);
+
+ QRadioButton *modeSliceRowRB = new QRadioButton(widget);
+ modeSliceRowRB->setText(QStringLiteral("Row Slice"));
+ modeSliceRowRB->setChecked(false);
+
+ QRadioButton *modeSliceColumnRB = new QRadioButton(widget);
+ modeSliceColumnRB->setText(QStringLiteral("Column Slice"));
+ modeSliceColumnRB->setChecked(false);
+
+ QVBoxLayout *selectionVBox = new QVBoxLayout;
+ selectionVBox->addWidget(modeNoneRB);
+ selectionVBox->addWidget(modeItemRB);
+ selectionVBox->addWidget(modeSliceRowRB);
+ selectionVBox->addWidget(modeSliceColumnRB);
+ selectionGroupBox->setLayout(selectionVBox);
+
+ QSlider *axisMinSliderX = new QSlider(Qt::Horizontal, widget);
+ axisMinSliderX->setMinimum(0);
+ axisMinSliderX->setTickInterval(1);
+ axisMinSliderX->setEnabled(true);
+ QSlider *axisMaxSliderX = new QSlider(Qt::Horizontal, widget);
+ axisMaxSliderX->setMinimum(2);
+ axisMaxSliderX->setTickInterval(1);
+ axisMaxSliderX->setEnabled(true);
+ QSlider *axisMinSliderZ = new QSlider(Qt::Horizontal, widget);
+ axisMinSliderZ->setMinimum(0);
+ axisMinSliderZ->setTickInterval(1);
+ axisMinSliderZ->setEnabled(true);
+ QSlider *axisMaxSliderZ = new QSlider(Qt::Horizontal, widget);
+ axisMaxSliderZ->setMinimum(2);
+ axisMaxSliderZ->setTickInterval(1);
+ axisMaxSliderZ->setEnabled(true);
+
+ QComboBox *themeList = new QComboBox(widget);
+ themeList->addItem(QStringLiteral("Qt"));
+ themeList->addItem(QStringLiteral("Primary Colors"));
+ themeList->addItem(QStringLiteral("Digia"));
+ themeList->addItem(QStringLiteral("Stone Moss"));
+ themeList->addItem(QStringLiteral("Army Blue"));
+ themeList->addItem(QStringLiteral("Retro"));
+ themeList->addItem(QStringLiteral("Ebony"));
+ themeList->addItem(QStringLiteral("Isabelle"));
+
+ QGroupBox *colorGroupBox = new QGroupBox(QStringLiteral("Custom gradient"));
+
+ QLinearGradient grBtoY(0, 0, 1, 100);
+ grBtoY.setColorAt(1.0, Qt::black);
+ grBtoY.setColorAt(0.67, Qt::blue);
+ grBtoY.setColorAt(0.33, Qt::red);
+ grBtoY.setColorAt(0.0, Qt::yellow);
+ QPixmap pm(24, 100);
+ QPainter pmp(&pm);
+ pmp.setBrush(QBrush(grBtoY));
+ pmp.setPen(Qt::NoPen);
+ pmp.drawRect(0, 0, 24, 100);
+ QPushButton *gradientBtoYPB = new QPushButton(widget);
+ gradientBtoYPB->setIcon(QIcon(pm));
+ gradientBtoYPB->setIconSize(QSize(24, 100));
+
+ QLinearGradient grGtoR(0, 0, 1, 100);
+ grGtoR.setColorAt(1.0, Qt::darkGreen);
+ grGtoR.setColorAt(0.5, Qt::yellow);
+ grGtoR.setColorAt(0.2, Qt::red);
+ grGtoR.setColorAt(0.0, Qt::darkRed);
+ pmp.setBrush(QBrush(grGtoR));
+ pmp.drawRect(0, 0, 24, 100);
+ QPushButton *gradientGtoRPB = new QPushButton(widget);
+ gradientGtoRPB->setIcon(QIcon(pm));
+ gradientGtoRPB->setIconSize(QSize(24, 100));
+
+ QHBoxLayout *colorHBox = new QHBoxLayout;
+ colorHBox->addWidget(gradientBtoYPB);
+ colorHBox->addWidget(gradientGtoRPB);
+ colorGroupBox->setLayout(colorHBox);
+
+ vLayout->addWidget(modelGroupBox);
+ vLayout->addWidget(selectionGroupBox);
+ vLayout->addWidget(new QLabel(QStringLiteral("Column range")));
+ vLayout->addWidget(axisMinSliderX);
+ vLayout->addWidget(axisMaxSliderX);
+ vLayout->addWidget(new QLabel(QStringLiteral("Row range")));
+ vLayout->addWidget(axisMinSliderZ);
+ vLayout->addWidget(axisMaxSliderZ);
+ vLayout->addWidget(new QLabel(QStringLiteral("Theme")));
+ vLayout->addWidget(themeList);
+ vLayout->addWidget(colorGroupBox);
+
+ widget->show();
+
+ SurfaceGraph *modifier = new SurfaceGraph(graph);
+
+ QObject::connect(heightMapModelRB, &QRadioButton::toggled,
+ modifier, &SurfaceGraph::enableHeightMapModel);
+ QObject::connect(sqrtSinModelRB, &QRadioButton::toggled,
+ modifier, &SurfaceGraph::enableSqrtSinModel);
+ QObject::connect(modeNoneRB, &QRadioButton::toggled,
+ modifier, &SurfaceGraph::toggleModeNone);
+ QObject::connect(modeItemRB, &QRadioButton::toggled,
+ modifier, &SurfaceGraph::toggleModeItem);
+ QObject::connect(modeSliceRowRB, &QRadioButton::toggled,
+ modifier, &SurfaceGraph::toggleModeSliceRow);
+ QObject::connect(modeSliceColumnRB, &QRadioButton::toggled,
+ modifier, &SurfaceGraph::toggleModeSliceColumn);
+ QObject::connect(axisMinSliderX, &QSlider::valueChanged,
+ modifier, &SurfaceGraph::adjustXMin);
+ QObject::connect(axisMaxSliderX, &QSlider::valueChanged,
+ modifier, &SurfaceGraph::adjustXMax);
+ QObject::connect(axisMinSliderZ, &QSlider::valueChanged,
+ modifier, &SurfaceGraph::adjustZMin);
+ QObject::connect(axisMaxSliderZ, &QSlider::valueChanged,
+ modifier, &SurfaceGraph::adjustZMax);
+ QObject::connect(themeList, SIGNAL(currentIndexChanged(int)),
+ modifier, SLOT(changeTheme(int)));
+ QObject::connect(gradientBtoYPB, &QPushButton::pressed,
+ modifier, &SurfaceGraph::setBlackToYellowGradient);
+ QObject::connect(gradientGtoRPB, &QPushButton::pressed,
+ modifier, &SurfaceGraph::setGreenToRedGradient);
+
+ modifier->setAxisMinSliderX(axisMinSliderX);
+ modifier->setAxisMaxSliderX(axisMaxSliderX);
+ modifier->setAxisMinSliderZ(axisMinSliderZ);
+ modifier->setAxisMaxSliderZ(axisMaxSliderZ);
+
+ sqrtSinModelRB->setChecked(true);
+ modeItemRB->setChecked(true);
+ themeList->setCurrentIndex(2);
+
+ return app.exec();
+}
diff --git a/examples/surface/mountain.png b/examples/surface/mountain.png
new file mode 100644
index 00000000..9138c710
--- /dev/null
+++ b/examples/surface/mountain.png
Binary files differ
diff --git a/examples/surface/surface.pro b/examples/surface/surface.pro
new file mode 100644
index 00000000..20c8a1a8
--- /dev/null
+++ b/examples/surface/surface.pro
@@ -0,0 +1,17 @@
+!include( ../examples.pri ) {
+ error( "Couldn't find the examples.pri file!" )
+}
+
+SOURCES += main.cpp \
+ surfacegraph.cpp
+
+HEADERS += surfacegraph.h
+
+QT += widgets
+
+INSTALLS += target
+
+RESOURCES += surface.qrc
+
+OTHER_FILES += doc/src/* \
+ doc/images/*
diff --git a/examples/surface/surface.qrc b/examples/surface/surface.qrc
new file mode 100644
index 00000000..e4a7c38b
--- /dev/null
+++ b/examples/surface/surface.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/maps">
+ <file alias="mountain">mountain.png</file>
+ </qresource>
+</RCC>
diff --git a/examples/surface/surfacegraph.cpp b/examples/surface/surfacegraph.cpp
new file mode 100644
index 00000000..a33f060b
--- /dev/null
+++ b/examples/surface/surfacegraph.cpp
@@ -0,0 +1,242 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 "surfacegraph.h"
+
+#include <QtDataVisualization/Q3DValueAxis>
+#include <QtGui/QImage>
+#include <QtCore/qmath.h>
+
+using namespace QtDataVisualization;
+
+const int sampleCountX = 50;
+const int sampleCountZ = 50;
+const int heightMapGridStepX = 6;
+const int heightMapGridStepZ = 6;
+
+SurfaceGraph::SurfaceGraph(Q3DSurface *surface)
+ : m_graph(surface)
+{
+ m_graph->setAxisX(new Q3DValueAxis);
+ m_graph->setAxisY(new Q3DValueAxis);
+ m_graph->setAxisZ(new Q3DValueAxis);
+ m_graph->setLabelStyle(QDataVis::LabelStyleFromTheme);
+
+ //! [0]
+ sqrtSinProxy = new QSurfaceDataProxy();
+ //! [0]
+ fillSqrtSinProxy();
+
+ //! [2]
+ QImage heightMapImage(":/maps/mountain");
+ m_heightMapProxy = new QHeightMapSurfaceDataProxy(heightMapImage);
+ m_heightMapProxy->setValueRanges(34.0, 40.0, 18.0, 24.0);
+ //! [2]
+ m_heightMapWidth = heightMapImage.width();
+ m_heightMapHeight = heightMapImage.height();
+}
+
+SurfaceGraph::~SurfaceGraph()
+{
+ delete m_graph;
+}
+
+//! [1]
+void SurfaceGraph::fillSqrtSinProxy()
+{
+ qreal stepX = 16.0 / qreal(sampleCountX);
+ qreal stepZ = 16.0 / qreal(sampleCountZ);
+
+ QSurfaceDataArray *dataArray = new QSurfaceDataArray;
+ dataArray->reserve(sampleCountZ);
+ for (qreal i = -8.0 + stepZ / 2.0 ; i < 8.0 ; i += stepZ) {
+ QSurfaceDataRow *newRow = new QSurfaceDataRow(sampleCountX);
+ int index = 0;
+ for (qreal j = -8.0 + stepX / 2.0; j < 8.0; j += stepX) {
+ qreal R = qSqrt(i * i + j * j) + 0.01;
+ qreal y = (qSin(R) / R + 0.24) * 1.61;
+ (*newRow)[index++].setPosition(QVector3D(j, y, i));
+ }
+ *dataArray << newRow;
+ }
+
+ sqrtSinProxy->resetArray(dataArray);
+}
+//! [1]
+
+void SurfaceGraph::enableSqrtSinModel()
+{
+ //! [3]
+ m_graph->setSurfaceGridEnabled(true);
+ m_graph->setSmoothSurfaceEnabled(false);
+
+ m_graph->axisX()->setLabelFormat("%.2f");
+ m_graph->axisZ()->setLabelFormat("%.2f");
+ m_graph->axisX()->setRange(-8.0, 8.0);
+ m_graph->axisY()->setRange(0.0, 2.0);
+ m_graph->axisZ()->setRange(-8.0, 8.0);
+
+ m_graph->setActiveDataProxy(sqrtSinProxy);
+ //! [3]
+
+ // Reset range sliders for Sqrt&Sin
+ m_rangeMinX = -8.0;
+ m_rangeMinZ = -8.0;
+ m_stepX = 16.0 / qreal(sampleCountX - 1);
+ m_stepZ = 16.0 / qreal(sampleCountZ - 1);
+ m_axisMinSliderX->setMaximum(sampleCountX - 3);
+ m_axisMinSliderX->setValue(0);
+ m_axisMaxSliderX->setMaximum(sampleCountX - 1);
+ m_axisMaxSliderX->setValue(sampleCountX - 1);
+ m_axisMinSliderZ->setMaximum(sampleCountZ - 3);
+ m_axisMinSliderZ->setValue(0);
+ m_axisMaxSliderZ->setMaximum(sampleCountZ - 1);
+ m_axisMaxSliderZ->setValue(sampleCountZ - 1);
+}
+
+void SurfaceGraph::enableHeightMapModel()
+{
+ //! [4]
+ m_graph->setSurfaceGridEnabled(false);
+ m_graph->setSmoothSurfaceEnabled(true);
+
+ m_graph->axisX()->setLabelFormat("%.1f N");
+ m_graph->axisZ()->setLabelFormat("%.1f E");
+ m_graph->axisX()->setRange(34.0, 40.0);
+ m_graph->axisY()->setAutoAdjustRange(true);
+ m_graph->axisZ()->setRange(18.0, 24.0);
+
+ m_graph->setActiveDataProxy(m_heightMapProxy);
+ //! [4]
+
+ // Reset range sliders for height map
+ int mapGridCountX = m_heightMapWidth / heightMapGridStepX;
+ int mapGridCountZ = m_heightMapHeight / heightMapGridStepZ;
+ m_rangeMinX = 34.0;
+ m_rangeMinZ = 18.0;
+ m_stepX = 6.0 / qreal(mapGridCountX - 1);
+ m_stepZ = 6.0 / qreal(mapGridCountZ - 1);
+ m_axisMinSliderX->setMaximum(mapGridCountX - 3);
+ m_axisMinSliderX->setValue(0);
+ m_axisMaxSliderX->setMaximum(mapGridCountX - 1);
+ m_axisMaxSliderX->setValue(mapGridCountX - 1);
+ m_axisMinSliderZ->setMaximum(mapGridCountZ - 3);
+ m_axisMinSliderZ->setValue(0);
+ m_axisMaxSliderZ->setMaximum(mapGridCountZ - 1);
+ m_axisMaxSliderZ->setValue(mapGridCountZ - 1);
+}
+
+void SurfaceGraph::adjustXMin(int min)
+{
+ qreal minX = m_stepX * qreal(min) + m_rangeMinX;
+
+ int max = m_axisMaxSliderX->value();
+ if (min >= (max - 1)) {
+ max = min + 2;
+ m_axisMaxSliderX->setValue(max);
+ }
+ qreal maxX = m_stepX * max + m_rangeMinX;
+
+ setAxisXRange(minX, maxX);
+}
+
+void SurfaceGraph::adjustXMax(int max)
+{
+ qreal maxX = m_stepX * qreal(max) + m_rangeMinX;
+
+ int min = m_axisMinSliderX->value();
+ if (max <= (min + 1)) {
+ min = max - 2;
+ m_axisMinSliderX->setValue(min);
+ }
+ qreal minX = m_stepX * min + m_rangeMinX;
+
+ setAxisXRange(minX, maxX);
+}
+
+void SurfaceGraph::adjustZMin(int min)
+{
+ qreal minZ = m_stepZ * qreal(min) + m_rangeMinZ;
+
+ int max = m_axisMaxSliderZ->value();
+ if (min >= (max - 1)) {
+ max = min + 2;
+ m_axisMaxSliderZ->setValue(max);
+ }
+ qreal maxZ = m_stepZ * max + m_rangeMinZ;
+
+ setAxisZRange(minZ, maxZ);
+}
+
+void SurfaceGraph::adjustZMax(int max)
+{
+ qreal maxX = m_stepZ * qreal(max) + m_rangeMinZ;
+
+ int min = m_axisMinSliderZ->value();
+ if (max <= (min + 1)) {
+ min = max - 2;
+ m_axisMinSliderZ->setValue(min);
+ }
+ qreal minX = m_stepZ * min + m_rangeMinZ;
+
+ setAxisZRange(minX, maxX);
+}
+
+//! [5]
+void SurfaceGraph::setAxisXRange(qreal min, qreal max)
+{
+ m_graph->axisX()->setRange(min, max);
+}
+
+void SurfaceGraph::setAxisZRange(qreal min, qreal max)
+{
+ m_graph->axisZ()->setRange(min, max);
+}
+//! [5]
+
+//! [6]
+void SurfaceGraph::changeTheme(int theme)
+{
+ m_graph->setTheme((QDataVis::Theme)theme);
+}
+//! [6]
+
+void SurfaceGraph::setBlackToYellowGradient()
+{
+ //! [7]
+ QLinearGradient gr;
+ gr.setColorAt(0.0, Qt::black);
+ gr.setColorAt(0.33, Qt::blue);
+ gr.setColorAt(0.67, Qt::red);
+ gr.setColorAt(1.0, Qt::yellow);
+
+ m_graph->setGradient(gr);
+ //! [7]
+}
+
+void SurfaceGraph::setGreenToRedGradient()
+{
+ QLinearGradient gr;
+ gr.setColorAt(0.0, Qt::darkGreen);
+ gr.setColorAt(0.5, Qt::yellow);
+ gr.setColorAt(0.8, Qt::red);
+ gr.setColorAt(1.0, Qt::darkRed);
+
+ m_graph->setGradient(gr);
+}
+
diff --git a/examples/surface/surfacegraph.h b/examples/surface/surfacegraph.h
new file mode 100644
index 00000000..ac297bf6
--- /dev/null
+++ b/examples/surface/surfacegraph.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 SURFACEGRAPH_H
+#define SURFACEGRAPH_H
+
+#include <QtDataVisualization/Q3DSurface>
+#include <QtDataVisualization/QSurfaceDataProxy>
+#include <QtDataVisualization/QHeightMapSurfaceDataProxy>
+#include <QtWidgets/QSlider>
+
+using namespace QtDataVisualization;
+
+class SurfaceGraph : public QObject
+{
+ Q_OBJECT
+public:
+ explicit SurfaceGraph(Q3DSurface *surface);
+ ~SurfaceGraph();
+
+ void enableHeightMapModel();
+ void enableSqrtSinModel();
+
+ //! [0]
+ void toggleModeNone() { m_graph->setSelectionMode(QDataVis::SelectionModeNone); }
+ void toggleModeItem() { m_graph->setSelectionMode(QDataVis::SelectionModeItem); }
+ void toggleModeSliceRow() { m_graph->setSelectionMode(QDataVis::SelectionModeSliceRow); }
+ void toggleModeSliceColumn() { m_graph->setSelectionMode(QDataVis::SelectionModeSliceColumn); }
+ //! [0]
+
+ void setBlackToYellowGradient();
+ void setGreenToRedGradient();
+
+ void setAxisMinSliderX(QSlider *slider) { m_axisMinSliderX = slider; }
+ void setAxisMaxSliderX(QSlider *slider) { m_axisMaxSliderX = slider; }
+ void setAxisMinSliderZ(QSlider *slider) { m_axisMinSliderZ = slider; }
+ void setAxisMaxSliderZ(QSlider *slider) { m_axisMaxSliderZ = slider; }
+
+ void adjustXMin(int min);
+ void adjustXMax(int max);
+ void adjustZMin(int min);
+ void adjustZMax(int max);
+
+public slots:
+ void changeTheme(int theme);
+
+private:
+ Q3DSurface *m_graph;
+ QHeightMapSurfaceDataProxy *m_heightMapProxy;
+ QSurfaceDataProxy *sqrtSinProxy;
+
+ QSlider *m_axisMinSliderX;
+ QSlider *m_axisMaxSliderX;
+ QSlider *m_axisMinSliderZ;
+ QSlider *m_axisMaxSliderZ;
+ qreal m_rangeMinX;
+ qreal m_rangeMinZ;
+ qreal m_stepX;
+ qreal m_stepZ;
+ int m_heightMapWidth;
+ int m_heightMapHeight;
+
+ void setAxisXRange(qreal min, qreal max);
+ void setAxisZRange(qreal min, qreal max);
+ void fillSqrtSinProxy();
+};
+
+#endif // SURFACEGRAPH_H
diff --git a/examples/surfacechart/chartmodifier.cpp b/examples/surfacechart/chartmodifier.cpp
deleted file mode 100644
index b685a680..00000000
--- a/examples/surfacechart/chartmodifier.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-/****************************************************************************
-**
-** 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
deleted file mode 100644
index 3ab2d179..00000000
--- a/examples/surfacechart/chartmodifier.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/****************************************************************************
-**
-** 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
deleted file mode 100644
index 1297d92b..00000000
--- a/examples/surfacechart/main.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-/****************************************************************************
-**
-** 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
deleted file mode 100644
index 79fd967d..00000000
--- a/examples/surfacechart/surfacechart.pro
+++ /dev/null
@@ -1,11 +0,0 @@
-!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
deleted file mode 100644
index a8c6c14a..00000000
--- a/examples/widget/chart.cpp
+++ /dev/null
@@ -1,440 +0,0 @@
-/****************************************************************************
-**
-** 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 "chart.h"
-#include <QtDataVis3D/qcategoryaxis.h>
-#include <QtDataVis3D/qvalueaxis.h>
-#include <QtDataVis3D/qbardataproxy.h>
-#include <QTime>
-
-QT_DATAVIS3D_USE_NAMESPACE
-
-const QString celsiusString = QString(QChar(0xB0)) + "C";
-
-ChartModifier::ChartModifier(Q3DBars *barchart)
- : m_chart(barchart),
- m_columnCount(21),
- m_rowCount(21),
- m_xRotation(0.0f),
- m_yRotation(0.0f),
- m_static(true),
- m_barWidth(1.0f),
- m_barDepth(1.0f),
- m_barSpacingX(0.1f),
- m_barSpacingZ(0.1f),
- m_fontSize(20),
- 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()
-{
- delete m_chart;
-}
-
-void ChartModifier::start()
-{
- if (m_static)
- addDataSet();
-}
-
-void ChartModifier::restart(bool dynamicData)
-{
- m_static = !dynamicData;
-
- if (m_static) {
- start();
- // Set selection mode to zoom row
- m_chart->setSelectionMode(QDataVis::ModeZoomRow);
- m_chart->setFont(QFont("Times Roman", 20));
- } else {
- m_chart->dataProxy()->resetArray(0);
- // Set up sample space
- m_chart->setupSampleSpace(m_rowCount, m_columnCount);
- // Set selection mode to full
- 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));
- }
-}
-
-void ChartModifier::addDataSet()
-{
- // Prepare data to be visualized
- // Use QDataSet adder
-
- // Set window title
- m_chart->setWindowTitle(QStringLiteral("Average temperatures in Oulu, Finland (2006-2012)"));
-
- // Set up row and column names
- QStringList months;
- months << "January" << "February" << "March" << "April" << "May" << "June" << "July" << "August" << "September" << "October" << "November" << "December";
- QStringList years;
- years << "2006" << "2007" << "2008" << "2009" << "2010" << "2011" << "2012";
-
- // Set up data
- float temp[7][12] = {{-6.7f, -11.7f, -9.7f, 3.3f, 9.2f, 14.0f, 16.3f, 17.8f, 10.2f, 2.1f, -2.6f, -0.3f}, // 2006
- {-6.8f, -13.3f, 0.2f, 1.5f, 7.9f, 13.4f, 16.1f, 15.5f, 8.2f, 5.4f, -2.6f, -0.8f}, // 2007
- {-4.2f, -4.0f, -4.6f, 1.9f, 7.3f, 12.5f, 15.0f, 12.8f, 7.6f, 5.1f, -0.9f, -1.3f}, // 2008
- {-7.8f, -8.8f, -4.2f, 0.7f, 9.3f, 13.2f, 15.8f, 15.5f, 11.2f, 0.6f, 0.7f, -8.4f}, // 2009
- {-14.4f, -12.1f, -7.0f, 2.3f, 11.0f, 12.6f, 18.8f, 13.8f, 9.4f, 3.9f, -5.6f, -13.0f}, // 2010
- {-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
-
- // Use default data proxy to feed data directly in expected format
- QBarDataProxy *proxy = m_chart->dataProxy();
- proxy->setItemLabelFormat(celsiusString);
-
- // Add labels
- 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
- QBarDataArray *dataSet = new QBarDataArray;
- QBarDataRow *dataRow;
-
- dataSet->reserve(years.size());
- for (int year = 0; year < years.size(); year++) {
- dataRow = new QBarDataRow(months.size());
- // Create data items
- for (int month = 0; month < months.size(); month++) {
- // Add data to rows
- (*dataRow)[month].setValue(temp[year][month]);
- }
- // Add row to set
- dataSet->append(dataRow);
- }
-
- // Set up sample space based on prepared data
- 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);
- }
-}
-
-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::removeRows()
-{
- // 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()
-{
- static int model = 0;
- switch (model) {
- case 0:
- m_chart->setBarType(QDataVis::Cylinders, false);
- break;
- case 1:
- m_chart->setBarType(QDataVis::Cylinders, true);
- break;
- case 2:
- m_chart->setBarType(QDataVis::Cones, false);
- break;
- case 3:
- m_chart->setBarType(QDataVis::Cones, true);
- break;
- case 4:
- m_chart->setBarType(QDataVis::Bars, false);
- break;
- case 5:
- m_chart->setBarType(QDataVis::Bars, true);
- break;
- case 6:
- m_chart->setBarType(QDataVis::Pyramids, false);
- break;
- case 7:
- m_chart->setBarType(QDataVis::Pyramids, true);
- break;
- case 8:
- m_chart->setBarType(QDataVis::BevelBars, false);
- break;
- case 9:
- m_chart->setBarType(QDataVis::BevelBars, true);
- break;
- }
- model++;
- if (model > 9)
- model = 0;
-}
-
-void ChartModifier::changePresetCamera()
-{
- static int preset = QDataVis::PresetFrontLow;
-
- m_chart->setCameraPreset((QDataVis::CameraPreset)preset);
-
- if (++preset > QDataVis::PresetDirectlyBelow)
- preset = QDataVis::PresetFrontLow;
-}
-
-void ChartModifier::changeTheme()
-{
- static int theme = QDataVis::ThemeSystem;
-
- m_chart->setTheme((QDataVis::ColorTheme)theme);
-
- if (++theme > QDataVis::ThemeLight)
- theme = QDataVis::ThemeSystem;
-}
-
-void ChartModifier::changeTransparency()
-{
- static int transparency = QDataVis::TransparencyNone;
-
- m_chart->setLabelTransparency((QDataVis::LabelTransparency)transparency);
-
- if (++transparency > QDataVis::TransparencyNoBackground)
- transparency = QDataVis::TransparencyFromTheme;
-}
-
-void ChartModifier::changeSelectionMode()
-{
- static int selectionMode = QDataVis::ModeNone;
-
- m_chart->setSelectionMode((QDataVis::SelectionMode)selectionMode);
-
- if (++selectionMode > QDataVis::ModeZoomColumn)
- selectionMode = QDataVis::ModeNone;
-}
-
-void ChartModifier::changeFont(const QFont &font)
-{
- QFont newFont = font;
- newFont.setPointSize(m_fontSize);
- //qDebug() << newFont << newFont.style();
- m_chart->setFont(newFont);
-}
-
-void ChartModifier::changeFontSize(int fontsize)
-{
- m_fontSize = 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)
-{
- 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 ChartModifier::setBackgroundEnabled(int enabled)
-{
- m_chart->setBackgroundVisible((bool)enabled);
-}
-
-void ChartModifier::setGridEnabled(int enabled)
-{
- m_chart->setGridVisible((bool)enabled);
-}
-
-void ChartModifier::rotateX(int rotation)
-{
- m_xRotation = rotation;
- m_chart->setCameraPosition(m_xRotation, m_yRotation);
-}
-
-void ChartModifier::rotateY(int rotation)
-{
- m_yRotation = rotation;
- m_chart->setCameraPosition(m_xRotation, m_yRotation);
-}
-
-void ChartModifier::setSpecsX(int barwidth)
-{
- m_barWidth = (float)barwidth / 100.0f;
- m_chart->setBarSpecs(QSizeF(m_barWidth, m_barDepth), QSizeF(m_barSpacingX, m_barSpacingZ));
-}
-
-void ChartModifier::setSpecsZ(int bardepth)
-{
- m_barDepth = (float)bardepth / 100.0f;
- m_chart->setBarSpecs(QSizeF(m_barWidth, m_barDepth), QSizeF(m_barSpacingX, m_barSpacingZ));
-}
-
-void ChartModifier::setSpacingSpecsX(int spacing)
-{
- m_barSpacingX = (float)spacing / 100.0f;
- m_chart->setBarSpecs(QSizeF(m_barWidth, m_barDepth), QSizeF(m_barSpacingX, m_barSpacingZ));
-}
-
-void ChartModifier::setSpacingSpecsZ(int spacing)
-{
- m_barSpacingZ = (float)spacing / 100.0f;
- m_chart->setBarSpecs(QSizeF(m_barWidth, m_barDepth), QSizeF(m_barSpacingX, m_barSpacingZ));
-}
-
-void ChartModifier::setSampleCountX(int samples)
-{
- m_columnCount = samples;
- 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_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/doc/images/widget-example.png b/examples/widget/doc/images/widget-example.png
deleted file mode 100644
index 4fb43b42..00000000
--- a/examples/widget/doc/images/widget-example.png
+++ /dev/null
Binary files differ
diff --git a/examples/widget/doc/src/widget.qdoc b/examples/widget/doc/src/widget.qdoc
deleted file mode 100644
index 6645d356..00000000
--- a/examples/widget/doc/src/widget.qdoc
+++ /dev/null
@@ -1,29 +0,0 @@
-/****************************************************************************
-**
-** 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 widget
- \title Widget Example
-
- The widget example shows how to make a 3D bar chart using Q3DBars and combining the use of
- widgets for adjusting several adjustable qualities.
-
- \image widget-example.png
-
- TODO
-*/
diff --git a/qtdatavis3d.pro b/qtdatavisualization.pro
index 8a6fa51e..d7cb1c90 100644
--- a/qtdatavis3d.pro
+++ b/qtdatavisualization.pro
@@ -2,8 +2,8 @@ load(qt_parts)
# We need opengl, minimum es2 or desktop
!contains(QT_CONFIG, opengl) {
- error(QtDataVis3D requires OpenGL!)
+ error(QtDataVisualization requires OpenGL!)
}
contains(QT_CONFIG, opengles1) {
- error(QtDataVis3D does not support OpenGL ES 1!)
+ error(QtDataVisualization does not support OpenGL ES 1!)
}
diff --git a/src/datavis3d/axis/axis.pri b/src/datavis3d/axis/axis.pri
deleted file mode 100644
index 7d5a1c6f..00000000
--- a/src/datavis3d/axis/axis.pri
+++ /dev/null
@@ -1,12 +0,0 @@
-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
deleted file mode 100644
index 71b9effd..00000000
--- a/src/datavis3d/axis/qabstractaxis.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-/****************************************************************************
-**
-** 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_p.h b/src/datavis3d/axis/qabstractaxis_p.h
deleted file mode 100644
index 3866ee75..00000000
--- a/src/datavis3d/axis/qabstractaxis_p.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/****************************************************************************
-**
-** 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
deleted file mode 100644
index c20eb80f..00000000
--- a/src/datavis3d/axis/qcategoryaxis.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-/****************************************************************************
-**
-** 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/qvalueaxis.cpp b/src/datavis3d/axis/qvalueaxis.cpp
deleted file mode 100644
index cee8a5c7..00000000
--- a/src/datavis3d/axis/qvalueaxis.cpp
+++ /dev/null
@@ -1,235 +0,0 @@
-/****************************************************************************
-**
-** 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/data/maprenderitem.cpp b/src/datavis3d/data/maprenderitem.cpp
deleted file mode 100644
index c7165104..00000000
--- a/src/datavis3d/data/maprenderitem.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-/****************************************************************************
-**
-** 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
deleted file mode 100644
index f1e7290e..00000000
--- a/src/datavis3d/data/maprenderitem_p.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/****************************************************************************
-**
-** 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
deleted file mode 100644
index 11874edb..00000000
--- a/src/datavis3d/data/qabstractdataproxy.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-/****************************************************************************
-**
-** 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/qbardataproxy.cpp b/src/datavis3d/data/qbardataproxy.cpp
deleted file mode 100644
index 589ed37a..00000000
--- a/src/datavis3d/data/qbardataproxy.cpp
+++ /dev/null
@@ -1,262 +0,0 @@
-/****************************************************************************
-**
-** 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/qitemmodelbardatamapping.cpp b/src/datavis3d/data/qitemmodelbardatamapping.cpp
deleted file mode 100644
index 0aecb082..00000000
--- a/src/datavis3d/data/qitemmodelbardatamapping.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-/****************************************************************************
-**
-** 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/qitemmodelbardataproxy.cpp b/src/datavis3d/data/qitemmodelbardataproxy.cpp
deleted file mode 100644
index 4b3ed020..00000000
--- a/src/datavis3d/data/qitemmodelbardataproxy.cpp
+++ /dev/null
@@ -1,290 +0,0 @@
-/****************************************************************************
-**
-** 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
deleted file mode 100644
index 1d60bed6..00000000
--- a/src/datavis3d/data/qitemmodelbardataproxy.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/****************************************************************************
-**
-** 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
deleted file mode 100644
index c69b1679..00000000
--- a/src/datavis3d/data/qitemmodelbardataproxy_p.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/****************************************************************************
-**
-** 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
deleted file mode 100644
index a59be94b..00000000
--- a/src/datavis3d/data/qitemmodelmapdatamapping.cpp
+++ /dev/null
@@ -1,130 +0,0 @@
-/****************************************************************************
-**
-** 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
deleted file mode 100644
index 79080a65..00000000
--- a/src/datavis3d/data/qitemmodelmapdatamapping.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/****************************************************************************
-**
-** 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/qitemmodelmapdataproxy.cpp b/src/datavis3d/data/qitemmodelmapdataproxy.cpp
deleted file mode 100644
index b41384e9..00000000
--- a/src/datavis3d/data/qitemmodelmapdataproxy.cpp
+++ /dev/null
@@ -1,275 +0,0 @@
-/****************************************************************************
-**
-** 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
deleted file mode 100644
index 784ee162..00000000
--- a/src/datavis3d/data/qitemmodelmapdataproxy.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/****************************************************************************
-**
-** 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
deleted file mode 100644
index 64b16c7f..00000000
--- a/src/datavis3d/data/qitemmodelmapdataproxy_p.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/****************************************************************************
-**
-** 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
deleted file mode 100644
index 0b430b79..00000000
--- a/src/datavis3d/data/qitemmodelscatterdatamapping.cpp
+++ /dev/null
@@ -1,154 +0,0 @@
-/****************************************************************************
-**
-** 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/qitemmodelscatterdataproxy.cpp b/src/datavis3d/data/qitemmodelscatterdataproxy.cpp
deleted file mode 100644
index c4f4f0a7..00000000
--- a/src/datavis3d/data/qitemmodelscatterdataproxy.cpp
+++ /dev/null
@@ -1,305 +0,0 @@
-/****************************************************************************
-**
-** 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_p.h b/src/datavis3d/data/qitemmodelscatterdataproxy_p.h
deleted file mode 100644
index aed3d974..00000000
--- a/src/datavis3d/data/qitemmodelscatterdataproxy_p.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/****************************************************************************
-**
-** 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
deleted file mode 100644
index 2fe9b6e8..00000000
--- a/src/datavis3d/data/qmapdataitem.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-/****************************************************************************
-**
-** 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
deleted file mode 100644
index 240b03dd..00000000
--- a/src/datavis3d/data/qmapdataitem.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/****************************************************************************
-**
-** 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/qmapdataproxy.cpp b/src/datavis3d/data/qmapdataproxy.cpp
deleted file mode 100644
index a7a0e9d5..00000000
--- a/src/datavis3d/data/qmapdataproxy.cpp
+++ /dev/null
@@ -1,111 +0,0 @@
-/****************************************************************************
-**
-** 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
deleted file mode 100644
index 45bb95d5..00000000
--- a/src/datavis3d/data/qmapdataproxy.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/****************************************************************************
-**
-** 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/qscatterdataproxy.cpp b/src/datavis3d/data/qscatterdataproxy.cpp
deleted file mode 100644
index d2f544ef..00000000
--- a/src/datavis3d/data/qscatterdataproxy.cpp
+++ /dev/null
@@ -1,210 +0,0 @@
-/****************************************************************************
-**
-** 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/scatterrenderitem.cpp b/src/datavis3d/data/scatterrenderitem.cpp
deleted file mode 100644
index 15281c0a..00000000
--- a/src/datavis3d/data/scatterrenderitem.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/****************************************************************************
-**
-** 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/datavis3d.pro b/src/datavis3d/datavis3d.pro
deleted file mode 100644
index fa548c22..00000000
--- a/src/datavis3d/datavis3d.pro
+++ /dev/null
@@ -1,24 +0,0 @@
-TARGET = QtDataVis3D
-QT = core gui opengl #qml
-
-DEFINES += QT_DATAVIS3D_LIBRARY
-
-QMAKE_DOCS = $$PWD/doc/qtdatavis3d.qdocconf
-
-load(qt_module)
-
-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.
- # -O2/1 expands to /Og plus additional arguments.
- contains(DEFINES, MIPS) {
- QMAKE_CXXFLAGS_RELEASE ~= s/-O2/-Oi -Ot -Oy -Ob2/
- QMAKE_CXXFLAGS_RELEASE ~= s/-O1/-Os -Oy -Ob2/
- }
-}
diff --git a/src/datavis3d/doc/images/q3dbars-minimal.png b/src/datavis3d/doc/images/q3dbars-minimal.png
deleted file mode 100644
index 63b77998..00000000
--- a/src/datavis3d/doc/images/q3dbars-minimal.png
+++ /dev/null
Binary files differ
diff --git a/src/datavis3d/doc/qtdatavis3d.qdocconf b/src/datavis3d/doc/qtdatavis3d.qdocconf
deleted file mode 100644
index 0e9f6d5b..00000000
--- a/src/datavis3d/doc/qtdatavis3d.qdocconf
+++ /dev/null
@@ -1,33 +0,0 @@
-include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf)
-
-project = QtDataVis3D
-description = Qt Data Visualization 3D Reference Documentation
-version = 1.0.0
-
-exampledirs += ../../../examples \
- snippets
-
-headerdirs += ..
-imagedirs += ../images \
- images
-sourcedirs += ..
-
-depends += qtcore \
- qtgui
-
-qhp.projects = qtdatavis3d
-
-qhp.qtdatavis3d.file = qtdatavis3d.qhp
-qhp.qtdatavis3d.namespace = org.qt-project.qtdatavis3d.1.0.0
-qhp.qtdatavis3d.virtualFolder = qtdatavis3d
-qhp.qtdatavis3d.indexTitle = Qt Data Visualization 3D
-qhp.qtdatavis3d.indexRoot =
-
-qhp.qtdatavis3d.filterAttributes = qtdatavis3d 1.0.0 qtrefdoc
-qhp.qtdatavis3d.customFilters.Qt.name = QtDataVis3D 1.0.0
-qhp.qtdatavis3d.customFilters.Qt.filterAttributes = qtdatavis3d 1.0.0
-qhp.qtdatavis3d.subprojects = classes
-qhp.qtdatavis3d.subprojects.classes.title = C++ Classes
-qhp.qtdatavis3d.subprojects.classes.indexTitle = Qt Data Visualization 3D C++ Classes
-qhp.qtdatavis3d.subprojects.classes.selectors = class fake:headerfile
-qhp.qtdatavis3d.subprojects.classes.sortPages = true
diff --git a/src/datavis3d/doc/snippets/doc_src_qtdatavis3d.cpp b/src/datavis3d/doc/snippets/doc_src_qtdatavis3d.cpp
deleted file mode 100644
index a3b3e8e8..00000000
--- a/src/datavis3d/doc/snippets/doc_src_qtdatavis3d.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-/****************************************************************************
-**
-** 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
-**
-****************************************************************************/
-
-//! [0]
-#include <QtDataVis3D>
-//! [0]
diff --git a/src/datavis3d/doc/src/qtdatavis3d-index.qdoc b/src/datavis3d/doc/src/qtdatavis3d-index.qdoc
deleted file mode 100644
index dae2a14d..00000000
--- a/src/datavis3d/doc/src/qtdatavis3d-index.qdoc
+++ /dev/null
@@ -1,62 +0,0 @@
-/****************************************************************************
-**
-** 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
-**
-****************************************************************************/
-
-/*!
- \title Qt Data Visualization 3D
- \page qtdatavis3d-index.html
- \brief QtDataVis3D module provides functionality for 3D visualization.
-
- Qt Data Visualization module provides a way to visualize data in 3D.
- It uses OpneGL for the data rendering.
-
- \section1 Getting Started
-
- Qt Data Visualization provides classes for rendering 3D data. To include
- the definitions of the module's classes, use the following directive:
-
- \snippet doc_src_qtdatavis3d.cpp 0
-
- To link against the module, add this line to your \l qmake \c
- .pro file:
-
- \snippet doc_src_qtdatavis3d.pro 0
-
- \section1 Articles
- \list
- \li \l{Qt Data Visualization 3D License Information}{License Information}
- \endlist
-
- \section1 References
- \list
- \li \l{Qt Data Visualization 3D C++ Classes}
- \endlist
-
- Qt Data Visualization 3D comes with the following examples:
-
- \list
- \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
deleted file mode 100644
index c27fe0a3..00000000
--- a/src/datavis3d/doc/src/qtdatavis3d.qdoc
+++ /dev/null
@@ -1,26 +0,0 @@
-/****************************************************************************
-**
-** 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
-**
-****************************************************************************/
-
-/*!
- \module QtDataVis3D
- \title Qt Data Visualization 3D C++ Classes
- \ingroup modules
-
- \brief The QtDataVis3D module provides functionality for 3D visualization.
-*/
-
diff --git a/src/datavis3d/doc/src/qtdatavis3dlicense.qdoc b/src/datavis3d/doc/src/qtdatavis3dlicense.qdoc
deleted file mode 100644
index 610fb9b7..00000000
--- a/src/datavis3d/doc/src/qtdatavis3dlicense.qdoc
+++ /dev/null
@@ -1,31 +0,0 @@
-/****************************************************************************
-**
-** 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
-**
-****************************************************************************/
-
-/*!
- \page qtdatavis3dlicense.html
- \title Qt Data Visualization 3D License Information
- \ingroup licensing
- \brief License information for Qt Data Visualization 3D
-
- TODO
-
- \legalese
- TODO
- \endlegalese
-
-*/
diff --git a/src/datavis3d/engine/abstract3dcontroller.cpp b/src/datavis3d/engine/abstract3dcontroller.cpp
deleted file mode 100644
index 12f76fd1..00000000
--- a/src/datavis3d/engine/abstract3dcontroller.cpp
+++ /dev/null
@@ -1,698 +0,0 @@
-/****************************************************************************
-**
-** 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/abstract3drenderer.cpp b/src/datavis3d/engine/abstract3drenderer.cpp
deleted file mode 100644
index b25e5a15..00000000
--- a/src/datavis3d/engine/abstract3drenderer.cpp
+++ /dev/null
@@ -1,219 +0,0 @@
-/****************************************************************************
-**
-** 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/bars3dcontroller.cpp b/src/datavis3d/engine/bars3dcontroller.cpp
deleted file mode 100644
index 86ceff72..00000000
--- a/src/datavis3d/engine/bars3dcontroller.cpp
+++ /dev/null
@@ -1,459 +0,0 @@
-/****************************************************************************
-**
-** 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());
-
- // Default bar type; specific to bars
- setBarType(QDataVis::Bars, false);
-
- 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);
- synchDataToRenderer();
-}
-
-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/maps3dcontroller.cpp b/src/datavis3d/engine/maps3dcontroller.cpp
deleted file mode 100644
index e86bdfa2..00000000
--- a/src/datavis3d/engine/maps3dcontroller.cpp
+++ /dev/null
@@ -1,1763 +0,0 @@
-/****************************************************************************
-**
-** 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
deleted file mode 100644
index d0c2e74e..00000000
--- a/src/datavis3d/engine/maps3dcontroller_p.h
+++ /dev/null
@@ -1,253 +0,0 @@
-/****************************************************************************
-**
-** 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
deleted file mode 100644
index c05f2f51..00000000
--- a/src/datavis3d/engine/maps3drenderer.cpp
+++ /dev/null
@@ -1,74 +0,0 @@
-/****************************************************************************
-**
-** 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
deleted file mode 100644
index 89054e83..00000000
--- a/src/datavis3d/engine/maps3drenderer_p.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/****************************************************************************
-**
-** 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/q3dbars.cpp b/src/datavis3d/engine/q3dbars.cpp
deleted file mode 100644
index bd9f9f09..00000000
--- a/src/datavis3d/engine/q3dbars.cpp
+++ /dev/null
@@ -1,487 +0,0 @@
-/****************************************************************************
-**
-** 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 "q3dbars.h"
-#include "q3dbars_p.h"
-#include "bars3dcontroller_p.h"
-#include "qvalueaxis.h"
-
-#include <QMouseEvent>
-
-#include <QDebug>
-
-QT_DATAVIS3D_BEGIN_NAMESPACE
-
-/*!
- * \class Q3DBars
- * \inmodule QtDataVis3D
- * \brief The Q3DBars class provides methods for rendering 3D bar 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 Q3DBars chart
- *
- * After constructing Q3DBars, you need to set up sample space using setupSampleSpace(). Let's
- * set the sample space to 5 rows and 5 columns:
- *
- * \snippet doc_src_q3dbars_construction.cpp 0
- *
- * Now Q3DBars is ready to receive data to be rendered. Add one row of 5 floats into the data
- * set:
- *
- * \snippet doc_src_q3dbars_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_q3dbars_construction.cpp 2
- *
- * The complete code needed to create and display this chart is:
- *
- * \snippet doc_src_q3dbars_construction.cpp 3
- *
- * And this is what those few lines of code produce:
- *
- * \image q3dbars-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 bar window.
- */
-Q3DBars::Q3DBars()
- : d_ptr(new Q3DBarsPrivate(this, geometry()))
-{
- d_ptr->m_shared->initializeOpenGL();
- QObject::connect(d_ptr->m_shared, &Abstract3DController::shadowQualityChanged, this,
- &Q3DBars::handleShadowQualityUpdate);
-}
-
-/*!
- * Destroys the 3d bar window.
- */
-Q3DBars::~Q3DBars()
-{
-}
-
-/*!
- * \internal
- */
-void Q3DBars::render()
-{
- d_ptr->m_shared->synchDataToRenderer();
- d_ptr->m_shared->render();
-}
-
-void Q3DBars::handleShadowQualityUpdate(QDataVis::ShadowQuality quality)
-{
- emit shadowQualityChanged(quality);
-}
-
-#if defined(Q_OS_ANDROID)
-/*!
- * \internal
- */
-void Q3DBars::mouseDoubleClickEvent(QMouseEvent *event)
-{
- d_ptr->m_shared->mouseDoubleClickEvent(event);
-}
-
-/*!
- * \internal
- */
-void Q3DBars::touchEvent(QTouchEvent *event)
-{
- d_ptr->m_shared->touchEvent(event);
-}
-#endif
-
-/*!
- * \internal
- */
-void Q3DBars::mousePressEvent(QMouseEvent *event)
-{
- d_ptr->m_shared->mousePressEvent(event, event->pos());
-}
-
-/*!
- * \internal
- */
-void Q3DBars::mouseReleaseEvent(QMouseEvent *event)
-{
- d_ptr->m_shared->mouseReleaseEvent(event, event->pos());
-}
-
-/*!
- * \internal
- */
-void Q3DBars::mouseMoveEvent(QMouseEvent *event)
-{
- d_ptr->m_shared->mouseMoveEvent(event, event->pos());
-}
-
-/*!
- * \internal
- */
-void Q3DBars::wheelEvent(QWheelEvent *event)
-{
- d_ptr->m_shared->wheelEvent(event);
-}
-
-/*!
- * \internal
- */
-void Q3DBars::resizeEvent(QResizeEvent *event)
-{
- Q_UNUSED(event);
- d_ptr->m_shared->setSize(width(), height());
-}
-
-// TODO: Document
-// Size
-void Q3DBars::setWidth(const int width)
-{
- d_ptr->m_shared->setWidth(width);
- QWindow::setWidth(width);
-}
-
-void Q3DBars::setHeight(const int height)
-{
- d_ptr->m_shared->setHeight(height);
- QWindow::setHeight(height);
-}
-
-/*!
- * \a thickness Thickness of a bar in x and z axes.
- *
- * \a spacing Spacing between bars in x and z axes. If relative -flag is true, value of 0.0f
- * means the bars are side-to-side and for example 1.0f means there is one thickness in between the
- * bars.
- *
- * \a relative A flag to indicate if spacing is meant to be absolute or relative. \c true by
- * default.
- *
- * Sets bar specifications. Bar thickness is relative, as scene is automatically scaled to fit into
- * the view.
- */
-void Q3DBars::setBarSpecs(QSizeF thickness, QSizeF spacing, bool relative)
-{
- d_ptr->m_shared->setBarSpecs(thickness, spacing, relative);
-}
-
-/*!
- * \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.
- *
- * Sets the bar type to one of the supplied ones.
- *
- * \sa setMeshFileName()
- */
-void Q3DBars::setBarType(QDataVis::MeshStyle style, bool smooth)
-{
- d_ptr->m_shared->setBarType(style, smooth);
-}
-
-/*!
- * \a samplesRow How many rows of data there will be.
- *
- * \a samplesColumn How many items there are per row.
- *
- * 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)
-{
- 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 QDataVis::CameraPreset.
- *
- * Moves camera to a predefined position.
- */
-void Q3DBars::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 either -90...90 or 0...90 in vertical, depending
- * 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(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 bar colors, label colors, text color, background color,
- * window color and grid color. Lighting is also adjusted by themes.
- */
-void Q3DBars::setTheme(QDataVis::ColorTheme theme)
-{
- d_ptr->m_shared->setColorTheme(theme);
-}
-
-/*!
- * \a baseColor The base color of a bar. If all other colors are black, this sets the final color of
- * the bar.
- *
- * \a heightColor This color is added to the bar based on its height. The higher the bar, the more
- * prominent this color becomes. Setting this black keeps the color unchanged regardless of height.
- *
- * \a depthColor This color becomes more prominent the further away from the first row the bar is.
- * Setting this black keeps bars the same color regardless of "depth" in the set.
- *
- * \a uniform A flag to define if color needs to be uniform throughout bar's length, or will the
- * colors be applied by height. \c true by default.
- *
- * Set bar color using your own colors. This overrides colors from theme.
- */
-void Q3DBars::setBarColor(QColor baseColor, QColor heightColor, QColor depthColor, bool uniform)
-{
- d_ptr->m_shared->setObjectColor(baseColor, heightColor, depthColor, uniform);
-}
-
-/*!
- * \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(QDataVis::SelectionMode mode)
-{
- d_ptr->m_shared->setSelectionMode(mode);
-}
-
-QDataVis::SelectionMode Q3DBars::selectionMode() const
-{
- return d_ptr->m_shared->selectionMode();
-}
-
-/*!
- * \property Q3DBars::windowTitle
- *
- * \a title QString label to be used as window title.
- *
- * Sets the window title. The default is application executable name.
- */
-void Q3DBars::setWindowTitle(const QString &title)
-{
- setTitle(title);
-}
-
-QString Q3DBars::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 bar type with an object mesh. \sa setBarType()
- */
-void Q3DBars::setMeshFileName(const QString &objFileName)
-{
- d_ptr->m_shared->setMeshFileName(objFileName);
-}
-
-/*!
- * \property Q3DBars::fontSize
- *
- * \a fontsize Size of the font.
- *
- * Sets font size.
- */
-void Q3DBars::setFontSize(float fontsize)
-{
- d_ptr->m_shared->setFontSize(fontsize);
-}
-
-float Q3DBars::fontSize()
-{
- return d_ptr->m_shared->fontSize();
-}
-
-/*!
- * \property Q3DBars::font
- *
- * \a font QFont to be used for labels. \c Arial by default.
- *
- * Sets the font for labels.
- */
-void Q3DBars::setFont(const QFont &font)
-{
- d_ptr->m_shared->setFont(font);
-}
-
-QFont Q3DBars::font() const
-{
- return d_ptr->m_shared->font();
-}
-
-/*!
- * \property Q3DBars::labelTransparency
- *
- * \a transparency Transparency level of labels from \c QDataVis::LabelTransparency.
- * \c TransparencyFromTheme by default.
- *
- * Sets label transparency.
- */
-void Q3DBars::setLabelTransparency(QDataVis::LabelTransparency transparency)
-{
- d_ptr->m_shared->setLabelTransparency(transparency);
-}
-
-QDataVis::LabelTransparency Q3DBars::labelTransparency() const
-{
- return d_ptr->m_shared->labelTransparency();
-}
-
-/*!
- * \property Q3DBars::gridVisible
- *
- * \a visible Flag to enable or disable grid. \c true by default.
- *
- * Sets grid drawing on or off.
- */
-void Q3DBars::setGridVisible(bool visible)
-{
- d_ptr->m_shared->setGridEnabled(visible);
-}
-
-bool Q3DBars::isGridVisible() const
-{
- return d_ptr->m_shared->gridEnabled();
-}
-
-/*!
- * \property Q3DBars::backgroundVisible
- *
- * \a visible Flag to enable or disable background. \c true by default.
- *
- * Sets backround rendering on or off.
- */
-void Q3DBars::setBackgroundVisible(bool visible)
-{
- d_ptr->m_shared->setBackgroundEnabled(visible);
-}
-
-bool Q3DBars::isBackgroundVisible() const
-{
- return d_ptr->m_shared->backgroundEnabled();
-}
-
-/*!
- * \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(QDataVis::ShadowQuality quality)
-{
- return d_ptr->m_shared->setShadowQuality(quality);
-}
-
-QDataVis::ShadowQuality Q3DBars::shadowQuality() const
-{
- return d_ptr->m_shared->shadowQuality();
-}
-
-QCategoryAxis *Q3DBars::rowAxis()
-{
- return reinterpret_cast<QCategoryAxis *>(d_ptr->m_shared->axisX());
-}
-
-QCategoryAxis *Q3DBars::columnAxis()
-{
- return reinterpret_cast<QCategoryAxis *>(d_ptr->m_shared->axisZ());
-}
-
-void Q3DBars::setValueAxis(QValueAxis *axis)
-{
- Q_ASSERT(axis);
-
- return d_ptr->m_shared->setAxisY(axis);
-}
-
-QValueAxis *Q3DBars::valueAxis()
-{
- return static_cast<QValueAxis *>(d_ptr->m_shared->axisY());
-}
-
-void Q3DBars::setDataProxy(QBarDataProxy *proxy)
-{
- d_ptr->m_shared->setDataProxy(proxy);
-}
-
-QBarDataProxy *Q3DBars::dataProxy()
-{
- return d_ptr->m_shared->dataProxy();
-}
-
-Q3DBarsPrivate::Q3DBarsPrivate(Q3DBars *q, QRect rect)
- : q_ptr(q),
- m_shared(new Bars3dController(rect))
-{
-}
-
-Q3DBarsPrivate::~Q3DBarsPrivate()
-{
- qDebug() << "Destroying Q3DBarsPrivate";
- delete m_shared;
-}
-
-QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/engine/q3dbars.h b/src/datavis3d/engine/q3dbars.h
deleted file mode 100644
index a0eb9cb5..00000000
--- a/src/datavis3d/engine/q3dbars.h
+++ /dev/null
@@ -1,163 +0,0 @@
-/****************************************************************************
-**
-** 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 Q3DBARS_H
-#define Q3DBARS_H
-
-#include <QtDataVis3D/qdatavis3denums.h>
-#include <QtDataVis3D/q3dwindow.h>
-#include <QFont>
-
-QT_DATAVIS3D_BEGIN_NAMESPACE
-
-class Q3DBarsPrivate;
-class QCategoryAxis;
-class QValueAxis;
-class QBarDataProxy;
-
-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 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();
- ~Q3DBars();
-
- // 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(QDataVis::MeshStyle style, bool smooth = false);
-
- // how many samples per row and column, and names for axes
- // 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
- 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))
- 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)
- 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, QColor depthColor,
- bool uniform = true);
-
- // override bar type with own mesh
- void setMeshFileName(const QString &objFileName);
- // 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() const;
-
- // Set window title
- void setWindowTitle(const QString &title);
- QString windowTitle() const;
-
- // Font size adjustment
- void setFontSize(float fontsize);
- float fontSize();
-
- // 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 - 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 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<Q3DBarsPrivate> d_ptr;
- Q_DISABLE_COPY(Q3DBars)
-};
-
-QT_DATAVIS3D_END_NAMESPACE
-
-#endif
diff --git a/src/datavis3d/engine/q3dmaps.cpp b/src/datavis3d/engine/q3dmaps.cpp
deleted file mode 100644
index ffa5ed1b..00000000
--- a/src/datavis3d/engine/q3dmaps.cpp
+++ /dev/null
@@ -1,270 +0,0 @@
-/****************************************************************************
-**
-** 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 "q3dmaps.h"
-#include "q3dmaps_p.h"
-#include "maps3dcontroller_p.h"
-
-#include <QMouseEvent>
-
-#include <QDebug>
-
-QT_DATAVIS3D_BEGIN_NAMESPACE
-
-/*!
- * \class Q3DMaps
- * \inmodule QtDataVis3D
- * \brief The Q3DMaps class provides methods for rendering 3D bars on maps or other planes.
- * \since 1.0.0
- *
- * This class enables developers to render bars or objects on maps or other planes in 3D and to
- * view them by rotating the scene freely. Methods are provided for changing object types, themes
- * and so on.
- *
- * See methods themselves for more complete description.
- *
- * \sa Q3DBars, {Qt Data Visualization 3D C++ Classes}
- */
-
-/*!
- * Constructs Q3DMaps.
- */
-Q3DMaps::Q3DMaps()
- : d_ptr(new Q3DMapsPrivate(this, geometry()))
-{
- d_ptr->m_shared->initializeOpenGL();
-}
-
-/*!
- * Destructs Q3DMaps.
- */
-Q3DMaps::~Q3DMaps()
-{
-}
-
-/*!
- * \internal
- */
-void Q3DMaps::render()
-{
- d_ptr->m_shared->render();
-}
-
-#if defined(Q_OS_ANDROID)
-/*!
- * \internal
- */
-void Q3DMaps::mouseDoubleClickEvent(QMouseEvent *event)
-{
- d_ptr->m_shared->mouseDoubleClickEvent(event);
-}
-
-/*!
- * \internal
- */
-void Q3DMaps::touchEvent(QTouchEvent *event)
-{
- d_ptr->m_shared->touchEvent(event);
-}
-#endif
-
-/*!
- * \internal
- */
-void Q3DMaps::mousePressEvent(QMouseEvent *event)
-{
- d_ptr->m_shared->mousePressEvent(event, event->pos());
-}
-
-/*!
- * \internal
- */
-void Q3DMaps::mouseReleaseEvent(QMouseEvent *event)
-{
- d_ptr->m_shared->mouseReleaseEvent(event, event->pos());
-}
-
-/*!
- * \internal
- */
-void Q3DMaps::mouseMoveEvent(QMouseEvent *event)
-{
- d_ptr->m_shared->mouseMoveEvent(event, event->pos());
-}
-
-/*!
- * \internal
- */
-void Q3DMaps::wheelEvent(QWheelEvent *event)
-{
- d_ptr->m_shared->wheelEvent(event);
-}
-
-/*!
- * \internal
- */
-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();
-}
-
-// TODO: Document
-// Size
-void Q3DMaps::setWidth(const int width)
-{
- d_ptr->m_shared->setWidth(width);
- QWindow::setWidth(width);
-}
-
-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_shared->setBarSpecs(thickness, direction);
-}
-
-void Q3DMaps::setBarType(QDataVis::MeshStyle style, bool smooth)
-{
- d_ptr->m_shared->setBarType(style, smooth);
-}
-
-void Q3DMaps::setMeshFileName(const QString &objFileName)
-{
- d_ptr->m_shared->setMeshFileName(objFileName);
-}
-
-void Q3DMaps::setCameraPreset(QDataVis::CameraPreset preset)
-{
- d_ptr->m_shared->setCameraPreset(preset);
-}
-
-void Q3DMaps::setCameraPosition(GLfloat horizontal, GLfloat vertical, GLint distance)
-{
- d_ptr->m_shared->setCameraPosition(horizontal, vertical, distance);
-}
-
-void Q3DMaps::setTheme(QDataVis::ColorTheme theme)
-{
- d_ptr->m_shared->setTheme(theme);
-}
-
-void Q3DMaps::setBarColor(QColor baseColor, QColor heightColor, bool uniform)
-{
- d_ptr->m_shared->setBarColor(baseColor, heightColor, uniform);
-}
-
-void Q3DMaps::setAreaSpecs(const QRect &areaRect, const QImage &image)
-{
- d_ptr->m_shared->setAreaSpecs(areaRect, image);
-}
-
-void Q3DMaps::setImage(const QImage &image)
-{
- d_ptr->m_shared->setImage(image);
-}
-
-void Q3DMaps::setSelectionMode(QDataVis::SelectionMode mode)
-{
- d_ptr->m_shared->setSelectionMode(mode);
-}
-
-QDataVis::SelectionMode Q3DMaps::selectionMode() const
-{
- return d_ptr->m_shared->selectionMode();
-}
-
-void Q3DMaps::setWindowTitle(const QString &title)
-{
- setTitle(title);
-}
-
-QString Q3DMaps::windowTitle() const
-{
- return title();
-}
-
-void Q3DMaps::setFontSize(float fontsize)
-{
- d_ptr->m_shared->setFontSize(fontsize);
-}
-
-float Q3DMaps::fontSize() const
-{
- return d_ptr->m_shared->fontSize();
-}
-
-void Q3DMaps::setFont(const QFont &font)
-{
- d_ptr->m_shared->setFont(font);
-}
-
-QFont Q3DMaps::font() const
-{
- return d_ptr->m_shared->font();
-}
-
-void Q3DMaps::setLabelTransparency(QDataVis::LabelTransparency transparency)
-{
- d_ptr->m_shared->setLabelTransparency(transparency);
-}
-
-QDataVis::LabelTransparency Q3DMaps::labelTransparency() const
-{
- return d_ptr->m_shared->labelTransparency();
-}
-
-QDataVis::ShadowQuality Q3DMaps::setShadowQuality(QDataVis::ShadowQuality quality)
-{
- return d_ptr->m_shared->setShadowQuality(quality);
-}
-
-QDataVis::ShadowQuality Q3DMaps::shadowQuality() const
-{
- return d_ptr->m_shared->shadowQuality();
-}
-
-void Q3DMaps::setDataProxy(QMapDataProxy *proxy)
-{
- d_ptr->m_shared->setDataProxy(proxy);
-}
-
-QMapDataProxy *Q3DMaps::dataProxy()
-{
- return d_ptr->m_shared->dataProxy();
-}
-
-Q3DMapsPrivate::Q3DMapsPrivate(Q3DMaps *q, const QRect &rect)
- : q_ptr(q),
- m_shared(new Maps3DController(rect))
-{
-}
-
-Q3DMapsPrivate::~Q3DMapsPrivate()
-{
- qDebug() << "Destroying Q3DMapsPrivate";
- delete m_shared;
-}
-
-QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3d/engine/q3dmaps.h b/src/datavis3d/engine/q3dmaps.h
deleted file mode 100644
index 195b91e0..00000000
--- a/src/datavis3d/engine/q3dmaps.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/****************************************************************************
-**
-** 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 Q3DMAPS_H
-#define Q3DMAPS_H
-
-#include <QtDataVis3D/qdatavis3denums.h>
-#include <QtDataVis3D/q3dwindow.h>
-
-#include <QFont>
-#include <QVector3D>
-
-class QImage;
-class QRect;
-
-QT_DATAVIS3D_BEGIN_NAMESPACE
-
-class Maps3DController;
-class Q3DMapsPrivate;
-class QMapDataProxy;
-
-class QT_DATAVIS3D_EXPORT Q3DMaps : public Q3DWindow
-{
- Q_OBJECT
- Q_PROPERTY(QString windowTitle READ windowTitle WRITE setWindowTitle)
- Q_PROPERTY(QFont font READ font WRITE setFont)
- Q_PROPERTY(float fontSize READ fontSize WRITE setFontSize)
-
-public:
-
- enum AdjustmentDirection {
- AdjustHeight = 0, // map value to y
- AdjustWidth, // map value to x
- AdjustDepth, // map value to z
- AdjustRadius, // map value to x and z
- AdjustAll // map value to all (x, y, z)
- };
-
-public:
- explicit Q3DMaps();
- ~Q3DMaps();
-
- 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.
- void setBarSpecs(const QVector3D &thickness = QVector3D(1.0f, 1.0f, 1.0f),
- AdjustmentDirection direction = 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() 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;
-
- // Adjust shadow quality
- 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 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<Q3DMapsPrivate> d_ptr;
- Q_DISABLE_COPY(Q3DMaps)
-};
-
-QT_DATAVIS3D_END_NAMESPACE
-
-#endif
diff --git a/src/datavis3d/engine/q3dscatter.cpp b/src/datavis3d/engine/q3dscatter.cpp
deleted file mode 100644
index 73332bdd..00000000
--- a/src/datavis3d/engine/q3dscatter.cpp
+++ /dev/null
@@ -1,463 +0,0 @@
-/****************************************************************************
-**
-** 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, &Abstract3DController::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
deleted file mode 100644
index 73a7d214..00000000
--- a/src/datavis3d/engine/q3dscatter.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/****************************************************************************
-**
-** 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/q3dsurface.cpp b/src/datavis3d/engine/q3dsurface.cpp
deleted file mode 100644
index 7647ad10..00000000
--- a/src/datavis3d/engine/q3dsurface.cpp
+++ /dev/null
@@ -1,181 +0,0 @@
-/****************************************************************************
-**
-** 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
deleted file mode 100644
index c2deea9a..00000000
--- a/src/datavis3d/engine/q3dsurface.h
+++ /dev/null
@@ -1,84 +0,0 @@
-/****************************************************************************
-**
-** 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/scatter3dcontroller.cpp b/src/datavis3d/engine/scatter3dcontroller.cpp
deleted file mode 100644
index ef56fc23..00000000
--- a/src/datavis3d/engine/scatter3dcontroller.cpp
+++ /dev/null
@@ -1,367 +0,0 @@
-/****************************************************************************
-**
-** 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());
-
- // Default object type; specific to scatter
- setObjectType(QDataVis::Spheres, false);
-
- 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);
- synchDataToRenderer();
-}
-
-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/shaders/surfaceGrid.frag b/src/datavis3d/engine/shaders/surfaceGrid.frag
deleted file mode 100644
index 20b923fb..00000000
--- a/src/datavis3d/engine/shaders/surfaceGrid.frag
+++ /dev/null
@@ -1,16 +0,0 @@
-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
deleted file mode 100644
index efb40862..00000000
--- a/src/datavis3d/engine/shaders/surfaceGrid.vert
+++ /dev/null
@@ -1,26 +0,0 @@
-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
deleted file mode 100644
index 2915c993..00000000
--- a/src/datavis3d/engine/surface3dcontroller.cpp
+++ /dev/null
@@ -1,211 +0,0 @@
-/****************************************************************************
-**
-** 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
deleted file mode 100644
index d8c36d08..00000000
--- a/src/datavis3d/engine/surface3dcontroller_p.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/****************************************************************************
-**
-** 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
deleted file mode 100644
index c66bd291..00000000
--- a/src/datavis3d/engine/surface3drenderer.cpp
+++ /dev/null
@@ -1,894 +0,0 @@
-/****************************************************************************
-**
-** 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/theme.cpp b/src/datavis3d/engine/theme.cpp
deleted file mode 100644
index 7b2cb210..00000000
--- a/src/datavis3d/engine/theme.cpp
+++ /dev/null
@@ -1,307 +0,0 @@
-/****************************************************************************
-**
-** 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 "theme_p.h"
-
-#ifdef Q_OS_WIN
-#include <windows.h>
-#include <stdio.h>
-#endif
-
-QT_DATAVIS3D_BEGIN_NAMESPACE
-
-Theme::Theme()
- : m_baseColor(QColor(Qt::gray)),
- m_heightColor(QColor(Qt::black)),
- m_depthColor(QColor(Qt::black)),
- m_backgroundColor(QColor(Qt::gray)),
- m_windowColor(QColor(Qt::gray)),
- m_textColor(QColor(Qt::white)),
- m_textBackgroundColor(QColor(0x00, 0x00, 0x00, 0x80)),
- m_gridLine(QColor(Qt::black)),
- 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()
-{
-}
-
-QDataVis::ColorTheme Theme::colorTheme()
-{
- return m_colorTheme;
-}
-
-void Theme::useColorTheme(QDataVis::ColorTheme colorTheme)
-{
- m_colorTheme = colorTheme;
- switch (colorTheme) {
- case QDataVis::ThemeSystem: {
-#ifdef Q_OS_WIN
- DWORD colorHighlight;
- colorHighlight = GetSysColor(COLOR_HIGHLIGHT);
- m_baseColor = QColor(GetRValue(colorHighlight),
- GetGValue(colorHighlight),
- GetBValue(colorHighlight));
- DWORD colorWindowFrame;
- colorWindowFrame = GetSysColor(COLOR_WINDOWFRAME);
- m_heightColor = QColor(GetRValue(colorWindowFrame),
- GetGValue(colorWindowFrame),
- GetBValue(colorWindowFrame));
- m_depthColor = QColor(Qt::black);
- DWORD colorWindow;
- colorWindow = GetSysColor(COLOR_WINDOW);
- m_backgroundColor = QColor(GetRValue(colorWindow),
- GetGValue(colorWindow),
- GetBValue(colorWindow));
- m_windowColor = QColor(GetRValue(colorWindow),
- GetGValue(colorWindow),
- GetBValue(colorWindow));
- m_textColor = QColor(QRgb(0x404044));
- m_textBackgroundColor = QColor(0xd6, 0xd6, 0xd6, 0x80);
- m_gridLine = QColor(QRgb(0xe2e2e2));
- m_highlightBarColor = QColor(QRgb(0xe2e2e2));
- m_highlightRowColor = QColor(QRgb(0xf2f2f2));
- m_highlightColumnColor = QColor(QRgb(0xf2f2f2));
- m_lightStrength = 4.0f;
- m_ambientStrength = 0.3f;
- m_highlightLightStrength = 6.0f;
- m_uniformColor = true;
-#elif defined(Q_OS_LINUX)
- m_baseColor = QColor(QRgb(0x60a6e6));
- m_heightColor = QColor(QRgb(0xfc5751));
- m_depthColor = QColor(QRgb(0x92ca66));
- m_backgroundColor = QColor(QRgb(0xffffff));
- m_windowColor = QColor(QRgb(0xffffff));
- m_textColor = QColor(QRgb(0x404044));
- m_textBackgroundColor = QColor(0xd6, 0xd6, 0xd6, 0x80);
- m_gridLine = QColor(QRgb(0xe2e2e2));
- m_highlightBarColor = QColor(QRgb(0xeba85f));
- m_highlightRowColor = QColor(QRgb(0xfc5751));
- m_highlightColumnColor = QColor(QRgb(0xfc5751));
- m_lightStrength = 4.0f;
- m_ambientStrength = 0.3f;
- m_highlightLightStrength = 6.0f;
- m_uniformColor = true;
-#elif defined(Q_OS_MAC)
- m_baseColor = QColor(QRgb(0x60a6e6));
- m_heightColor = QColor(QRgb(0xfc5751));
- m_depthColor = QColor(QRgb(0x92ca66));
- m_backgroundColor = QColor(QRgb(0xffffff));
- m_windowColor = QColor(QRgb(0xffffff));
- m_textColor = QColor(QRgb(0x404044));
- m_textBackgroundColor = QColor(0xd6, 0xd6, 0xd6, 0x80);
- m_gridLine = QColor(QRgb(0xe2e2e2));
- m_highlightBarColor = QColor(QRgb(0xeba85f));
- m_highlightRowColor = QColor(QRgb(0xfc5751));
- m_highlightColumnColor = QColor(QRgb(0xfc5751));
- m_lightStrength = 4.0f;
- m_ambientStrength = 0.3f;
- m_highlightLightStrength = 6.0f;
- m_uniformColor = true;
-#else
- m_baseColor = QColor(QRgb(0x60a6e6));
- m_heightColor = QColor(QRgb(0xfc5751));
- m_depthColor = QColor(QRgb(0x92ca66));
- m_backgroundColor = QColor(QRgb(0xffffff));
- m_windowColor = QColor(QRgb(0xffffff));
- m_textColor = QColor(QRgb(0x404044));
- m_textBackgroundColor = QColor(0xd6, 0xd6, 0xd6, 0x80);
- m_gridLine = QColor(QRgb(0xe2e2e2));
- m_highlightBarColor = QColor(QRgb(0xeba85f));
- m_highlightRowColor = QColor(QRgb(0xfc5751));
- m_highlightColumnColor = QColor(QRgb(0xfc5751));
- m_lightStrength = 4.0f;
- m_ambientStrength = 0.3f;
- m_highlightLightStrength = 6.0f;
- m_uniformColor = true;
-#endif
- qDebug("ThemeSystem");
- break;
- }
- case QDataVis::ThemeBlueCerulean: {
- m_baseColor = QColor(QRgb(0xc7e85b));
- m_heightColor = QColor(QRgb(0xee7392));
- m_depthColor = QColor(QRgb(0x1cb54f));
- m_backgroundColor = QColor(QRgb(0x056189));
- m_windowColor = QColor(QRgb(0x101a31));
- m_textColor = QColor(QRgb(0xffffff));
- m_textBackgroundColor = QColor(0x05, 0x61, 0x89, 0x80);
- m_gridLine = QColor(QRgb(0x84a2b0));
- m_highlightBarColor = QColor(QRgb(0x5cbf9b));
- m_highlightRowColor = QColor(QRgb(0x009fbf));
- m_highlightColumnColor = QColor(QRgb(0x009fbf));
- m_lightStrength = 5.0f;
- m_ambientStrength = 0.2f;
- m_highlightLightStrength = 10.0f;
- m_uniformColor = true;
- qDebug("ThemeBlueCerulean");
- break;
- }
- case QDataVis::ThemeBlueIcy: {
- m_baseColor = QRgb(0x3daeda);
- m_heightColor = QRgb(0x2fa3b4);
- m_depthColor = QColor(QRgb(0x2685bf));
- m_backgroundColor = QColor(QRgb(0xffffff));
- m_windowColor = QColor(QRgb(0xffffff));
- m_textColor = QColor(QRgb(0x404044));
- m_textBackgroundColor = QColor(0xff, 0xff, 0xff, 0x80);
- m_gridLine = QColor(QRgb(0xe2e2e2));
- m_highlightBarColor = QColor(QRgb(0x0c2673));
- m_highlightRowColor = QColor(QRgb(0x5f3dba));
- m_highlightColumnColor = QColor(QRgb(0x5f3dba));
- m_lightStrength = 5.0f;
- m_ambientStrength = 0.3f;
- m_highlightLightStrength = 8.0f;
- m_uniformColor = true;
- qDebug("ThemeBlueIcy");
- break;
- }
- case QDataVis::ThemeBlueNcs: {
- m_baseColor = QColor(QRgb(0x1db0da));
- m_heightColor = QColor(QRgb(0x398ca3));
- m_depthColor = QColor(QRgb(0x1341a6));
- m_backgroundColor = QColor(QRgb(0xffffff));
- m_windowColor = QColor(QRgb(0xffffff));
- m_textColor = QColor(QRgb(0x404044));
- m_textBackgroundColor = QColor(0xff, 0xff, 0xff, 0x80);
- m_gridLine = QColor(QRgb(0xe2e2e2));
- m_highlightBarColor = QColor(QRgb(0x88d41e));
- m_highlightRowColor = QColor(QRgb(0xff8e1a));
- m_highlightColumnColor = QColor(QRgb(0xff8e1a));
- m_lightStrength = 4.0f;
- m_ambientStrength = 0.2f;
- m_highlightLightStrength = 6.0f;
- m_uniformColor = true;
- qDebug("ThemeBlueNcs");
- break;
- }
- case QDataVis::ThemeBrownSand: {
- m_baseColor = QColor(QRgb(0xb39b72));
- m_heightColor = QColor(QRgb(0x494345));
- m_depthColor = QColor(QRgb(0xb3b376));
- m_backgroundColor = QColor(QRgb(0xf3ece0));
- m_windowColor = QColor(QRgb(0xf3ece0));
- m_textColor = QColor(QRgb(0x404044));
- m_textBackgroundColor = QColor(0xb5, 0xb0, 0xa7, 0x80);
- m_gridLine = QColor(QRgb(0xd4cec3));
- m_highlightBarColor = QColor(QRgb(0xc35660));
- m_highlightRowColor = QColor(QRgb(0x536780));
- m_highlightColumnColor = QColor(QRgb(0x536780));
- m_lightStrength = 6.0f;
- m_ambientStrength = 0.3f;
- m_highlightLightStrength = 8.0f;
- m_uniformColor = false;
- qDebug("ThemeBrownSand");
- break;
- }
- 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
- m_backgroundColor = QColor(QRgb(0x2e303a)); // charts: background color 1
- m_windowColor = QColor(QRgb(0x121218)); // charts: background color 2
- m_textColor = QColor(QRgb(0xffffff)); // charts: label color
- m_textBackgroundColor = QColor(0x86, 0x87, 0x8c, 0x80); // charts: axis line pen OR background color 2
- m_gridLine = QColor(QRgb(0x86878c)); // charts: grid line color
- m_highlightBarColor = QColor(QRgb(0xeb8817)); // charts: series color 3
- m_highlightRowColor = QColor(QRgb(0x7b7f8c)); // charts: series color 4
- m_highlightColumnColor = QColor(QRgb(0x7b7f8c)); // charts: series color 4
- m_lightStrength = 6.0f;
- m_ambientStrength = 0.2f;
- m_highlightLightStrength = 8.0f;
- m_uniformColor = false;
- qDebug("ThemeDark");
- break;
- }
- case QDataVis::ThemeHighContrast: {
- m_baseColor = QColor(QRgb(0x202020));
- m_heightColor = QColor(QRgb(0xff4a41));
- m_depthColor = QColor(QRgb(0x596a74));
- m_backgroundColor = QColor(QRgb(0xffffff));
- m_windowColor = QColor(QRgb(0x000000));
- m_textColor = QColor(QRgb(0x181818));
- m_textBackgroundColor = QColor(0xff, 0xff, 0xff, 0x80);
- m_gridLine = QColor(QRgb(0x8c8c8c));
- m_highlightBarColor = QColor(QRgb(0xffab03));
- m_highlightRowColor = QColor(QRgb(0x038e9b));
- m_highlightColumnColor = QColor(QRgb(0x038e9b));
- m_lightStrength = 8.0f;
- m_ambientStrength = 0.3f;
- m_highlightLightStrength = 10.0f;
- m_uniformColor = false;
- qDebug("ThemeHighContrast");
- break;
- }
- case QDataVis::ThemeLight: {
- m_baseColor = QColor(QRgb(0x209fdf));
- m_heightColor = QColor(QRgb(0xbf593e));
- m_depthColor = QColor(QRgb(0x99ca53));
- m_backgroundColor = QColor(QRgb(0xffffff));
- m_windowColor = QColor(QRgb(0xffffff));
- m_textColor = QColor(QRgb(0x404044));
- m_textBackgroundColor = QColor(0xd6, 0xd6, 0xd6, 0x80);
- m_gridLine = QColor(QRgb(0xe2e2e2));
- m_highlightBarColor = QColor(QRgb(0xf6a625));
- m_highlightRowColor = QColor(QRgb(0x6d5fd5));
- m_highlightColumnColor = QColor(QRgb(0x6d5fd5));
- m_lightStrength = 6.0f;
- m_ambientStrength = 0.3f;
- m_highlightLightStrength = 7.0f;
- m_uniformColor = true;
- qDebug("ThemeLight");
- break;
- }
- default:
- break;
- }
-}
-
-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/global/global.pri b/src/datavis3d/global/global.pri
deleted file mode 100644
index 7292bbd6..00000000
--- a/src/datavis3d/global/global.pri
+++ /dev/null
@@ -1,4 +0,0 @@
-HEADERS += \
- $$PWD/qdatavis3dglobal.h \
- $$PWD/qdatavis3denums.h \
- $$PWD/datavis3dglobal_p.h
diff --git a/src/datavis3d/global/qdatavis3denums.h b/src/datavis3d/global/qdatavis3denums.h
deleted file mode 100644
index a6384508..00000000
--- a/src/datavis3d/global/qdatavis3denums.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/****************************************************************************
-**
-** 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
deleted file mode 100644
index 5e2e88b1..00000000
--- a/src/datavis3d/global/qdatavis3dglobal.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/****************************************************************************
-**
-** 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 QDATAVIS3DGLOBAL_H
-#define QDATAVIS3DGLOBAL_H
-
-#include <qglobal.h>
-
-#define QT_DATAVIS3D_VERSION_STR "0.0.1"
-/*
- QT_DATAVIS3D_VERSION is (major << 16) + (minor << 8) + patch.
-*/
-#define QT_DATAVIS3D_VERSION 0x000001
-/*
- can be used like #if (QT_DATAVIS3D_VERSION >= QT_DATAVIS3D_VERSION_CHECK(1, 1, 0))
-*/
-#define QT_DATAVIS3D_VERSION_CHECK(major, minor, patch) ((major<<16)|(minor<<8)|(patch))
-
-#if defined(QT_DATAVIS3D_LIBRARY)
-# define QT_DATAVIS3D_EXPORT Q_DECL_EXPORT
-#else
-# define QT_DATAVIS3D_EXPORT Q_DECL_IMPORT
-#endif
-
-#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 QT_DATAVIS3D_AUTOTEST_EXPORT
-#endif
-
-#ifdef QT_DATAVIS3D_STATICLIB
-# undef QT_DATAVIS3D_EXPORT
-# undef QT_DATAVIS3D_AUTOTEST_EXPORT
-# define QT_DATAVIS3D_EXPORT
-# define QT_DATAVIS3D_AUTOTEST_EXPORT
-#endif
-
-#define QT_DATAVIS3D_NAMESPACE QtDataVis3D
-
-#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 QT_DATAVIS3D_BEGIN_NAMESPACE
-# define QT_DATAVIS3D_END_NAMESPACE
-# define QT_DATAVIS3D_USE_NAMESPACE
-#endif
-
-#endif // QVIS3DGLOBAL_H
diff --git a/src/datavis3d/global/qtdatavis3dnamespace.qdoc b/src/datavis3d/global/qtdatavis3dnamespace.qdoc
deleted file mode 100644
index 2a1f6fae..00000000
--- a/src/datavis3d/global/qtdatavis3dnamespace.qdoc
+++ /dev/null
@@ -1,163 +0,0 @@
-/****************************************************************************
-**
-** 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/surfaceobject.cpp b/src/datavis3d/utils/surfaceobject.cpp
deleted file mode 100644
index 4c05c442..00000000
--- a/src/datavis3d/utils/surfaceobject.cpp
+++ /dev/null
@@ -1,349 +0,0 @@
-/****************************************************************************
-**
-** 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/utils.cpp b/src/datavis3d/utils/utils.cpp
deleted file mode 100644
index cf6b91f8..00000000
--- a/src/datavis3d/utils/utils.cpp
+++ /dev/null
@@ -1,234 +0,0 @@
-/****************************************************************************
-**
-** 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 "utils_p.h"
-
-#include <QVector3D>
-#include <QColor>
-#include <QPainter>
-#include <QPoint>
-#include <QImage>
-
-#include <qmath.h>
-
-#include <QDebug>
-
-QT_DATAVIS3D_BEGIN_NAMESPACE
-
-#define NUM_IN_POWER(y, x) for (;y<x;y<<=1)
-#define MIN_POWER 32
-
-GLuint Utils::getNearestPowerOfTwo(GLuint value, GLuint &padding)
-{
- GLuint powOfTwoValue = MIN_POWER;
- NUM_IN_POWER(powOfTwoValue, value);
- padding = powOfTwoValue - value;
- return powOfTwoValue;
-}
-
-QVector3D Utils::vectorFromColor(const QColor &color)
-{
- return QVector3D(color.redF(), color.greenF(), color.blueF());
-}
-
-void Utils::printText(QPainter *painter, const QString &text, const QSize &position,
- bool absoluteCoords, qreal rotation, qreal scale)
-{
- painter->save();
- painter->setCompositionMode(QPainter::CompositionMode_Source);
- painter->setPen(Qt::black); // TODO: Use black, as nothing works
- QFont bgrFont = QFont(QStringLiteral("Arial"), 17);
- QFont valueFont = QFont(QStringLiteral("Arial"), 11);
- valueFont.setBold(true);
- painter->setFont(bgrFont);
- QFontMetrics valueFM(valueFont);
- QFontMetrics bgrFM(bgrFont);
- int valueStrLen = valueFM.width(text);
- int bgrStrLen = 0;
- int bgrHeight = valueFM.height() + 8;
- QString bgrStr = QString();
- do {
- bgrStr.append(QStringLiteral("I"));
- bgrStrLen = bgrFM.width(bgrStr);
- } while (bgrStrLen <= (valueStrLen + 8));
-#if 0
- // Hack solution, as drawRect doesn't work
- painter->drawText(position.width() - (bgrStrLen / 2),
- position.height() - bgrHeight,
- bgrStrLen, bgrHeight,
- Qt::AlignCenter | Qt::AlignVCenter,
- bgrStr);
- //painter->setPen(d_ptr->m_textColor);
- painter->setPen(Qt::lightGray); // TODO: Use lightGray, as nothing works
- painter->setFont(valueFont);
- painter->drawText(position.width() - (valueStrLen / 2),
- position.height() - bgrHeight,
- valueStrLen, bgrHeight,
- Qt::AlignCenter | Qt::AlignVCenter,
- text);
-#else
- //qDebug() << painter->window() << painter->viewport();
- painter->scale(scale, scale);
- if (absoluteCoords) {
- // This assumes absolute screen coordinates
- painter->translate(position.width() - (((float)bgrStrLen / 2.0f)
- * qCos(qDegreesToRadians(rotation)))
- + (((float)bgrHeight / 2.0f) * qSin(qDegreesToRadians(rotation))),
- position.height()
- - ((((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)
- * qCos(qDegreesToRadians(rotation)))
- + (((float)bgrHeight / 2.0f) * qSin(qDegreesToRadians(rotation))),
- painter->window().height() - position.height()
- - ((((float)bgrHeight / 2.0f) * qCos(qDegreesToRadians(rotation)))
- + (((float)bgrStrLen / 2.0f) * qSin(qDegreesToRadians(rotation)))));
- }
- //qDebug() << painter->window().height() - position.height()
- // - ((((float)bgrHeight / 2.0f) * qCos(qDegreesToRadians(rotation)))
- // + (((float)bgrStrLen / 2.0f) * qSin(qDegreesToRadians(rotation))));
- painter->rotate(rotation);
- painter->drawText(0, 0,
- bgrStrLen, bgrHeight,
- Qt::AlignCenter | Qt::AlignVCenter,
- bgrStr);
- painter->setPen(Qt::lightGray); // TODO: Use lightGray, as nothing works
- painter->setFont(valueFont);
- painter->drawText(6, 0,
- valueStrLen, bgrHeight,
- Qt::AlignCenter | Qt::AlignVCenter,
- text);
- painter->resetTransform();
-#endif
- painter->restore();
-}
-
-QImage Utils::printTextToImage(const QFont &font, const QString &text, const QColor &bgrColor,
- const QColor &txtColor, QDataVis::LabelTransparency transparency)
-{
- GLuint paddingWidth = 15;
- GLuint paddingHeight = 15;
- // Calculate text dimensions
- QFont valueFont = font;
- valueFont.setPointSize(30);
- QFontMetrics valueFM(valueFont);
- int valueStrWidth = valueFM.width(text);
- int valueStrHeight = valueFM.height();
- QSize labelSize;
-
-#if defined(Q_OS_ANDROID)
- // Android can't handle textures with dimensions not in power of 2. Resize labels accordingly.
- // Add some padding before converting to power of two to avoid too tight fit
- GLuint prePadding = 10;
- labelSize = QSize(valueStrWidth + prePadding, valueStrHeight + prePadding);
- //qDebug() << "label size before padding" << labelSize;
- labelSize.setWidth(getNearestPowerOfTwo(labelSize.width(), paddingWidth));
- labelSize.setHeight(getNearestPowerOfTwo(labelSize.height(), paddingHeight));
- paddingWidth += prePadding;
- paddingHeight += prePadding;
- paddingWidth /= 2;
- paddingHeight /= 2;
- //qDebug() << "label size after padding" << labelSize << paddingWidth << paddingHeight;
-#else
- if (QDataVis::TransparencyNoBackground == transparency)
- labelSize = QSize(valueStrWidth, valueStrHeight);
- else
- labelSize = QSize(valueStrWidth + paddingWidth * 2, valueStrHeight + paddingHeight * 2);
-#endif
-
- // Create image
- QImage image = QImage(labelSize, QImage::Format_ARGB32);
- image.fill(Qt::transparent);
-
- // Init painter
- QPainter painter(&image);
- // Paint text
- painter.setRenderHint(QPainter::Antialiasing, true);
- 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 QDataVis::TransparencyNoBackground: {
- painter.setFont(valueFont);
- painter.setPen(txtColor);
- painter.drawText(0, 0,
- valueStrWidth, valueStrHeight,
- Qt::AlignCenter | Qt::AlignVCenter,
- text);
- break;
- }
- case QDataVis::TransparencyFromTheme: {
- painter.setBrush(QBrush(bgrColor));
- painter.setPen(bgrColor);
- painter.drawRoundedRect(0, 0, labelSize.width(), labelSize.height(), 10.0, 10.0f);
- painter.setFont(valueFont);
- painter.setPen(txtColor);
- painter.drawText(paddingWidth, paddingHeight,
- valueStrWidth, valueStrHeight,
- Qt::AlignCenter | Qt::AlignVCenter,
- text);
- break;
- }
- case QDataVis::TransparencyNone: {
- painter.setBrush(QBrush(bgrColor));
- painter.setPen(bgrColor);
- painter.drawRect(0, 0, labelSize.width(), labelSize.height());
- painter.setFont(valueFont);
- painter.setPen(txtColor);
- painter.drawText(paddingWidth, paddingHeight,
- valueStrWidth, valueStrHeight,
- Qt::AlignCenter | Qt::AlignVCenter,
- text);
- break;
- }
- }
- return image;
-}
-
-QVector3D Utils::getSelection(QPoint mousepos, int height)
-{
- QVector3D selectedColor;
-
- //#if defined(QT_OPENGL_ES_2)
- // This is the only one that works with ANGLE (ES 2.0)
- // Item count will be limited to 256*256*256
- GLubyte pixel[4];
- glReadPixels(mousepos.x(), height - mousepos.y(), 1, 1,
- GL_RGBA, GL_UNSIGNED_BYTE, (void *)pixel);
- //qDebug() << "rgba" << pixel[0] << pixel[1] << pixel[2];// << pixel[3];
- //#else
- //// These work with desktop OpenGL
- //// They offer a lot higher possible object count and a possibility to use object ids
- //GLuint pixel[3];
- //glReadPixels(mousepos.x(), height - mousepos.y(), 1, 1,
- // GL_RGB, GL_UNSIGNED_INT, (void *)pixel);
- //qDebug() << "rgba" << pixel[0] << pixel[1] << pixel[2];// << pixel[3];
-
- //GLfloat pixel3[3];
- //glReadPixels(mousepos.x(), height - mousepos.y(), 1, 1,
- // GL_RGB, GL_FLOAT, (void *)pixel3);
- //qDebug() << "rgba" << pixel3[0] << pixel3[1] << pixel3[2];// << pixel[3];
- //#endif
- selectedColor = QVector3D(pixel[0], pixel[1], pixel[2]);
- //qDebug() << selectedColor;
-
- return selectedColor;
-}
-
-QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3dqml2/datavis3dqml2_plugin.cpp b/src/datavis3dqml2/datavis3dqml2_plugin.cpp
deleted file mode 100644
index d1e534f8..00000000
--- a/src/datavis3dqml2/datavis3dqml2_plugin.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/****************************************************************************
-**
-** 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 "datavis3dqml2_plugin.h"
-
-#include <qqml.h>
-
-QT_DATAVIS3D_BEGIN_NAMESPACE
-
-void Datavis3dqml2Plugin::registerTypes(const char *uri)
-{
- // @uri com.digia.QtDataVis3D
- 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");
-
- qmlRegisterType<QValueAxis>(uri, 1, 0, "ValueAxis");
- qmlRegisterType<QCategoryAxis>(uri, 1, 0, "CategoryAxis");
-}
-
-QT_DATAVIS3D_END_NAMESPACE
-
diff --git a/src/datavis3dqml2/datavis3dqml2_plugin.h b/src/datavis3dqml2/datavis3dqml2_plugin.h
deleted file mode 100644
index ac88e1b5..00000000
--- a/src/datavis3dqml2/datavis3dqml2_plugin.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/****************************************************************************
-**
-** 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 DATAVIS3DQML2_PLUGIN_H
-#define DATAVIS3DQML2_PLUGIN_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>
-
-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(QAbstractAxis *)
-Q_DECLARE_METATYPE(QCategoryAxis *)
-Q_DECLARE_METATYPE(QValueAxis *)
-
-QT_DATAVIS3D_BEGIN_NAMESPACE
-
-class Datavis3dqml2Plugin : public QQmlExtensionPlugin
-{
- Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
-
-public:
- void registerTypes(const char *uri);
-};
-
-QT_DATAVIS3D_END_NAMESPACE
-
-#endif // DATAVIS3DQML2_PLUGIN_H
-
diff --git a/src/datavis3dqml2/declarativebars.cpp b/src/datavis3dqml2/declarativebars.cpp
deleted file mode 100644
index 2e4dbf04..00000000
--- a/src/datavis3dqml2/declarativebars.cpp
+++ /dev/null
@@ -1,380 +0,0 @@
-/****************************************************************************
-**
-** 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 "declarativebars_p.h"
-#include "declarativebarsrenderer_p.h"
-#include "qitemmodelbardataproxy.h"
-#include "qvalueaxis.h"
-
-QT_DATAVIS3D_BEGIN_NAMESPACE
-
-const QString smoothString(QStringLiteral("Smooth"));
-
-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);
-
- // 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, &Abstract3DController::shadowQualityChanged, this,
- &DeclarativeBars::handleShadowQualityUpdate);
-
- m_shared->setDataProxy(new QItemModelBarDataProxy);
-}
-
-DeclarativeBars::~DeclarativeBars()
-{
- delete m_shared;
-}
-
-void DeclarativeBars::handleShadowQualityUpdate(QDataVis::ShadowQuality quality)
-{
- emit shadowQualityChanged(quality);
-}
-
-void DeclarativeBars::classBegin()
-{
- qDebug() << "classBegin";
-}
-
-void DeclarativeBars::componentComplete()
-{
- qDebug() << "componentComplete";
-}
-
-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;
- }
-
- // 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
- DeclarativeBarsRenderer *node = new DeclarativeBarsRenderer(window(), m_shared);
- node->setRect(boundingRect());
- m_shared->setBoundingRect(boundingRect().toRect());
- return node;
-}
-
-void DeclarativeBars::setupSampleSpace(int rowCount, int columnCount)
-{
- m_shared->setupSampleSpace(rowCount, columnCount);
-}
-
-void DeclarativeBars::setBarColor(QColor baseColor, QColor heightColor, QColor depthColor,
- bool uniform)
-{
- m_shared->setObjectColor(baseColor, heightColor, depthColor, uniform);
-}
-
-void DeclarativeBars::setCameraPosition(qreal horizontal, qreal vertical, int distance)
-{
- m_shared->setCameraPosition(GLfloat(horizontal), GLfloat(vertical), GLint(distance));
-}
-
-void DeclarativeBars::setData(QAbstractItemModel *data)
-{
- static_cast<QItemModelBarDataProxy *>(m_shared->dataProxy())->setItemModel(data);
-}
-
-QAbstractItemModel *DeclarativeBars::data()
-{
- return static_cast<QItemModelBarDataProxy *>(m_shared->dataProxy())->itemModel();
-}
-
-void DeclarativeBars::setMapping(QItemModelBarDataMapping *mapping)
-{
- static_cast<QItemModelBarDataProxy *>(m_shared->dataProxy())->setMapping(mapping);
-}
-
-QCategoryAxis *DeclarativeBars::axisX() const
-{
- return static_cast<QCategoryAxis *>(m_shared->axisX());
-}
-
-void DeclarativeBars::setAxisX(QCategoryAxis *axis)
-{
- m_shared->setAxisX(axis);
-}
-
-QValueAxis *DeclarativeBars::axisY() const
-{
- return static_cast<QValueAxis *>(m_shared->axisY());
-}
-
-void DeclarativeBars::setAxisY(QValueAxis *axis)
-{
- m_shared->setAxisY(axis);
-}
-
-QCategoryAxis *DeclarativeBars::axisZ() const
-{
- return static_cast<QCategoryAxis *>(m_shared->axisZ());
-}
-
-void DeclarativeBars::setAxisZ(QCategoryAxis *axis)
-{
- m_shared->setAxisZ(axis);
-}
-
-QItemModelBarDataMapping *DeclarativeBars::mapping() const
-{
- return static_cast<QItemModelBarDataProxy *>(m_shared->dataProxy())->mapping();
-}
-
-void DeclarativeBars::setBarThickness(QSizeF thickness)
-{
- m_shared->setBarSpecs(thickness, barSpacing(), isBarSpacingRelative());
-}
-
-QSizeF DeclarativeBars::barThickness()
-{
- return m_shared->barThickness();
-}
-
-void DeclarativeBars::setBarSpacing(QSizeF spacing)
-{
- m_shared->setBarSpecs(barThickness(), spacing, isBarSpacingRelative());
-}
-
-QSizeF DeclarativeBars::barSpacing()
-{
- return m_shared->barSpacing();
-}
-
-void DeclarativeBars::setBarSpacingRelative(bool relative)
-{
- m_shared->setBarSpecs(barThickness(), barSpacing(), relative);
-}
-
-bool DeclarativeBars::isBarSpacingRelative()
-{
- return m_shared->isBarSpecRelative();
-}
-
-void DeclarativeBars::setBarType(QDataVis::MeshStyle style)
-{
- QString objFile = m_shared->meshFileName();
- bool smooth = objFile.endsWith(smoothString);
- m_shared->setBarType(style, smooth);
-}
-
-QDataVis::MeshStyle DeclarativeBars::barType()
-{
- QString objFile = m_shared->meshFileName();
- if (objFile.contains("/sphere"))
- return QDataVis::Spheres;
- else
- return QDataVis::Dots;
-}
-
-void DeclarativeBars::setBarSmooth(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 DeclarativeBars::barSmooth()
-{
- QString objFile = m_shared->meshFileName();
- return objFile.endsWith(smoothString);
-}
-
-void DeclarativeBars::setMeshFileName(const QString &objFileName)
-{
- m_shared->setMeshFileName(objFileName);
-}
-
-QString DeclarativeBars::meshFileName()
-{
- return m_shared->meshFileName();
-}
-
-void DeclarativeBars::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 DeclarativeBars::cameraPreset()
-{
- return m_cameraPreset;
-}
-
-void DeclarativeBars::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);
-}
-
-QDataVis::ColorTheme DeclarativeBars::theme()
-{
- return m_theme;
-}
-
-void DeclarativeBars::setFontSize(float fontsize)
-{
- 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();
-}
-
-void DeclarativeBars::setLabelTransparency(QDataVis::LabelTransparency transparency)
-{
- m_shared->setLabelTransparency(transparency);
-}
-
-QDataVis::LabelTransparency DeclarativeBars::labelTransparency()
-{
- return m_shared->labelTransparency();
-}
-
-void DeclarativeBars::setGridVisible(bool visible)
-{
- m_shared->setGridEnabled(visible);
-}
-
-bool DeclarativeBars::isGridVisible()
-{
- return m_shared->gridEnabled();
-}
-
-void DeclarativeBars::setBackgroundVisible(bool visible)
-{
- m_shared->setBackgroundEnabled(visible);
-}
-
-bool DeclarativeBars::isBackgroundVisible()
-{
- return m_shared->backgroundEnabled();
-}
-
-void DeclarativeBars::setSelectionMode(QDataVis::SelectionMode mode)
-{
- m_shared->setSelectionMode(mode);
-}
-
-QDataVis::SelectionMode DeclarativeBars::selectionMode()
-{
- return m_shared->selectionMode();
-}
-
-void DeclarativeBars::setShadowQuality(QDataVis::ShadowQuality quality)
-{
- m_shared->setShadowQuality(quality);
-}
-
-QDataVis::ShadowQuality DeclarativeBars::shadowQuality()
-{
- return m_shared->shadowQuality();
-}
-
-int DeclarativeBars::rows() const
-{
- return m_shared->rowCount();
-}
-
-void DeclarativeBars::setRows(int rows)
-{
- setupSampleSpace(rows, columns());
-}
-
-int DeclarativeBars::columns() const
-{
- return m_shared->columnCount();
-}
-
-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);
-}
-
-void DeclarativeBars::mouseReleaseEvent(QMouseEvent *event)
-{
- QPoint mousePos = event->pos();
- //mousePos.setY(height() - mousePos.y());
- m_shared->mouseReleaseEvent(event, mousePos);
-}
-
-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);
-}
-
-QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3dqml2/declarativebars_p.h b/src/datavis3dqml2/declarativebars_p.h
deleted file mode 100644
index 07dc21d4..00000000
--- a/src/datavis3dqml2/declarativebars_p.h
+++ /dev/null
@@ -1,206 +0,0 @@
-/****************************************************************************
-**
-** 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 DECLARATIVEBARS_P_H
-#define DECLARATIVEBARS_P_H
-
-#include "datavis3dglobal_p.h"
-#include "bars3dcontroller_p.h"
-#include "declarativebars_p.h"
-#include "qitemmodelbardatamapping.h"
-#include "qvalueaxis.h"
-#include "qcategoryaxis.h"
-
-#include <QAbstractItemModel>
-#include <QQuickItem>
-#include <QObject>
-#include <QQuickWindow>
-
-QT_DATAVIS3D_BEGIN_NAMESPACE
-
-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 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);
-
- int columns() const;
- void setColumns(int columns);
-
-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:
- Bars3dController *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/declarativemaps.cpp b/src/datavis3dqml2/declarativemaps.cpp
deleted file mode 100644
index 7be239f2..00000000
--- a/src/datavis3dqml2/declarativemaps.cpp
+++ /dev/null
@@ -1,229 +0,0 @@
-/****************************************************************************
-**
-** 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 "declarativemaps_p.h"
-#include "declarativemapsrenderer_p.h"
-#include "qitemmodelmapdataproxy.h"
-
-QT_DATAVIS3D_BEGIN_NAMESPACE
-
-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();
-}
-
-QItemModelMapDataMapping *DeclarativeMaps::mapping() const
-{
- return static_cast<QItemModelMapDataProxy *>(m_shared->dataProxy())->mapping();
-}
-
-void DeclarativeMaps::setMapping(QItemModelMapDataMapping *mapping)
-{
- static_cast<QItemModelMapDataProxy *>(m_shared->dataProxy())->setMapping(mapping);
-}
-
-void DeclarativeMaps::mousePressEvent(QMouseEvent *event)
-{
- QPoint mousePos = event->pos();
- //mousePos.setY(height() - mousePos.y());
- m_shared->mousePressEvent(event, mousePos);
-}
-
-void DeclarativeMaps::mouseReleaseEvent(QMouseEvent *event)
-{
- QPoint mousePos = event->pos();
- //mousePos.setY(height() - mousePos.y());
- m_shared->mouseReleaseEvent(event, mousePos);
-}
-
-void DeclarativeMaps::mouseMoveEvent(QMouseEvent *event)
-{
- QPoint mousePos = event->pos();
- //mousePos.setY(height() - mousePos.y());
- m_shared->mouseMoveEvent(event, mousePos);
-}
-
-void DeclarativeMaps::wheelEvent(QWheelEvent *event)
-{
- m_shared->wheelEvent(event);
-}
-
-QT_DATAVIS3D_END_NAMESPACE
diff --git a/src/datavis3dqml2/declarativemaps_p.h b/src/datavis3dqml2/declarativemaps_p.h
deleted file mode 100644
index ba2da0b3..00000000
--- a/src/datavis3dqml2/declarativemaps_p.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/****************************************************************************
-**
-** 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/declarativescatter.cpp b/src/datavis3dqml2/declarativescatter.cpp
deleted file mode 100644
index 6731035e..00000000
--- a/src/datavis3dqml2/declarativescatter.cpp
+++ /dev/null
@@ -1,328 +0,0 @@
-/****************************************************************************
-**
-** 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, &Abstract3DController::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
deleted file mode 100644
index dce5c021..00000000
--- a/src/datavis3dqml2/declarativescatter_p.h
+++ /dev/null
@@ -1,175 +0,0 @@
-/****************************************************************************
-**
-** 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/qmldir b/src/datavis3dqml2/qmldir
deleted file mode 100644
index 876138db..00000000
--- a/src/datavis3dqml2/qmldir
+++ /dev/null
@@ -1,3 +0,0 @@
-module com.digia.QtDataVis3D
-plugin datavis3dqml2
-
diff --git a/src/datavisualization/axis/axis.pri b/src/datavisualization/axis/axis.pri
new file mode 100644
index 00000000..4e96618b
--- /dev/null
+++ b/src/datavisualization/axis/axis.pri
@@ -0,0 +1,12 @@
+HEADERS += \
+ $$PWD/q3dabstractaxis.h \
+ $$PWD/q3dabstractaxis_p.h \
+ $$PWD/q3dvalueaxis.h \
+ $$PWD/q3dvalueaxis_p.h \
+ $$PWD/q3dcategoryaxis.h \
+ $$PWD/q3dcategoryaxis_p.h
+
+SOURCES += \
+ $$PWD/q3dabstractaxis.cpp \
+ $$PWD/q3dvalueaxis.cpp \
+ $$PWD/q3dcategoryaxis.cpp
diff --git a/src/datavisualization/axis/q3dabstractaxis.cpp b/src/datavisualization/axis/q3dabstractaxis.cpp
new file mode 100644
index 00000000..07761d0c
--- /dev/null
+++ b/src/datavisualization/axis/q3dabstractaxis.cpp
@@ -0,0 +1,373 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 "q3dabstractaxis.h"
+#include "q3dabstractaxis_p.h"
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+/*!
+ * \class Q3DAbstractAxis
+ * \inmodule QtDataVisualization
+ * \brief Q3DAbstractAxis is base class for axes of a graph.
+ * \since 1.0.0
+ *
+ * You should not need to use this class directly, but one of its subclasses instead.
+ *
+ * \sa Q3DCategoryAxis, Q3DValueAxis
+ */
+
+/*!
+ * \qmltype AbstractAxis3D
+ * \inqmlmodule com.digia.QtDataVisualization 1.0
+ * \since com.digia.QtDataVisualization 1.0
+ * \ingroup datavisualization_qml
+ * \instantiates Q3DAbstractAxis
+ * \brief AbstractAxis3D is base type for axes of a graph.
+ *
+ * This type is uncreatable, but contains properties that are exposed via subtypes.
+ */
+
+/*!
+ * \qmlproperty string AbstractAxis3D::title
+ * Defines the title for the axis.
+ */
+
+/*!
+ * \qmlproperty list AbstractAxis3D::labels
+ * Defines the labels for the axis.
+ */
+
+/*!
+ * \qmlproperty AbstractAxis3D.AxisOrientation AbstractAxis3D::orientation
+ * Defines the orientation of the axis.
+ */
+
+/*!
+ * \qmlproperty AbstractAxis3D.AxisType AbstractAxis3D::type
+ * Defines the type of the axis.
+ */
+
+/*!
+ * \qmlproperty real AbstractAxis3D::min
+ *
+ * Defines the minimum value on the axis.
+ * When setting this property the max is adjusted if necessary, to ensure that the range remains
+ * valid.
+ */
+
+/*!
+ * \qmlproperty real AbstractAxis3D::max
+ *
+ * Defines the maximum value on the axis.
+ * When setting this property the min is adjusted if necessary, to ensure that the range remains
+ * valid.
+ */
+
+/*!
+ * \qmlproperty bool AbstractAxis3D::autoAdjustRange
+ *
+ * If set, the axis will automatically adjust the range so that all data fits in it.
+ */
+
+
+/*!
+ * \enum Q3DAbstractAxis::AxisOrientation
+ *
+ * The orientation of the axis object.
+ *
+ * \value AxisOrientationNone
+ * \value AxisOrientationX
+ * \value AxisOrientationY
+ * \value AxisOrientationZ
+ */
+
+/*!
+ * \enum Q3DAbstractAxis::AxisType
+ *
+ * The type of the axis object.
+ *
+ * \value AxisTypeNone
+ * \value AxisTypeCategory
+ * \value AxisTypeValue
+ */
+
+/*!
+ * \internal
+ */
+Q3DAbstractAxis::Q3DAbstractAxis(Q3DAbstractAxisPrivate *d, QObject *parent) :
+ QObject(parent),
+ d_ptr(d)
+{
+}
+
+/*!
+ * Destroys Q3DAbstractAxis.
+ */
+Q3DAbstractAxis::~Q3DAbstractAxis()
+{
+}
+
+/*!
+ * \property Q3DAbstractAxis::title
+ *
+ * Defines the title for the axis.
+ */
+QString Q3DAbstractAxis::title() const
+{
+ return d_ptr->m_title;
+}
+
+/*!
+ * \property Q3DAbstractAxis::labels
+ *
+ * Defines the labels for the axis.
+ */
+QStringList Q3DAbstractAxis::labels() const
+{
+ d_ptr->updateLabels();
+ return d_ptr->m_labels;
+}
+
+/*!
+ * \property Q3DAbstractAxis::orientation
+ *
+ * Defines the orientation of the axis, one of \c Q3DAbstractAxis::AxisOrientation.
+ */
+Q3DAbstractAxis::AxisOrientation Q3DAbstractAxis::orientation() const
+{
+ return d_ptr->m_orientation;
+}
+
+/*!
+ * \property Q3DAbstractAxis::type
+ *
+ * Defines the type of the axis, one of \c Q3DAbstractAxis::AxisType.
+ */
+Q3DAbstractAxis::AxisType Q3DAbstractAxis::type() const
+{
+ return d_ptr->m_type;
+}
+
+void Q3DAbstractAxis::setTitle(QString title)
+{
+ if (d_ptr->m_title != title) {
+ d_ptr->m_title = title;
+ emit titleChanged(title);
+ }
+}
+
+/*!
+ * Sets value range of the axis from \a min to \a max.
+ * When setting the range, the max is adjusted if necessary, to ensure that the range remains valid.
+ * \note For Q3DCategoryAxis this specifies the index range of rows or columns to show.
+ */
+void Q3DAbstractAxis::setRange(qreal min, qreal max)
+{
+ d_ptr->setRange(min, max);
+ setAutoAdjustRange(false);
+}
+
+/*!
+ * \property Q3DAbstractAxis::min
+ *
+ * Defines the minimum value on the axis.
+ * When setting this property the max is adjusted if necessary, to ensure that the range remains
+ * valid.
+ * \note For Q3DCategoryAxis this specifies the index of the first row or column to show.
+ */
+void Q3DAbstractAxis::setMin(qreal min)
+{
+ d_ptr->setMin(min);
+ setAutoAdjustRange(false);
+}
+
+/*!
+ * \property Q3DAbstractAxis::max
+ *
+ * Defines the maximum value on the axis.
+ * When setting this property the min is adjusted if necessary, to ensure that the range remains
+ * valid.
+ * \note For Q3DCategoryAxis this specifies the index of the last row or column to show.
+ */
+void Q3DAbstractAxis::setMax(qreal max)
+{
+ d_ptr->setMax(max);
+ setAutoAdjustRange(false);
+}
+
+qreal Q3DAbstractAxis::min() const
+{
+ return d_ptr->m_min;
+}
+
+qreal Q3DAbstractAxis::max() const
+{
+ return d_ptr->m_max;
+}
+
+/*!
+ * \property Q3DAbstractAxis::autoAdjustRange
+ *
+ * If set, the axis will automatically adjust the range so that all data fits in it.
+ *
+ * \sa setRange(), setMin(), setMax()
+ */
+void Q3DAbstractAxis::setAutoAdjustRange(bool autoAdjust)
+{
+ if (d_ptr->m_autoAdjust != autoAdjust) {
+ d_ptr->m_autoAdjust = autoAdjust;
+ emit autoAdjustRangeChanged(autoAdjust);
+ }
+}
+
+bool Q3DAbstractAxis::isAutoAdjustRange() const
+{
+ return d_ptr->m_autoAdjust;
+}
+
+// Q3DAbstractAxisPrivate
+
+Q3DAbstractAxisPrivate::Q3DAbstractAxisPrivate(Q3DAbstractAxis *q, Q3DAbstractAxis::AxisType type)
+ : QObject(0),
+ q_ptr(q),
+ m_orientation(Q3DAbstractAxis::AxisOrientationNone),
+ m_type(type),
+ m_isDefaultAxis(false),
+ m_min(0.0),
+ m_max(10.0),
+ m_autoAdjust(true),
+ m_onlyPositiveValues(false),
+ m_allowMinMaxSame(false)
+{
+}
+
+Q3DAbstractAxisPrivate::~Q3DAbstractAxisPrivate()
+{
+}
+
+void Q3DAbstractAxisPrivate::setOrientation(Q3DAbstractAxis::AxisOrientation orientation)
+{
+ if (m_orientation == Q3DAbstractAxis::AxisOrientationNone)
+ m_orientation = orientation;
+ else
+ Q_ASSERT("Attempted to reset axis orientation.");
+}
+
+void Q3DAbstractAxisPrivate::updateLabels()
+{
+ // Default implementation does nothing
+}
+
+void Q3DAbstractAxisPrivate::setRange(qreal min, qreal max)
+{
+ bool adjusted = false;
+ if (m_onlyPositiveValues) {
+ if (min < 0.0) {
+ min = 0.0;
+ adjusted = true;
+ }
+ if (max < 0.0) {
+ max = 0.0;
+ adjusted = true;
+ }
+ }
+ // If min >= max, we adjust ranges so that
+ // m_max becomes (min + 1.0)
+ // as axes need some kind of valid range.
+ bool dirty = false;
+ if (m_min != min) {
+ m_min = min;
+ dirty = true;
+ }
+ if (m_max != max || min > max || (!m_allowMinMaxSame && min == max)) {
+ if (min > max || (!m_allowMinMaxSame && min == max)) {
+ m_max = min + 1.0;
+ adjusted = true;
+ } else {
+ m_max = max;
+ }
+ dirty = true;
+ }
+
+ if (dirty) {
+ if (adjusted) {
+ qWarning() << "Warning: Tried to set invalid range for axis."
+ " Range automatically adjusted to a valid one:"
+ << min << "-" << max << "-->" << m_min << "-" << m_max;
+ }
+ emit q_ptr->rangeChanged(m_min, m_max);
+ }
+}
+
+void Q3DAbstractAxisPrivate::setMin(qreal min)
+{
+ if (m_onlyPositiveValues) {
+ if (min < 0.0) {
+ min = 0.0;
+ qWarning() << "Warning: Tried to set negative minimum for an axis that only supports"
+ " positive values:" << min;
+ }
+ }
+
+ if (m_min != min) {
+ if (min > m_max || (!m_allowMinMaxSame && 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;
+
+ emit q_ptr->rangeChanged(m_min, m_max);
+ }
+}
+
+void Q3DAbstractAxisPrivate::setMax(qreal max)
+{
+ if (m_onlyPositiveValues) {
+ if (max < 0.0) {
+ max = 0.0;
+ qWarning() << "Warning: Tried to set negative maximum for an axis that only supports"
+ " positive values:" << max;
+ }
+ }
+
+ if (m_max != max) {
+ if (m_min > max || (!m_allowMinMaxSame && m_min == max)) {
+ qreal oldMin = m_min;
+ m_min = max - 1.0;
+ if (m_onlyPositiveValues && m_min < 0.0) {
+ m_min = 0.0;
+ if (!m_allowMinMaxSame && max == 0.0) {
+ m_min = oldMin;
+ qWarning() << "Unable to set maximum value to zero.";
+ return;
+ }
+ }
+ 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;
+ emit q_ptr->rangeChanged(m_min, m_max);
+ }
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavis3d/axis/qabstractaxis.h b/src/datavisualization/axis/q3dabstractaxis.h
index 4bc0ac16..9e5c426a 100644
--- a/src/datavis3d/axis/qabstractaxis.h
+++ b/src/datavisualization/axis/q3dabstractaxis.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -16,20 +16,20 @@
**
****************************************************************************/
-#ifndef QABSTRACTAXIS_H
-#define QABSTRACTAXIS_H
+#ifndef Q3DABSTRACTAXIS_H
+#define Q3DABSTRACTAXIS_H
-#include <QtDataVis3D/qdatavis3denums.h>
+#include <QtDataVisualization/qdatavisualizationenums.h>
#include <QObject>
#include <QScopedPointer>
#include <QVector>
#include <QStringList>
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
-class QAbstractAxisPrivate;
+class Q3DAbstractAxisPrivate;
-class QT_DATAVIS3D_EXPORT QAbstractAxis : public QObject
+class QT_DATAVISUALIZATION_EXPORT Q3DAbstractAxis : public QObject
{
Q_OBJECT
Q_ENUMS(AxisOrientation)
@@ -38,6 +38,9 @@ class QT_DATAVIS3D_EXPORT QAbstractAxis : public QObject
Q_PROPERTY(QStringList labels READ labels NOTIFY labelsChanged)
Q_PROPERTY(AxisOrientation orientation READ orientation)
Q_PROPERTY(AxisType type READ type)
+ Q_PROPERTY(qreal min READ min WRITE setMin NOTIFY rangeChanged)
+ Q_PROPERTY(qreal max READ max WRITE setMax NOTIFY rangeChanged)
+ Q_PROPERTY(bool autoAdjustRange READ isAutoAdjustRange WRITE setAutoAdjustRange NOTIFY autoAdjustRangeChanged)
public:
enum AxisOrientation {
@@ -55,9 +58,10 @@ public:
};
protected:
- explicit QAbstractAxis(QAbstractAxisPrivate *d);
+ explicit Q3DAbstractAxis(Q3DAbstractAxisPrivate *d, QObject *parent = 0);
+
public:
- virtual ~QAbstractAxis();
+ virtual ~Q3DAbstractAxis();
QString title() const;
QStringList labels() const;
@@ -65,22 +69,32 @@ public:
AxisOrientation orientation() const;
AxisType type() const;
-public slots:
+ qreal min() const;
+ qreal max() const;
+ bool isAutoAdjustRange() const;
+
void setTitle(QString title);
+ void setRange(qreal min, qreal max);
+ void setMin(qreal min);
+ void setMax(qreal max);
+ void setAutoAdjustRange(bool autoAdjust);
signals:
void titleChanged(QString newTitle);
void labelsChanged();
+ void rangeChanged(qreal min, qreal max);
+ void autoAdjustRangeChanged(bool autoAdjust);
protected:
- QScopedPointer<QAbstractAxisPrivate> d_ptr;
+ QScopedPointer<Q3DAbstractAxisPrivate> d_ptr;
private:
- Q_DISABLE_COPY(QAbstractAxis)
+ Q_DISABLE_COPY(Q3DAbstractAxis)
friend class Abstract3DController;
+ friend class Bars3DController;
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif // QABSTRACTAXIS_H
diff --git a/src/datavisualization/axis/q3dabstractaxis_p.h b/src/datavisualization/axis/q3dabstractaxis_p.h
new file mode 100644
index 00000000..902f65be
--- /dev/null
+++ b/src/datavisualization/axis/q3dabstractaxis_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 QtDataVisualization 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 QtDataVisualization 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 "datavisualizationglobal_p.h"
+#include "q3dabstractaxis.h"
+#include "abstract3dcontroller_p.h"
+
+#ifndef Q3DABSTRACTAXIS_P_H
+#define Q3DABSTRACTAXIS_P_H
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class Q3DAbstractAxisPrivate : public QObject
+{
+ Q_OBJECT
+public:
+ Q3DAbstractAxisPrivate(Q3DAbstractAxis *q, Q3DAbstractAxis::AxisType type);
+ virtual ~Q3DAbstractAxisPrivate();
+
+ void setOrientation(Q3DAbstractAxis::AxisOrientation orientation);
+
+ inline bool isDefaultAxis() { return m_isDefaultAxis; }
+ inline void setDefaultAxis(bool isDefault) { m_isDefaultAxis = isDefault; }
+
+ virtual void setRange(qreal min, qreal max);
+ virtual void setMin(qreal min);
+ virtual void setMax (qreal max);
+
+protected:
+ virtual void updateLabels();
+
+ Q3DAbstractAxis *q_ptr;
+
+ QString m_title;
+ QStringList m_labels;
+ Q3DAbstractAxis::AxisOrientation m_orientation;
+ Q3DAbstractAxis::AxisType m_type;
+ bool m_isDefaultAxis;
+ qreal m_min;
+ qreal m_max;
+ bool m_autoAdjust;
+ bool m_onlyPositiveValues;
+ bool m_allowMinMaxSame;
+
+ friend class Q3DAbstractAxis;
+ friend class Q3DValueAxis;
+ friend class Q3DCategoryAxis;
+};
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
+#endif // QABSTRACTAXIS_P_H
diff --git a/src/datavisualization/axis/q3dcategoryaxis.cpp b/src/datavisualization/axis/q3dcategoryaxis.cpp
new file mode 100644
index 00000000..05f52cdc
--- /dev/null
+++ b/src/datavisualization/axis/q3dcategoryaxis.cpp
@@ -0,0 +1,152 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 "q3dcategoryaxis.h"
+#include "q3dcategoryaxis_p.h"
+#include "bars3dcontroller_p.h"
+#include "qbardataproxy.h"
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+/*!
+ * \class Q3DCategoryAxis
+ * \inmodule QtDataVisualization
+ * \brief The Q3DCategoryAxis class is used for manipulating an axis of a graph.
+ * \since 1.0.0
+ *
+ * Q3DCategoryAxis provides an axis that can be given labels. The axis is divided into equal-sized
+ * categories based on the data window size defined by setting the axis range.
+ *
+ * Grid lines are drawn between categories, if visible. Labels are drawn to positions of categories
+ * if provided.
+ */
+
+/*!
+ * \qmltype CategoryAxis3D
+ * \inqmlmodule com.digia.QtDataVisualization 1.0
+ * \since com.digia.QtDataVisualization 1.0
+ * \ingroup datavisualization_qml
+ * \instantiates Q3DCategoryAxis
+ * \inherits AbstractAxis3D
+ * \brief The CategoryAxis3D type is used for manipulating an axis of a graph.
+ *
+ * This type provides an axis that can be given labels.
+ */
+
+/*!
+ * \qmlproperty list CategoryAxis3D::categoryLabels
+ * Defines labels for axis applied to categories. If there are fewer labels than categories, the
+ * remaining ones do not have a label. If category labels are not explicitly defined, labels are
+ * generated from the data row and column labels.
+ */
+
+/*!
+ * Constructs Q3DCategoryAxis with \a parent.
+ */
+Q3DCategoryAxis::Q3DCategoryAxis(QObject *parent) :
+ Q3DAbstractAxis(new Q3DCategoryAxisPrivate(this), parent)
+{
+}
+
+/*!
+ * Destroys Q3DCategoryAxis.
+ */
+Q3DCategoryAxis::~Q3DCategoryAxis()
+{
+}
+
+/*!
+ * \property Q3DCategoryAxis::categoryLabels
+ *
+ * Defines labels for axis applied to categories. If there are fewer labels than categories, the
+ * remaining ones do not have a label. If category labels are not explicitly defined, labels are
+ * generated from the data row and column labels.
+ *
+ * \note CategoryLabels actually reads/writes the Q3DAbstractAxis::labels property,
+ * which is read only there. Since subclass cannot have property with same name,
+ * this partially duplicate property is necessary.
+ */
+QStringList Q3DCategoryAxis::categoryLabels() const
+{
+ return labels();
+}
+
+void Q3DCategoryAxis::setCategoryLabels(const QStringList &labels)
+{
+ dptr()->m_labelsExplicitlySet = !labels.isEmpty();
+ bool labelsFromData = false;
+
+ // Get labels from data proxy if axis is attached to a bar controller and an active axis there
+ if (labels.isEmpty()) {
+ Bars3DController *controller = qobject_cast<Bars3DController *>(parent());
+ if (controller) {
+ if (controller->axisX() == this) {
+ controller->handleDataRowLabelsChanged();
+ labelsFromData = true;
+ } else if (controller->axisZ() == this) {
+ controller->handleDataColumnLabelsChanged();
+ labelsFromData = true;
+ }
+ }
+ }
+
+ if (!labelsFromData && d_ptr->m_labels != labels) {
+ d_ptr->m_labels = labels;
+ emit labelsChanged();
+ }
+}
+
+/*!
+ * \internal
+ */
+Q3DCategoryAxisPrivate *Q3DCategoryAxis::dptr()
+{
+ return static_cast<Q3DCategoryAxisPrivate *>(d_ptr.data());
+}
+
+Q3DCategoryAxisPrivate::Q3DCategoryAxisPrivate(Q3DCategoryAxis *q)
+ : Q3DAbstractAxisPrivate(q, Q3DAbstractAxis::AxisTypeCategory),
+ m_labelsExplicitlySet(false)
+{
+ m_onlyPositiveValues = true;
+ m_allowMinMaxSame = true;
+}
+
+Q3DCategoryAxisPrivate::~Q3DCategoryAxisPrivate()
+{
+}
+
+/*!
+ * \internal
+ * Controller uses this function to set labels from data proxy as category labels.
+ * If the labels have been explicitly set by user, data proxy labels are not used.
+ */
+void Q3DCategoryAxisPrivate::setDataLabels(const QStringList &labels)
+{
+ if (!m_labelsExplicitlySet && m_labels != labels) {
+ m_labels = labels;
+ emit qptr()->labelsChanged();
+ }
+}
+
+Q3DCategoryAxis *Q3DCategoryAxisPrivate::qptr()
+{
+ return static_cast<Q3DCategoryAxis *>(q_ptr);
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavis3d/axis/qcategoryaxis.h b/src/datavisualization/axis/q3dcategoryaxis.h
index 8d1e3f57..ef545950 100644
--- a/src/datavis3d/axis/qcategoryaxis.h
+++ b/src/datavisualization/axis/q3dcategoryaxis.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -16,39 +16,35 @@
**
****************************************************************************/
-#ifndef QCATEGORYAXIS_H
-#define QCATEGORYAXIS_H
+#ifndef Q3DCATEGORYAXIS_H
+#define Q3DCATEGORYAXIS_H
-#include <QtDataVis3D/qabstractaxis.h>
+#include <QtDataVisualization/q3dabstractaxis.h>
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
-class QCategoryAxisPrivate;
+class Q3DCategoryAxisPrivate;
-class QT_DATAVIS3D_EXPORT QCategoryAxis : public QAbstractAxis
+class QT_DATAVISUALIZATION_EXPORT Q3DCategoryAxis : public Q3DAbstractAxis
{
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();
+ explicit Q3DCategoryAxis(QObject *parent = 0);
+ virtual ~Q3DCategoryAxis();
QStringList categoryLabels() const;
-
-public slots:
void setCategoryLabels(const QStringList &labels);
protected:
- QCategoryAxisPrivate *dptr();
+ Q3DCategoryAxisPrivate *dptr();
private:
-
- Q_DISABLE_COPY(QCategoryAxis)
+ Q_DISABLE_COPY(Q3DCategoryAxis)
+ friend class Bars3DController;
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif // QCATEGORYAXIS_H
diff --git a/src/datavis3d/axis/qcategoryaxis_p.h b/src/datavisualization/axis/q3dcategoryaxis_p.h
index 3ca79c64..9b66e48a 100644
--- a/src/datavis3d/axis/qcategoryaxis_p.h
+++ b/src/datavisualization/axis/q3dcategoryaxis_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,30 +20,38 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization 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 "q3dcategoryaxis.h"
+#include "q3dabstractaxis_p.h"
#include "qbardataitem.h"
#ifndef QCATEGORYAXIS_P_H
#define QCATEGORYAXIS_P_H
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
-class QCategoryAxisPrivate : public QAbstractAxisPrivate
+class Q3DCategoryAxisPrivate : public Q3DAbstractAxisPrivate
{
Q_OBJECT
public:
- QCategoryAxisPrivate(QCategoryAxis *q);
- virtual ~QCategoryAxisPrivate();
+ Q3DCategoryAxisPrivate(Q3DCategoryAxis *q);
+ virtual ~Q3DCategoryAxisPrivate();
+
+ void setDataLabels(const QStringList &labels);
+
+private:
+ Q3DCategoryAxis *qptr();
+
+ bool m_labelsExplicitlySet;
+ friend class Q3DCategoryAxis;
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif // QCATEGORYAXIS_P_H
diff --git a/src/datavisualization/axis/q3dvalueaxis.cpp b/src/datavisualization/axis/q3dvalueaxis.cpp
new file mode 100644
index 00000000..5e38e4ca
--- /dev/null
+++ b/src/datavisualization/axis/q3dvalueaxis.cpp
@@ -0,0 +1,270 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 "q3dvalueaxis.h"
+#include "q3dvalueaxis_p.h"
+#include "utils_p.h"
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+/*!
+ * \class Q3DValueAxis
+ * \inmodule QtDataVisualization
+ * \brief The Q3DValueAxis class is used for manipulating an axis of a graph.
+ * \since 1.0.0
+ *
+ * Q3DValueAxis provides an axis that can be given a range of values and segment and subsegment
+ * counts to divide the range into.
+ *
+ * Labels are drawn between each segment. Grid lines are drawn between each segment and each
+ * subsegment. \note If visible, there will always be at least two grid lines and labels indicating
+ * the minimum and the maximum values of the range, as there is always at least one segment.
+ */
+
+/*!
+ * \qmltype ValueAxis3D
+ * \inqmlmodule com.digia.QtDataVisualization 1.0
+ * \since com.digia.QtDataVisualization 1.0
+ * \ingroup datavisualization_qml
+ * \instantiates Q3DValueAxis
+ * \inherits AbstractAxis3D
+ * \brief The ValueAxis3D type is used for manipulating an axis of a graph.
+ *
+ * This type provides an axis that can be given a range of values and segment and subsegment
+ * counts to divide the range into.
+ */
+
+
+/*!
+ * \qmlproperty int ValueAxis3D::segmentCount
+ *
+ * Defines the number of segments on the axis. This indicates how many labels are drawn. The number
+ * of grid lines to be drawn is calculated with formula: \c {segments * subsegments + 1}.
+ * The preset default is \c 5, and it can not be below \c 1.
+ */
+
+/*!
+ * \qmlproperty int ValueAxis3D::subSegmentCount
+ *
+ * Defines the number of subsegments inside each segment on the axis. Grid lines are drawn between
+ * each subsegment, in addition to each segment.
+ * The preset default is \c 1, and it can not be below \c 1.
+ */
+
+/*!
+ * \qmlproperty string ValueAxis3D::labelFormat
+ *
+ * Defines the label format to be used for the labels on this axis. Supported specifiers are:
+ * \c {d, i, o, x, X, f, F, e, E, g, G, c}. See QString::sprintf() for additional details.
+ */
+
+/*!
+ * Constructs Q3DValueAxis with the given \a parent.
+ */
+Q3DValueAxis::Q3DValueAxis(QObject *parent) :
+ Q3DAbstractAxis(new Q3DValueAxisPrivate(this), parent)
+{
+}
+
+/*!
+ * Destroys Q3DValueAxis.
+ */
+Q3DValueAxis::~Q3DValueAxis()
+{
+}
+
+
+/*!
+ * \property Q3DValueAxis::segmentCount
+ *
+ * Defines the number of segments on the axis. This indicates how many labels are drawn. The number
+ * of grid lines to be drawn is calculated with formula: \c {segments * subsegments + 1}.
+ * The preset default is \c 5, and it can not be below \c 1.
+ *
+ * \sa setSubSegmentCount()
+ */
+void Q3DValueAxis::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()->emitLabelsChanged();
+ emit segmentCountChanged(count);
+ }
+}
+
+int Q3DValueAxis::segmentCount() const
+{
+ return dptrc()->m_segmentCount;
+}
+
+/*!
+ * \property Q3DValueAxis::subSegmentCount
+ *
+ * Defines the number of subsegments inside each segment on the axis. Grid lines are drawn between
+ * each subsegment, in addition to each segment.
+ * The preset default is \c 1, and it can not be below \c 1.
+ *
+ * \sa setSegmentCount()
+ */
+void Q3DValueAxis::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 Q3DValueAxis::subSegmentCount() const
+{
+ return dptrc()->m_subSegmentCount;
+}
+
+/*!
+ * \property Q3DValueAxis::labelFormat
+ *
+ * Defines the label format to be used for the labels on this axis. Supported specifiers are:
+ * \c {d, i, o, x, X, f, F, e, E, g, G, c}. See QString::sprintf() for additional details.
+ *
+ * Usage example:
+ *
+ * \c {axis->setLabelFormat("%.2f mm");}
+ */
+void Q3DValueAxis::setLabelFormat(const QString &format)
+{
+ if (dptr()->m_labelFormat != format) {
+ dptr()->m_labelFormat = format;
+ dptr()->emitLabelsChanged();
+ emit labelFormatChanged(format);
+ }
+}
+
+QString Q3DValueAxis::labelFormat() const
+{
+ return dptrc()->m_labelFormat;
+}
+
+/*!
+ * \internal
+ */
+Q3DValueAxisPrivate *Q3DValueAxis::dptr()
+{
+ return static_cast<Q3DValueAxisPrivate *>(d_ptr.data());
+}
+
+/*!
+ * \internal
+ */
+const Q3DValueAxisPrivate *Q3DValueAxis::dptrc() const
+{
+ return static_cast<const Q3DValueAxisPrivate *>(d_ptr.data());
+}
+
+Q3DValueAxisPrivate::Q3DValueAxisPrivate(Q3DValueAxis *q)
+ : Q3DAbstractAxisPrivate(q, Q3DAbstractAxis::AxisTypeValue),
+ m_segmentCount(5),
+ m_subSegmentCount(1),
+ m_labelFormat(Utils::defaultLabelFormat()),
+ m_labelsDirty(true)
+{
+}
+
+Q3DValueAxisPrivate::~Q3DValueAxisPrivate()
+{
+}
+
+void Q3DValueAxisPrivate::setRange(qreal min, qreal max)
+{
+ bool dirty = (min != m_min || max != m_max);
+
+ Q3DAbstractAxisPrivate::setRange(min, max);
+
+ if (dirty)
+ emitLabelsChanged();
+}
+
+void Q3DValueAxisPrivate::setMin(qreal min)
+{
+ bool dirty = (min != m_min);
+
+ Q3DAbstractAxisPrivate::setMin(min);
+
+ if (dirty)
+ emitLabelsChanged();
+}
+
+void Q3DValueAxisPrivate::setMax(qreal max)
+{
+ bool dirty = (max != m_max);
+
+ Q3DAbstractAxisPrivate::setMax(max);
+
+ if (dirty)
+ emitLabelsChanged();
+}
+
+void Q3DValueAxisPrivate::emitLabelsChanged()
+{
+ m_labelsDirty = true;
+ emit q_ptr->labelsChanged();
+}
+
+void Q3DValueAxisPrivate::updateLabels()
+{
+ if (!m_labelsDirty)
+ return;
+
+ m_labelsDirty = false;
+
+ 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;
+
+ QString formatString(m_labelFormat);
+ Utils::ParamType paramType = Utils::findFormatParamType(formatString);
+ QByteArray formatArray = formatString.toUtf8();
+
+ for (int i = 0; i < m_segmentCount; i++) {
+ qreal value = m_min + (segmentStep * i);
+ newLabels.append(Utils::formatLabel(formatArray, paramType, value));
+ }
+
+ // Ensure max label doesn't suffer from any rounding errors
+ newLabels.append(Utils::formatLabel(formatArray, paramType, m_max));
+
+ if (m_labels != newLabels)
+ m_labels = newLabels;
+}
+
+Q3DValueAxis *Q3DValueAxisPrivate::qptr()
+{
+ return static_cast<Q3DValueAxis *>(q_ptr);
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavis3d/axis/qvalueaxis.h b/src/datavisualization/axis/q3dvalueaxis.h
index c9658f37..f1280e25 100644
--- a/src/datavis3d/axis/qvalueaxis.h
+++ b/src/datavisualization/axis/q3dvalueaxis.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -19,59 +19,47 @@
#ifndef QVALUEAXIS_H
#define QVALUEAXIS_H
-#include <QtDataVis3D/qabstractaxis.h>
+#include <QtDataVisualization/q3dabstractaxis.h>
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
-class QValueAxisPrivate;
+class Q3DValueAxisPrivate;
-class QT_DATAVIS3D_EXPORT QValueAxis : public QAbstractAxis
+class QT_DATAVISUALIZATION_EXPORT Q3DValueAxis : public Q3DAbstractAxis
{
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();
+ explicit Q3DValueAxis(QObject *parent = 0);
+ virtual ~Q3DValueAxis();
- 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;
+ Q3DValueAxisPrivate *dptr();
+ const Q3DValueAxisPrivate *dptrc() const;
private:
- Q_DISABLE_COPY(QValueAxis)
- friend class Bars3dController;
+ Q_DISABLE_COPY(Q3DValueAxis)
+ friend class Bars3DController;
friend class Scatter3DController;
+ friend class Surface3DController;
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif // QVALUEAXIS_H
diff --git a/src/datavis3d/axis/qvalueaxis_p.h b/src/datavisualization/axis/q3dvalueaxis_p.h
index f730d0c0..5d0084e6 100644
--- a/src/datavis3d/axis/qvalueaxis_p.h
+++ b/src/datavisualization/axis/q3dvalueaxis_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,48 +20,47 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization 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"
+#include "q3dvalueaxis.h"
+#include "q3dabstractaxis_p.h"
#ifndef QVALUEAXIS_P_H
#define QVALUEAXIS_P_H
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
-class QValueAxisPrivate : public QAbstractAxisPrivate
+class Q3DValueAxisPrivate : public Q3DAbstractAxisPrivate
{
Q_OBJECT
public:
- QValueAxisPrivate(QValueAxis *q);
- virtual ~QValueAxisPrivate();
+ Q3DValueAxisPrivate(Q3DValueAxis *q);
+ virtual ~Q3DValueAxisPrivate();
- void setRange(qreal min, qreal max);
- void setMin(qreal min);
- void setMax (qreal max);
+ virtual void setRange(qreal min, qreal max);
+ virtual void setMin(qreal min);
+ virtual void setMax (qreal max);
protected:
- void recreateLabels();
+ void emitLabelsChanged();
+ virtual void updateLabels();
- qreal m_min;
- qreal m_max;
int m_segmentCount;
int m_subSegmentCount;
- bool m_autoAdjust;
QString m_labelFormat;
+ bool m_labelsDirty;
private:
- QValueAxis *qptr();
+ Q3DValueAxis *qptr();
- friend class QValueAxis;
+ friend class Q3DValueAxis;
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif // QVALUEAXIS_P_H
diff --git a/src/datavis3d/common.pri b/src/datavisualization/common.pri
index 57948697..5b03ab98 100644
--- a/src/datavis3d/common.pri
+++ b/src/datavisualization/common.pri
@@ -5,4 +5,5 @@ INCLUDEPATH += $$PWD/engine \
$$PWD/global \
$$PWD/utils \
$$PWD/axis \
- $$PWD/data
+ $$PWD/data \
+ $$PWD/input
diff --git a/src/datavisualization/data/abstractitemmodelhandler.cpp b/src/datavisualization/data/abstractitemmodelhandler.cpp
new file mode 100644
index 00000000..0ad0ac0b
--- /dev/null
+++ b/src/datavisualization/data/abstractitemmodelhandler.cpp
@@ -0,0 +1,250 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 "abstractitemmodelhandler_p.h"
+#include "qabstractdatamapping.h"
+#include <QTimer>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+AbstractItemModelHandler::AbstractItemModelHandler(QObject *parent)
+ : QObject(parent),
+ m_activeMapping(0),
+ resolvePending(0)
+{
+ m_resolveTimer.setSingleShot(true);
+ QObject::connect(&m_resolveTimer, &QTimer::timeout,
+ this, &AbstractItemModelHandler::handlePendingResolve);
+}
+
+AbstractItemModelHandler::~AbstractItemModelHandler()
+{
+}
+
+void AbstractItemModelHandler::setItemModel(const QAbstractItemModel *itemModel)
+{
+ if (!m_itemModel.isNull())
+ QObject::disconnect(m_itemModel, 0, this, 0);
+
+ m_itemModel = itemModel;
+
+ if (!m_itemModel.isNull()) {
+ QObject::connect(m_itemModel.data(), &QAbstractItemModel::columnsInserted,
+ this, &AbstractItemModelHandler::handleColumnsInserted);
+ QObject::connect(m_itemModel.data(), &QAbstractItemModel::columnsMoved,
+ this, &AbstractItemModelHandler::handleColumnsMoved);
+ QObject::connect(m_itemModel.data(), &QAbstractItemModel::columnsRemoved,
+ this, &AbstractItemModelHandler::handleColumnsRemoved);
+ QObject::connect(m_itemModel.data(), &QAbstractItemModel::dataChanged,
+ this, &AbstractItemModelHandler::handleDataChanged);
+ QObject::connect(m_itemModel.data(), &QAbstractItemModel::layoutChanged,
+ this, &AbstractItemModelHandler::handleLayoutChanged);
+ QObject::connect(m_itemModel.data(), &QAbstractItemModel::modelReset,
+ this, &AbstractItemModelHandler::handleModelReset);
+ QObject::connect(m_itemModel.data(), &QAbstractItemModel::rowsInserted,
+ this, &AbstractItemModelHandler::handleRowsInserted);
+ QObject::connect(m_itemModel.data(), &QAbstractItemModel::rowsMoved,
+ this, &AbstractItemModelHandler::handleRowsMoved);
+ QObject::connect(m_itemModel.data(), &QAbstractItemModel::rowsRemoved,
+ this, &AbstractItemModelHandler::handleRowsRemoved);
+ }
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0);
+}
+
+const QAbstractItemModel *AbstractItemModelHandler::itemModel() const
+{
+ return m_itemModel.data();
+}
+
+void AbstractItemModelHandler::setActiveMapping(QAbstractDataMapping *mapping)
+{
+ if (m_activeMapping)
+ QObject::disconnect(m_activeMapping, 0, this, 0);
+
+ if (mapping)
+ addMapping(mapping);
+
+ m_activeMapping = mapping;
+
+ if (m_activeMapping) {
+ QObject::connect(m_activeMapping, &QAbstractDataMapping::mappingChanged,
+ this, &AbstractItemModelHandler::handleMappingChanged);
+ }
+
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0);
+}
+
+QAbstractDataMapping *AbstractItemModelHandler::activeMapping() const
+{
+ return m_activeMapping;
+}
+
+void AbstractItemModelHandler::addMapping(QAbstractDataMapping *mapping)
+{
+ Q_ASSERT(mapping);
+ AbstractItemModelHandler *owner = qobject_cast<AbstractItemModelHandler *>(mapping->parent());
+ if (owner != this) {
+ Q_ASSERT_X(!owner, "addMapping", "Mapping already attached to a proxy.");
+ mapping->setParent(this);
+ }
+ if (!m_mappings.contains(mapping))
+ m_mappings.append(mapping);
+}
+
+void AbstractItemModelHandler::releaseMapping(QAbstractDataMapping *mapping)
+{
+ if (mapping && m_mappings.contains(mapping)) {
+ // If the mapping is in use, clear the existing mapping
+ if (m_activeMapping == mapping)
+ setActiveMapping(0);
+
+ m_mappings.removeAll(mapping);
+ mapping->setParent(0);
+ }
+}
+
+QList<QAbstractDataMapping *> AbstractItemModelHandler::mappings() const
+{
+ return m_mappings;
+}
+
+void AbstractItemModelHandler::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 AbstractItemModelHandler::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 AbstractItemModelHandler::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 AbstractItemModelHandler::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 AbstractItemModelHandler::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 AbstractItemModelHandler::handleModelReset()
+{
+ // Data cleared, reset array
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0); // TODO Resolving entire model is inefficient
+}
+
+void AbstractItemModelHandler::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 AbstractItemModelHandler::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 AbstractItemModelHandler::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 AbstractItemModelHandler::handleMappingChanged()
+{
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0);
+}
+
+void AbstractItemModelHandler::handlePendingResolve()
+{
+ resolveModel();
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualization/data/abstractitemmodelhandler_p.h b/src/datavisualization/data/abstractitemmodelhandler_p.h
new file mode 100644
index 00000000..fbaaa1f9
--- /dev/null
+++ b/src/datavisualization/data/abstractitemmodelhandler_p.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 QtDataVisualization 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 ABSTRACTITEMMODELHANDLER_P_H
+#define ABSTRACTITEMMODELHANDLER_P_H
+
+#include "datavisualizationglobal_p.h"
+#include <QAbstractItemModel>
+#include <QPointer>
+#include <QTimer>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class QAbstractDataMapping;
+
+class AbstractItemModelHandler : public QObject
+{
+ Q_OBJECT
+public:
+ AbstractItemModelHandler(QObject *parent = 0);
+ virtual ~AbstractItemModelHandler();
+
+ virtual void setItemModel(const QAbstractItemModel *itemModel);
+ virtual const QAbstractItemModel *itemModel() const;
+ virtual void setActiveMapping(QAbstractDataMapping *mapping);
+ virtual QAbstractDataMapping *activeMapping() const;
+ virtual void addMapping(QAbstractDataMapping *mapping);
+ virtual void releaseMapping(QAbstractDataMapping *mapping);
+ virtual QList<QAbstractDataMapping *> mappings() const;
+
+public slots:
+ virtual void handleColumnsInserted(const QModelIndex &parent, int start, int end);
+ virtual void handleColumnsMoved(const QModelIndex &sourceParent, int sourceStart,
+ int sourceEnd, const QModelIndex &destinationParent,
+ int destinationColumn);
+ virtual void handleColumnsRemoved(const QModelIndex &parent, int start, int end);
+ virtual void handleDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight,
+ const QVector<int> &roles = QVector<int> ());
+ virtual void handleLayoutChanged(const QList<QPersistentModelIndex> &parents = QList<QPersistentModelIndex>(),
+ QAbstractItemModel::LayoutChangeHint hint = QAbstractItemModel::NoLayoutChangeHint);
+ virtual void handleModelReset();
+ virtual void handleRowsInserted(const QModelIndex &parent, int start, int end);
+ virtual void handleRowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd,
+ const QModelIndex &destinationParent, int destinationRow);
+ virtual void handleRowsRemoved(const QModelIndex &parent, int start, int end);
+
+ virtual void handleMappingChanged();
+ virtual void handlePendingResolve();
+
+protected:
+ virtual void resolveModel() = 0;
+
+ QPointer<const QAbstractItemModel> m_itemModel; // Not owned
+ QAbstractDataMapping *m_activeMapping;
+ bool resolvePending;
+ QTimer m_resolveTimer;
+ QList<QAbstractDataMapping *> m_mappings;
+
+private:
+ Q_DISABLE_COPY(AbstractItemModelHandler)
+};
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/data/abstractrenderitem.cpp b/src/datavisualization/data/abstractrenderitem.cpp
index 004fb598..22a1c6de 100644
--- a/src/datavis3d/data/abstractrenderitem.cpp
+++ b/src/datavisualization/data/abstractrenderitem.cpp
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -18,48 +18,43 @@
#include "abstractrenderitem_p.h"
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
AbstractRenderItem::AbstractRenderItem()
- : m_labelItem(0),
- m_selectionLabel(0)
+ : m_selectionLabelItem(0)
{
}
-AbstractRenderItem::~AbstractRenderItem()
+AbstractRenderItem::AbstractRenderItem(const AbstractRenderItem &other)
{
- delete m_labelItem;
- delete m_selectionLabel;
+ m_selectionLabel = other.m_selectionLabel;
+ m_translation = other.m_translation;
+ m_selectionLabelItem = 0;
}
-LabelItem &AbstractRenderItem::labelItem()
+AbstractRenderItem::~AbstractRenderItem()
{
- if (!m_labelItem)
- m_labelItem = new LabelItem;
- return *m_labelItem;
+ delete m_selectionLabelItem;
}
-LabelItem &AbstractRenderItem::selectionLabel()
+LabelItem &AbstractRenderItem::selectionLabelItem()
{
- if (!m_selectionLabel)
- m_selectionLabel = new LabelItem;
- return *m_selectionLabel;
+ if (!m_selectionLabelItem)
+ m_selectionLabelItem = new LabelItem;
+ return *m_selectionLabelItem;
}
-QString &AbstractRenderItem::label()
+void AbstractRenderItem::setSelectionLabel(const QString &label)
{
- if (m_label.isNull())
- formatLabel();
- return m_label;
+ if (m_selectionLabelItem)
+ m_selectionLabelItem->clear();
+ m_selectionLabel = label;
}
-void AbstractRenderItem::setLabel(const QString &label)
+QString &AbstractRenderItem::selectionLabel()
{
- if (m_labelItem)
- m_labelItem->clear();
- if (m_selectionLabel)
- m_selectionLabel->clear();
- m_label = label;
+ return m_selectionLabel;
}
-QT_DATAVIS3D_END_NAMESPACE
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavis3d/data/abstractrenderitem_p.h b/src/datavisualization/data/abstractrenderitem_p.h
index 4bf4df71..5f623c41 100644
--- a/src/datavis3d/data/abstractrenderitem_p.h
+++ b/src/datavisualization/data/abstractrenderitem_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -29,46 +29,41 @@
#ifndef ABSTRACTRENDERITEM_P_H
#define ABSTRACTRENDERITEM_P_H
-#include "datavis3dglobal_p.h"
+#include "datavisualizationglobal_p.h"
#include "labelitem_p.h"
#include <QOpenGLFunctions>
#include <QString>
#include <QVector3D>
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
class AbstractRenderItem
{
public:
AbstractRenderItem();
+ AbstractRenderItem(const AbstractRenderItem &other);
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();
+ LabelItem &selectionLabelItem();
- // Formatted label for item.
- void setLabel(const QString &label);
- QString &label(); // Formats label if not previously formatted
+ // Formatted selection label for item.
+ void setSelectionLabel(const QString &label);
+ QString &selectionLabel(); // Formats selection label if not previously formatted
protected:
- virtual void formatLabel() = 0;
-
- QString m_label;
+ QString m_selectionLabel;
QVector3D m_translation;
- LabelItem *m_labelItem;
- LabelItem *m_selectionLabel;
+ LabelItem *m_selectionLabelItem;
friend class QAbstractDataItem;
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif
diff --git a/src/datavisualization/data/baritemmodelhandler.cpp b/src/datavisualization/data/baritemmodelhandler.cpp
new file mode 100644
index 00000000..f7611668
--- /dev/null
+++ b/src/datavisualization/data/baritemmodelhandler.cpp
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 "baritemmodelhandler_p.h"
+#include "qitemmodelbardatamapping_p.h"
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+BarItemModelHandler::BarItemModelHandler(QItemModelBarDataProxy *proxy, QObject *parent)
+ : AbstractItemModelHandler(parent),
+ m_proxy(proxy),
+ m_proxyArray(0),
+ m_columnCount(0)
+{
+}
+
+BarItemModelHandler::~BarItemModelHandler()
+{
+}
+
+// Resolve entire item model into QBarDataArray.
+void BarItemModelHandler::resolveModel()
+{
+ QItemModelBarDataMapping *mapping = static_cast<QItemModelBarDataMapping *>(m_activeMapping);
+ if (m_itemModel.isNull() || !mapping) {
+ m_proxy->resetArray(0);
+ return;
+ }
+
+ if (!mapping->useModelCategories()
+ && (mapping->rowRole().isEmpty() || mapping->columnRole().isEmpty())) {
+ m_proxy->resetArray(0);
+ return;
+ }
+
+ QStringList rowLabels;
+ QStringList columnLabels;
+
+ QHash<int, QByteArray> roleHash = m_itemModel->roleNames();
+
+ // Default to display role if no mapping
+ int valueRole = roleHash.key(mapping->valueRole().toLatin1(), Qt::DisplayRole);
+ int rowCount = m_itemModel->rowCount();
+ int columnCount = m_itemModel->columnCount();
+
+ if (mapping->useModelCategories()) {
+ // If dimensions have changed, recreate the array
+ if (m_proxyArray != m_proxy->array() || columnCount != m_columnCount
+ || rowCount != m_proxyArray->size()) {
+ m_proxyArray = new QBarDataArray;
+ m_proxyArray->reserve(rowCount);
+ for (int i = 0; i < rowCount; i++)
+ m_proxyArray->append(new QBarDataRow(columnCount));
+ }
+ for (int i = 0; i < rowCount; i++) {
+ QBarDataRow &newProxyRow = *m_proxyArray->at(i);
+ for (int j = 0; j < columnCount; j++)
+ newProxyRow[j].setValue(m_itemModel->index(i, j).data(valueRole).toReal());
+ }
+ // Generate labels from headers if using model rows/columns
+ for (int i = 0; i < rowCount; i++)
+ rowLabels << m_itemModel->headerData(i, Qt::Vertical).toString();
+ for (int i = 0; i < columnCount; i++)
+ columnLabels << m_itemModel->headerData(i, Qt::Horizontal).toString();
+ m_columnCount = columnCount;
+ } else {
+ int rowRole = roleHash.key(mapping->rowRole().toLatin1());
+ int columnRole = roleHash.key(mapping->columnRole().toLatin1());
+
+ bool generateRows = mapping->autoRowCategories();
+ bool generateColumns = mapping->autoColumnCategories();
+ QStringList rowList;
+ QStringList columnList;
+ // For detecting duplicates in categories generation, using QHashes should be faster than
+ // simple QStringList::contains() check.
+ QHash<QString, bool> rowListHash;
+ QHash<QString, bool> columnListHash;
+
+ // 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);
+ QString rowRoleStr = index.data(rowRole).toString();
+ QString columnRoleStr = index.data(columnRole).toString();
+ itemValueMap[rowRoleStr][columnRoleStr] = index.data(valueRole).toReal();
+ if (generateRows && !rowListHash.value(rowRoleStr, false)) {
+ rowListHash.insert(rowRoleStr, true);
+ rowList << rowRoleStr;
+ }
+ if (generateColumns && !columnListHash.value(columnRoleStr, false)) {
+ columnListHash.insert(columnRoleStr, true);
+ columnList << columnRoleStr;
+ }
+ }
+ }
+
+ if (generateRows)
+ mapping->dptr()->m_rowCategories = rowList;
+ else
+ rowList = mapping->rowCategories();
+
+ if (generateColumns)
+ mapping->dptr()->m_columnCategories = columnList;
+ else
+ columnList = mapping->columnCategories();
+
+ // If dimensions have changed, recreate the array
+ if (m_proxyArray != m_proxy->array() || columnList.size() != m_columnCount
+ || rowList.size() != m_proxyArray->size()) {
+ m_proxyArray = new QBarDataArray;
+ m_proxyArray->reserve(rowList.size());
+ for (int i = 0; i < rowList.size(); i++)
+ m_proxyArray->append(new QBarDataRow(columnList.size()));
+ }
+ // Create new data array from itemValueMap
+ for (int i = 0; i < rowList.size(); i++) {
+ QString rowKey = rowList.at(i);
+ QBarDataRow &newProxyRow = *m_proxyArray->at(i);
+ for (int j = 0; j < columnList.size(); j++)
+ newProxyRow[j].setValue(itemValueMap[rowKey][columnList.at(j)]);
+ }
+
+ rowLabels = rowList;
+ columnLabels = columnList;
+ m_columnCount = columnList.size();
+ }
+
+ m_proxy->resetArray(m_proxyArray, rowLabels, columnLabels);
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavis3d/data/qitemmodelmapdatamapping_p.h b/src/datavisualization/data/baritemmodelhandler_p.h
index 99618942..54b45f2e 100644
--- a/src/datavis3d/data/qitemmodelmapdatamapping_p.h
+++ b/src/datavisualization/data/baritemmodelhandler_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,37 +20,35 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization 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 BARITEMMODELHANDLER_P_H
+#define BARITEMMODELHANDLER_P_H
-#ifndef QITEMMODELMAPDATAMAPPING_P_H
-#define QITEMMODELMAPDATAMAPPING_P_H
+#include "abstractitemmodelhandler_p.h"
+#include "qitemmodelbardataproxy.h"
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
-class QItemModelMapDataMappingPrivate : public QObject
+class BarItemModelHandler : public AbstractItemModelHandler
{
Q_OBJECT
public:
- QItemModelMapDataMappingPrivate(QItemModelMapDataMapping *q);
- virtual ~QItemModelMapDataMappingPrivate();
+ BarItemModelHandler(QItemModelBarDataProxy *proxy, QObject *parent = 0);
+ virtual ~BarItemModelHandler();
-private:
- QString m_labelRole;
- QString m_xPosRole;
- QString m_yPosRole;
- QString m_valueRole;
+protected:
+ void virtual resolveModel();
- QItemModelMapDataMapping *q_ptr;
-
- friend class QItemModelMapDataMapping;
+ QItemModelBarDataProxy *m_proxy; // Not owned
+ QBarDataArray *m_proxyArray; // Not owned
+ int m_columnCount;
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif
diff --git a/src/datavis3d/data/barrenderitem.cpp b/src/datavisualization/data/barrenderitem.cpp
index db377aa3..558e2f96 100644
--- a/src/datavis3d/data/barrenderitem.cpp
+++ b/src/datavisualization/data/barrenderitem.cpp
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -19,28 +19,49 @@
#include "barrenderitem_p.h"
#include "bars3drenderer_p.h"
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
BarRenderItem::BarRenderItem()
: AbstractRenderItem(),
- m_renderer(0),
- m_value(0)
+ m_value(0),
+ m_height(0.0f),
+ m_sliceLabelItem(0)
{
}
+BarRenderItem::BarRenderItem(const BarRenderItem &other)
+ : AbstractRenderItem(other)
+{
+ m_value = other.m_value;
+ m_position = other.m_position;
+ m_height = other.m_height;
+ m_sliceLabel = other.m_sliceLabel;
+ m_sliceLabelItem = 0;
+}
+
BarRenderItem::~BarRenderItem()
{
+ delete m_sliceLabelItem;
+}
+
+LabelItem &BarRenderItem::sliceLabelItem()
+{
+ if (!m_sliceLabelItem)
+ m_sliceLabelItem = new LabelItem;
+ return *m_sliceLabelItem;
}
-void BarRenderItem::formatLabel()
+void BarRenderItem::setSliceLabel(const QString &label)
{
- // 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
+ if (m_sliceLabelItem)
+ m_sliceLabelItem->clear();
+ m_sliceLabel = label;
}
-QT_DATAVIS3D_END_NAMESPACE
+QString &BarRenderItem::sliceLabel()
+{
+ return m_sliceLabel;
+}
+
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavis3d/data/barrenderitem_p.h b/src/datavisualization/data/barrenderitem_p.h
index babab795..6cd2b0fa 100644
--- a/src/datavis3d/data/barrenderitem_p.h
+++ b/src/datavisualization/data/barrenderitem_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -31,14 +31,15 @@
#include "abstractrenderitem_p.h"
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
-class Bars3dRenderer;
+class Bars3DRenderer;
class BarRenderItem : public AbstractRenderItem
{
public:
BarRenderItem();
+ BarRenderItem(const BarRenderItem &other);
virtual ~BarRenderItem();
// Position relative to data window (for bar label generation)
@@ -53,32 +54,36 @@ public:
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; }
+ // Label item for formatted label
+ LabelItem &sliceLabelItem();
-protected:
- virtual void formatLabel();
+ // Formatted label for item.
+ void setSliceLabel(const QString &label);
+ QString &sliceLabel(); // Formats label if not previously formatted
- Bars3dRenderer *m_renderer;
+protected:
qreal m_value;
QPoint m_position; // x = row, y = column
GLfloat m_height;
+ QString m_sliceLabel;
+ LabelItem *m_sliceLabelItem;
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
- }
+ m_value = value;
+ // Force reformatting on next access by setting label string to null string
+ if (!m_sliceLabel.isNull())
+ setSliceLabel(QString());
+ if (!m_selectionLabel.isNull())
+ setSelectionLabel(QString());
}
typedef QVector<BarRenderItem> BarRenderItemRow;
typedef QVector<BarRenderItemRow> BarRenderItemArray;
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif
diff --git a/src/datavis3d/data/data.pri b/src/datavisualization/data/data.pri
index a3b28e6e..770d2bd1 100644
--- a/src/datavis3d/data/data.pri
+++ b/src/datavisualization/data/data.pri
@@ -12,24 +12,31 @@ HEADERS += \
$$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
+ $$PWD/qitemmodelscatterdataproxy_p.h \
+ $$PWD/abstractitemmodelhandler_p.h \
+ $$PWD/baritemmodelhandler_p.h \
+ $$PWD/qabstractdatamapping.h \
+ $$PWD/qabstractdatamapping_p.h \
+ $$PWD/scatteritemmodelhandler_p.h \
+ $$PWD/qsurfacedataproxy.h \
+ $$PWD/qsurfacedataproxy_p.h \
+ $$PWD/qheightmapsurfacedataproxy.h \
+ $$PWD/qheightmapsurfacedataproxy_p.h \
+ $$PWD/qitemmodelsurfacedatamapping.h \
+ $$PWD/qitemmodelsurfacedatamapping_p.h \
+ $$PWD/qitemmodelsurfacedataproxy.h \
+ $$PWD/qitemmodelsurfacedataproxy_p.h \
+ $$PWD/surfaceitemmodelhandler_p.h \
+ $$PWD/qsurfacedataitem.h \
+ $$PWD/qsurfacedataitem_p.h
SOURCES += \
$$PWD/labelitem.cpp \
@@ -40,13 +47,18 @@ SOURCES += \
$$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
+ $$PWD/qitemmodelscatterdataproxy.cpp \
+ $$PWD/abstractitemmodelhandler.cpp \
+ $$PWD/baritemmodelhandler.cpp \
+ $$PWD/qabstractdatamapping.cpp \
+ $$PWD/scatteritemmodelhandler.cpp \
+ $$PWD/qsurfacedataproxy.cpp \
+ $$PWD/qheightmapsurfacedataproxy.cpp \
+ $$PWD/qitemmodelsurfacedatamapping.cpp \
+ $$PWD/qitemmodelsurfacedataproxy.cpp \
+ $$PWD/surfaceitemmodelhandler.cpp \
+ $$PWD/qsurfacedataitem.cpp
diff --git a/src/datavis3d/data/labelitem.cpp b/src/datavisualization/data/labelitem.cpp
index 1d1bf6f7..5e27a50e 100644
--- a/src/datavis3d/data/labelitem.cpp
+++ b/src/datavisualization/data/labelitem.cpp
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -18,7 +18,7 @@
#include "labelitem_p.h"
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
LabelItem::LabelItem()
: m_size(QSize(0, 0)),
@@ -61,4 +61,4 @@ void LabelItem::clear()
m_size = QSize(0, 0);
}
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavis3d/data/labelitem_p.h b/src/datavisualization/data/labelitem_p.h
index 84625002..c10c1f12 100644
--- a/src/datavis3d/data/labelitem_p.h
+++ b/src/datavisualization/data/labelitem_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -29,11 +29,11 @@
#ifndef LABELITEM_P_H
#define LABELITEM_P_H
-#include "datavis3dglobal_p.h"
+#include "datavisualizationglobal_p.h"
#include <QOpenGLFunctions>
#include <QSize>
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
class LabelItem
{
@@ -54,6 +54,6 @@ private:
GLuint m_textureId;
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif
diff --git a/src/datavisualization/data/qabstractdatamapping.cpp b/src/datavisualization/data/qabstractdatamapping.cpp
new file mode 100644
index 00000000..892d2f94
--- /dev/null
+++ b/src/datavisualization/data/qabstractdatamapping.cpp
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 "qabstractdatamapping_p.h"
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+/*!
+ * \class QAbstractDataMapping
+ * \inmodule QtDataVisualization
+ * \brief Abstract base class for QtDataVisualization data mapping classes.
+ * \since 1.0.0
+ *
+ * Data mapping classes provide a way to map data from an external data source to one of
+ * QtDataVisualization data proxies.
+ * \sa QItemModelBarDataMapping, QItemModelScatterDataMapping
+ */
+
+/*!
+ * \internal
+ */
+QAbstractDataMapping::QAbstractDataMapping(QAbstractDataMappingPrivate *d, QObject *parent)
+ : QObject(parent),
+ d_ptr(d)
+{
+}
+
+/*!
+ * Destroys QAbstractDataMapping.
+ */
+QAbstractDataMapping::~QAbstractDataMapping()
+{
+}
+
+/*!
+ * \fn void QAbstractDataMapping::mappingChanged()
+ *
+ * Emitted when any mapping has changed.
+ */
+
+// QItemModelBarDataMappingPrivate
+
+QAbstractDataMappingPrivate::QAbstractDataMappingPrivate(QAbstractDataMapping *q,
+ QAbstractDataProxy::DataType type)
+ : QObject(0),
+ q_ptr(q),
+ m_type(type)
+{
+}
+
+QAbstractDataMappingPrivate::~QAbstractDataMappingPrivate()
+{
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
diff --git a/src/datavisualization/data/qabstractdatamapping.h b/src/datavisualization/data/qabstractdatamapping.h
new file mode 100644
index 00000000..eb892cb7
--- /dev/null
+++ b/src/datavisualization/data/qabstractdatamapping.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 QtDataVisualization 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 QABSTRACTDATAMAPPING_H
+#define QABSTRACTDATAMAPPING_H
+
+#include <QtDataVisualization/qdatavisualizationenums.h>
+#include <QtDataVisualization/qabstractdataproxy.h>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class QAbstractDataMappingPrivate;
+
+class QT_DATAVISUALIZATION_EXPORT QAbstractDataMapping : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit QAbstractDataMapping(QAbstractDataMappingPrivate *d, QObject *parent = 0);
+ virtual ~QAbstractDataMapping();
+
+signals:
+ void mappingChanged();
+
+private:
+ QScopedPointer<QAbstractDataMappingPrivate> d_ptr;
+
+ Q_DISABLE_COPY(QAbstractDataMapping)
+
+ friend class QItemModelBarDataMapping;
+ friend class QItemModelScatterDataMapping;
+ friend class QItemModelSurfaceDataMapping;
+};
+
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
+#endif
diff --git a/src/datavisualization/data/qabstractdatamapping_p.h b/src/datavisualization/data/qabstractdatamapping_p.h
new file mode 100644
index 00000000..39012237
--- /dev/null
+++ b/src/datavisualization/data/qabstractdatamapping_p.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 QtDataVisualization 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 "qabstractdatamapping.h"
+
+#ifndef QABSTRACTDATAMAPPING_P_H
+#define QABSTRACTDATAMAPPING_P_H
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class QAbstractDataMappingPrivate : public QObject
+{
+ Q_OBJECT
+public:
+ QAbstractDataMappingPrivate(QAbstractDataMapping *q, QAbstractDataProxy::DataType type);
+ virtual ~QAbstractDataMappingPrivate();
+
+private:
+ QAbstractDataMapping *q_ptr;
+ QAbstractDataProxy::DataType m_type;
+};
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
+#endif
diff --git a/src/datavisualization/data/qabstractdataproxy.cpp b/src/datavisualization/data/qabstractdataproxy.cpp
new file mode 100644
index 00000000..8ccb0d7a
--- /dev/null
+++ b/src/datavisualization/data/qabstractdataproxy.cpp
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+/*!
+ * \class QAbstractDataProxy
+ * \inmodule QtDataVisualization
+ * \brief Base class for all QtDataVisualization data proxies.
+ * \since 1.0.0
+ *
+ * You use the visualization type specific inherited classes instead of the base class.
+ * \sa QBarDataProxy, QScatterDataProxy, QSurfaceDataProxy, {Qt Data Visualization Data Handling}
+ */
+
+/*!
+ * \qmltype AbstractDataProxy
+ * \inqmlmodule com.digia.QtDataVisualization 1.0
+ * \since com.digia.QtDataVisualization 1.0
+ * \ingroup datavisualization_qml
+ * \instantiates QAbstractDataProxy
+ * \brief Base type for all QtDataVisualization data proxies.
+ *
+ * This type is uncreatable, but contains properties that are exposed via subtypes.
+ * \sa BarDataProxy, ScatterDataProxy, SurfaceDataProxy, {Qt Data Visualization Data Handling}
+ */
+
+/*!
+ * \qmlproperty AbstractDataProxy.DataType AbstractDataProxy::type
+ * The type of the proxy.
+ */
+
+/*!
+ * \qmlproperty string AbstractDataProxy::itemLabelFormat
+ *
+ * Label format for data items in this proxy. This format is used for single item labels,
+ * e.g. when an item is selected. How the format is interpreted depends on proxy type. See
+ * each proxy class documentation for more information.
+ */
+
+/*!
+ * \enum QAbstractDataProxy::DataType
+ *
+ * Data type of the proxy.
+ *
+ * \value DataTypeNone
+ * No data type.
+ * \value DataTypeBar
+ * Data type for Q3DBars.
+ * \value DataTypeScatter
+ * Data type for Q3DScatter.
+ * \value DataTypeSurface
+ * Data type for Q3DSurface.
+ */
+
+/*!
+ * \internal
+ */
+QAbstractDataProxy::QAbstractDataProxy(QAbstractDataProxyPrivate *d, QObject *parent) :
+ QObject(parent),
+ d_ptr(d)
+{
+}
+
+/*!
+ * Destroys QAbstractDataProxy.
+ */
+QAbstractDataProxy::~QAbstractDataProxy()
+{
+}
+
+/*!
+ * \property QAbstractDataProxy::type
+ *
+ * The type of the proxy.
+ */
+QAbstractDataProxy::DataType QAbstractDataProxy::type() const
+{
+ return d_ptr->m_type;
+}
+
+/*!
+ * \property QAbstractDataProxy::itemLabelFormat
+ *
+ * Sets label \a format for data items in this proxy. This format is used for single item labels,
+ * e.g. when an item is selected. How the format is interpreted depends on proxy type. See
+ * each proxy class documentation for more information.
+ *
+ * \sa QBarDataProxy, QScatterDataProxy, QSurfaceDataProxy
+ */
+void QAbstractDataProxy::setItemLabelFormat(const QString &format)
+{
+ d_ptr->setItemLabelFormat(format);
+ emit itemLabelFormatChanged();
+}
+
+/*!
+ * \return label format for data items in this proxy.
+ */
+QString QAbstractDataProxy::itemLabelFormat() const
+{
+ return d_ptr->m_itemLabelFormat;
+}
+
+/*!
+ * \fn void QAbstractDataProxy::itemLabelFormatChanged()
+ *
+ * Emitted when label format changes.
+ */
+
+// QAbstractDataProxyPrivate
+
+QAbstractDataProxyPrivate::QAbstractDataProxyPrivate(QAbstractDataProxy *q, QAbstractDataProxy::DataType type)
+ : QObject(0),
+ q_ptr(q),
+ m_type(type),
+ m_isDefaultProxy(false)
+{
+}
+
+QAbstractDataProxyPrivate::~QAbstractDataProxyPrivate()
+{
+}
+
+void QAbstractDataProxyPrivate::setItemLabelFormat(const QString &format)
+{
+ m_itemLabelFormat = format;
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavis3d/data/qabstractdataproxy.h b/src/datavisualization/data/qabstractdataproxy.h
index 0e717dbb..db0e0863 100644
--- a/src/datavis3d/data/qabstractdataproxy.h
+++ b/src/datavisualization/data/qabstractdataproxy.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -19,38 +19,37 @@
#ifndef QABSTRACTDATAPROXY_H
#define QABSTRACTDATAPROXY_H
-#include <QtDataVis3D/qdatavis3denums.h>
+#include <QtDataVisualization/qdatavisualizationenums.h>
#include <QObject>
#include <QScopedPointer>
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
class QAbstractDataProxyPrivate;
-class QT_DATAVIS3D_EXPORT QAbstractDataProxy : public QObject
+class QT_DATAVISUALIZATION_EXPORT QAbstractDataProxy : public QObject
{
Q_OBJECT
Q_ENUMS(DataType)
Q_PROPERTY(DataType type READ type)
+ Q_PROPERTY(QString itemLabelFormat READ itemLabelFormat WRITE setItemLabelFormat NOTIFY itemLabelFormatChanged)
public:
enum DataType {
DataTypeNone = 0,
DataTypeBar = 1,
- DataTypeMap = 2,
- DataTypeScatter = 4,
- DataTypeSurface = 8
+ DataTypeScatter = 2,
+ DataTypeSurface = 4
};
protected:
- explicit QAbstractDataProxy(QAbstractDataProxyPrivate *d);
+ explicit QAbstractDataProxy(QAbstractDataProxyPrivate *d, QObject *parent = 0);
+
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;
@@ -62,8 +61,13 @@ protected:
private:
Q_DISABLE_COPY(QAbstractDataProxy)
+
+ friend class Abstract3DController;
+ friend class Bars3DController;
+ friend class Scatter3DController;
+ friend class Surface3DController;
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif // QABSTRACTDATAPROXY_H
diff --git a/src/datavis3d/data/qabstractdataproxy_p.h b/src/datavisualization/data/qabstractdataproxy_p.h
index eda13b86..4aa1b678 100644
--- a/src/datavis3d/data/qabstractdataproxy_p.h
+++ b/src/datavisualization/data/qabstractdataproxy_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,20 +20,20 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization 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 "datavisualizationglobal_p.h"
#include "qabstractdataproxy.h"
#include <QString>
#ifndef QABSTRACTDATAPROXY_P_H
#define QABSTRACTDATAPROXY_P_H
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
class QAbstractDataProxyPrivate : public QObject
{
@@ -44,15 +44,19 @@ public:
void setItemLabelFormat(const QString &format);
+ inline bool isDefaultProxy() { return m_isDefaultProxy; }
+ inline void setDefaultProxy(bool isDefault) { m_isDefaultProxy = isDefault; }
+
protected:
QAbstractDataProxy *q_ptr;
QAbstractDataProxy::DataType m_type;
QString m_itemLabelFormat;
+ bool m_isDefaultProxy;
private:
friend class QAbstractDataProxy;
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif // QABSTRACTDATAPROXY_P_H
diff --git a/src/datavis3d/data/qbardataitem.cpp b/src/datavisualization/data/qbardataitem.cpp
index 1e8f3d95..2803c01a 100644
--- a/src/datavis3d/data/qbardataitem.cpp
+++ b/src/datavisualization/data/qbardataitem.cpp
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -18,18 +18,18 @@
#include "qbardataitem_p.h"
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
/*!
* \class QBarDataItem
- * \inmodule QtDataVis3D
+ * \inmodule QtDataVisualization
* \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}
+ * \sa QBarDataProxy, {Qt Data Visualization C++ Classes}
*/
/*!
@@ -41,12 +41,18 @@ QBarDataItem::QBarDataItem()
{
}
+/*!
+ * Constructs QBarDataItem with \a value.
+ */
QBarDataItem::QBarDataItem(qreal value)
: d_ptr(0),
m_value(value)
{
}
+/*!
+ * Constructs a copy of \a other.
+ */
QBarDataItem::QBarDataItem(const QBarDataItem &other)
{
operator=(other);
@@ -60,6 +66,9 @@ QBarDataItem::~QBarDataItem()
delete d_ptr;
}
+/*!
+ * Assigns a copy of \a other to this object.
+ */
QBarDataItem &QBarDataItem::operator=(const QBarDataItem &other)
{
m_value = other.m_value;
@@ -71,23 +80,25 @@ QBarDataItem &QBarDataItem::operator=(const QBarDataItem &other)
return *this;
}
-void QBarDataItem::setValue(qreal value)
-{
- m_value = value;
-}
+/*!
+ * \fn void QBarDataItem::setValue(qreal value)
+ * Sets \a value to this data item.
+ */
-qreal QBarDataItem::value() const
-{
- return m_value;
-}
+/*!
+ * \fn qreal QBarDataItem::value() const
+ * \return value of this data item.
+ */
+/*!
+ * \internal
+ */
void QBarDataItem::createExtraData()
{
if (!d_ptr)
d_ptr = new QBarDataItemPrivate;
}
-
QBarDataItemPrivate::QBarDataItemPrivate()
{
}
@@ -96,4 +107,4 @@ QBarDataItemPrivate::~QBarDataItemPrivate()
{
}
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavis3d/data/qbardataitem.h b/src/datavisualization/data/qbardataitem.h
index d7062b66..68bbcedf 100644
--- a/src/datavis3d/data/qbardataitem.h
+++ b/src/datavisualization/data/qbardataitem.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -19,13 +19,13 @@
#ifndef QBARDATAITEM_H
#define QBARDATAITEM_H
-#include <QtDataVis3D/qdatavis3denums.h>
+#include <QtDataVisualization/qdatavisualizationenums.h>
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
class QBarDataItemPrivate;
-class QT_DATAVIS3D_EXPORT QBarDataItem
+class QT_DATAVISUALIZATION_EXPORT QBarDataItem
{
public:
QBarDataItem();
@@ -35,8 +35,8 @@ public:
QBarDataItem &operator=(const QBarDataItem &other);
- void setValue(qreal value);
- qreal value() const;
+ void setValue(qreal value) { m_value = value; }
+ qreal value() const { return m_value; }
// TODO Set color, label format, ...?
@@ -49,6 +49,6 @@ private:
qreal m_value;
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif
diff --git a/src/datavis3d/data/qbardataitem_p.h b/src/datavisualization/data/qbardataitem_p.h
index e63ce787..20b7ea69 100644
--- a/src/datavis3d/data/qbardataitem_p.h
+++ b/src/datavisualization/data/qbardataitem_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -29,10 +29,10 @@
#ifndef QBARDATAITEM_P_H
#define QBARDATAITEM_P_H
-#include "datavis3dglobal_p.h"
+#include "datavisualizationglobal_p.h"
#include "qbardataitem.h"
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
class QBarDataItemPrivate
{
@@ -46,6 +46,6 @@ protected:
friend class QBarDataItem;
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif
diff --git a/src/datavisualization/data/qbardataproxy.cpp b/src/datavisualization/data/qbardataproxy.cpp
new file mode 100644
index 00000000..2ec38980
--- /dev/null
+++ b/src/datavisualization/data/qbardataproxy.cpp
@@ -0,0 +1,707 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+/*!
+ * \class QBarDataProxy
+ * \inmodule QtDataVisualization
+ * \brief Base proxy class for Q3DBars.
+ * \since 1.0.0
+ *
+ * QBarDataProxy handles adding, inserting, changing and removing rows of data.
+ *
+ * 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.
+ * If you use QBarDataRow pointers to directly modify data after adding the array to the proxy,
+ * you must also emit proper signal to make the graph update.
+ *
+ * QBarDataProxy optionally keeps track of row and column labels, which Q3DCategoryAxis can utilize
+ * to show axis labels. The row and column labels are stored in separate array from the data and
+ * row manipulation methods provide an alternate versions that don't affect the row labels.
+ * This enables the option of having row labels that relate to the position of the data in the
+ * array rather than the data itself.
+ *
+ * QBarDataProxy supports the following format tags for QAbstractDataProxy::setItemLabelFormat():
+ * \table
+ * \row
+ * \li @rowTitle \li Title from row axis
+ * \row
+ * \li @colTitle \li Title from column axis
+ * \row
+ * \li @valueTitle \li Title from value axis
+ * \row
+ * \li @rowIdx \li Visible row index
+ * \row
+ * \li @colIdx \li Visible Column index
+ * \row
+ * \li @rowLabel \li Label from row axis
+ * \row
+ * \li @colLabel \li Label from column axis
+ * \row
+ * \li @valueLabel \li Item value formatted using the same format the value axis attached to the graph uses,
+ * see \l{Q3DValueAxis::setLabelFormat()} for more information.
+ * \row
+ * \li %<format spec> \li Item value in specified format.
+ * \endtable
+ *
+ * For example:
+ * \snippet doc_src_qtdatavisualization.cpp 1
+ *
+ * \sa {Qt Data Visualization Data Handling}
+ */
+
+/*!
+ * \qmltype BarDataProxy
+ * \inqmlmodule com.digia.QtDataVisualization 1.0
+ * \since com.digia.QtDataVisualization 1.0
+ * \ingroup datavisualization_qml
+ * \instantiates QBarDataProxy
+ * \inherits AbstractDataProxy
+ * \brief Base proxy type for Bars3D.
+ *
+ * This type handles adding, inserting, changing and removing rows of data with Qt Quick 2.
+ *
+ * This type is uncreatable, but contains properties that are exposed via subtypes.
+ *
+ * For more complete description, see QBarDataProxy.
+ *
+ * \sa ItemModelBarDataProxy, {Qt Data Visualization Data Handling}
+ */
+
+/*!
+ * \qmlproperty int BarDataProxy::rowCount
+ * Row count in the array.
+ */
+
+/*!
+ * \qmlproperty list BarDataProxy::rowLabels
+ *
+ * Optional row labels for the array. Indexes in this array match row indexes in data array.
+ * If the list is shorter than row count, all rows will not get labels.
+ */
+
+/*!
+ * \qmlproperty list BarDataProxy::columnLabels
+ *
+ * Optional column labels for the array. Indexes in this array match column indexes in rows.
+ * If the list is shorter than the longest row, all columns will not get labels.
+ */
+
+/*!
+ * Constructs QBarDataProxy with the given \a parent.
+ */
+QBarDataProxy::QBarDataProxy(QObject *parent) :
+ QAbstractDataProxy(new QBarDataProxyPrivate(this), parent)
+{
+}
+
+/*!
+ * \internal
+ */
+QBarDataProxy::QBarDataProxy(QBarDataProxyPrivate *d, QObject *parent) :
+ QAbstractDataProxy(d, parent)
+{
+}
+
+/*!
+ * Destroys QBarDataProxy.
+ */
+QBarDataProxy::~QBarDataProxy()
+{
+}
+
+/*!
+ * Clears the existing array and row and column labels.
+ */
+void QBarDataProxy::resetArray()
+{
+ resetArray(0, QStringList(), QStringList());
+}
+
+/*!
+ * Takes ownership of the \a newArray. Clears the existing array and if the \a newArray is
+ * different than the existing array. If it's the same array, this just triggers arrayReset()
+ * signal.
+ * Passing null array deletes the old array and creates a new empty array.
+ * Row and column labels are not affected.
+ */
+void QBarDataProxy::resetArray(QBarDataArray *newArray)
+{
+ dptr()->resetArray(newArray, 0, 0);
+ emit arrayReset();
+}
+
+/*!
+ * Takes ownership of the \a newArray. Clears the existing array and if the \a newArray is
+ * different than the existing array. If it's the same array, this just triggers arrayReset()
+ * signal.
+ * Passing null array deletes the old array and creates a new empty array.
+ * The \a rowLabels and \a columnLabels lists specify the new labels for rows and columns.
+ */
+void QBarDataProxy::resetArray(QBarDataArray *newArray, const QStringList &rowLabels,
+ const QStringList &columnLabels)
+{
+ dptr()->resetArray(newArray, &rowLabels, &columnLabels);
+ emit arrayReset();
+}
+
+/*!
+ * Changes existing rows by replacing a row at \a rowIndex with \a row. The \a row can be
+ * the same as the existing row already stored at the \a rowIndex.
+ * Existing row labels are not affected.
+ */
+void QBarDataProxy::setRow(int rowIndex, QBarDataRow *row)
+{
+ dptr()->setRow(rowIndex, row, 0);
+ emit rowsChanged(rowIndex, 1);
+}
+
+/*!
+ * Changes existing rows by replacing a row at \a rowIndex with \a row. The \a row can be
+ * the same as the existing row already stored at the \a rowIndex.
+ * Changes the row label to the \a label.
+ */
+void QBarDataProxy::setRow(int rowIndex, QBarDataRow *row, const QString &label)
+{
+ dptr()->setRow(rowIndex, row, &label);
+ emit rowsChanged(rowIndex, 1);
+}
+
+/*!
+ * Changes existing rows by replacing a rows starting at \a rowIndex with \a rows.
+ * Existing row labels are not affected. The rows in the \a rows array can be
+ * the same as the existing rows already stored at the \a rowIndex.
+ */
+void QBarDataProxy::setRows(int rowIndex, const QBarDataArray &rows)
+{
+ dptr()->setRows(rowIndex, rows, 0);
+ emit rowsChanged(rowIndex, rows.size());
+}
+
+/*!
+ * Changes existing rows by replacing a rows starting at \a rowIndex with \a rows.
+ * The row labels are changed to \a labels. The rows in the \a rows array can be
+ * the same as the existing rows already stored at the \a rowIndex.
+ */
+void QBarDataProxy::setRows(int rowIndex, const QBarDataArray &rows, const QStringList &labels)
+{
+ dptr()->setRows(rowIndex, rows, &labels);
+ emit rowsChanged(rowIndex, rows.size());
+}
+
+/*!
+ * Changes a single item at \a rowIndex, \a columnIndex to the \a item.
+ */
+void QBarDataProxy::setItem(int rowIndex, int columnIndex, const QBarDataItem &item)
+{
+ dptr()->setItem(rowIndex, columnIndex, item);
+ emit itemChanged(rowIndex, columnIndex);
+}
+
+/*!
+ * Adds a new \a row to the end of array.
+ * Existing row labels are not affected.
+ *
+ * \return index of the added row.
+ */
+int QBarDataProxy::addRow(QBarDataRow *row)
+{
+ int addIndex = dptr()->addRow(row, 0);
+ emit rowsAdded(addIndex, 1);
+ return addIndex;
+}
+
+/*!
+ * Adds a new \a row with the \a label to the end of array.
+ *
+ * \return index of the added row.
+ */
+int QBarDataProxy::addRow(QBarDataRow *row, const QString &label)
+{
+ int addIndex = dptr()->addRow(row, &label);
+ emit rowsAdded(addIndex, 1);
+ return addIndex;
+}
+
+/*!
+ * Adds new \a rows to the end of array.
+ * Existing row labels are not affected.
+ *
+ * \return index of the first added row.
+ */
+int QBarDataProxy::addRows(const QBarDataArray &rows)
+{
+ int addIndex = dptr()->addRows(rows, 0);
+ emit rowsAdded(addIndex, rows.size());
+ return addIndex;
+}
+
+/*!
+ * Adds new \a rows with \a labels to the end of array.
+ *
+ * \return index of the first added row.
+ */
+int QBarDataProxy::addRows(const QBarDataArray &rows, const QStringList &labels)
+{
+ int addIndex = dptr()->addRows(rows, &labels);
+ emit rowsAdded(addIndex, rows.size());
+ return addIndex;
+}
+
+/*!
+ * Inserts a new \a row into \a rowIndex.
+ * If rowIndex is equal to array size, rows are added to end of the array.
+ * Any existing row labels are not affected.
+ * \note Row labels array will be out of sync with row array after this call,
+ * if there were labeled rows beyond the inserted row.
+ */
+void QBarDataProxy::insertRow(int rowIndex, QBarDataRow *row)
+{
+ dptr()->insertRow(rowIndex, row, 0);
+ emit rowsInserted(rowIndex, 1);
+}
+
+/*!
+ * Inserts a new \a row with the \a label into \a rowIndex.
+ * If rowIndex is equal to array size, rows are added to end of the array.
+ */
+void QBarDataProxy::insertRow(int rowIndex, QBarDataRow *row, const QString &label)
+{
+ dptr()->insertRow(rowIndex, row, &label);
+ emit rowsInserted(rowIndex, 1);
+}
+
+/*!
+ * Inserts new \a rows into \a rowIndex.
+ * If rowIndex is equal to array size, rows are added to end of the array.
+ * Any existing row labels are not affected.
+ * \note Row labels array will be out of sync with row array after this call,
+ * if there were labeled rows beyond the inserted rows.
+ */
+void QBarDataProxy::insertRows(int rowIndex, const QBarDataArray &rows)
+{
+ dptr()->insertRows(rowIndex, rows, 0);
+ emit rowsInserted(rowIndex, rows.size());
+}
+
+/*!
+ * Inserts new \a rows with \a labels into \a rowIndex.
+ * If rowIndex is equal to array size, rows are added to end of the array.
+ */
+void QBarDataProxy::insertRows(int rowIndex, const QBarDataArray &rows, const QStringList &labels)
+{
+ dptr()->insertRows(rowIndex, rows, &labels);
+ emit rowsInserted(rowIndex, rows.size());
+}
+
+/*!
+ * Removes \a removeCount rows staring at \a rowIndex. Attempting to remove rows past the end of the
+ * array does nothing. If \a removeLabels is true, corresponding row labels are also removed. Otherwise
+ * the row labels are not affected.
+ * \note If \a removeLabels is false, the row labels array will be out of sync with the row array
+ * if there are labeled rows beyond the removed rows.
+ */
+void QBarDataProxy::removeRows(int rowIndex, int removeCount, bool removeLabels)
+{
+ if (rowIndex < rowCount() && removeCount >= 1) {
+ dptr()->removeRows(rowIndex, removeCount, removeLabels);
+ emit rowsRemoved(rowIndex, removeCount);
+ }
+}
+
+/*!
+ * \property QBarDataProxy::rowCount
+ *
+ * Row count in the array.
+ */
+int QBarDataProxy::rowCount() const
+{
+ return dptrc()->m_dataArray->size();
+}
+
+/*!
+ * \property QBarDataProxy::rowLabels
+ *
+ * Optional row labels for the array. Indexes in this array match row indexes in data array.
+ * If the list is shorter than row count, all rows will not get labels.
+ */
+QStringList QBarDataProxy::rowLabels() const
+{
+ return dptrc()->m_rowLabels;
+}
+
+void QBarDataProxy::setRowLabels(const QStringList &labels)
+{
+ if (dptr()->m_rowLabels != labels) {
+ dptr()->m_rowLabels = labels;
+ emit rowLabelsChanged();
+ }
+}
+
+/*!
+ * \property QBarDataProxy::columnLabels
+ *
+ * Optional column labels for the array. Indexes in this array match column indexes in rows.
+ * If the list is shorter than the longest row, all columns will not get labels.
+ */
+QStringList QBarDataProxy::columnLabels() const
+{
+ return dptrc()->m_columnLabels;
+}
+
+void QBarDataProxy::setColumnLabels(const QStringList &labels)
+{
+ if (dptr()->m_columnLabels != labels) {
+ dptr()->m_columnLabels = labels;
+ emit columnLabelsChanged();
+ }
+}
+
+/*!
+ * \return pointer to the data array.
+ */
+const QBarDataArray *QBarDataProxy::array() const
+{
+ return dptrc()->m_dataArray;
+}
+
+/*!
+ * \return pointer to the row at \a rowIndex. It is guaranteed to be valid only until next call
+ * that modifies data.
+ */
+const QBarDataRow *QBarDataProxy::rowAt(int rowIndex) const
+{
+ const QBarDataArray &dataArray = *dptrc()->m_dataArray;
+ Q_ASSERT(rowIndex >= 0 && rowIndex < dataArray.size());
+ return dataArray[rowIndex];
+}
+
+/*!
+ * \return pointer to the item at \a rowIndex, \a columnIndex. It is guaranteed to be valid only
+ * until next call that modifies data.
+ */
+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);
+}
+
+/*!
+ * \internal
+ */
+QBarDataProxyPrivate *QBarDataProxy::dptr()
+{
+ return static_cast<QBarDataProxyPrivate *>(d_ptr.data());
+}
+
+/*!
+ * \internal
+ */
+const QBarDataProxyPrivate *QBarDataProxy::dptrc() const
+{
+ return static_cast<const QBarDataProxyPrivate *>(d_ptr.data());
+}
+
+/*!
+ * \fn void QBarDataProxy::arrayReset()
+ *
+ * Emitted when data array is reset.
+ * If you change the whole array contents without calling resetArray(), you need to
+ * emit this signal yourself or the graph won't get updated.
+ */
+
+/*!
+ * \fn void QBarDataProxy::rowsAdded(int startIndex, int count)
+ *
+ * Emitted when rows have been added. Provides \a startIndex and \a count of rows added.
+ * If you add rows directly to the array without calling addRow() or addRows(), you
+ * need to emit this signal yourself or the graph won't get updated.
+ */
+
+/*!
+ * \fn void QBarDataProxy::rowsChanged(int startIndex, int count)
+ *
+ * Emitted when rows have changed. Provides \a startIndex and \a count of changed rows.
+ * If you change rows directly in the array without calling setRow() or setRows(), you
+ * need to emit this signal yourself or the graph won't get updated.
+ */
+
+/*!
+ * \fn void QBarDataProxy::rowsRemoved(int startIndex, int count)
+ *
+ * Emitted when rows have been removed. Provides \a startIndex and \a count of rows removed.
+ * Index is the current array size if rows were removed from the end of the array.
+ * If you remove rows directly from the array without calling removeRows(), you
+ * need to emit this signal yourself or the graph won't get updated.
+ */
+
+/*!
+ * \fn void QBarDataProxy::rowsInserted(int startIndex, int count)
+ *
+ * Emitted when rows have been inserted. Provides \a startIndex and \a count of inserted rows.
+ * If you insert rows directly into the array without calling insertRow() or insertRows(), you
+ * need to emit this signal yourself or the graph won't get updated.
+ */
+
+/*!
+ * \fn void QBarDataProxy::itemChanged(int rowIndex, int columnIndex)
+ *
+ * Emitted when an item has changed. Provides \a rowIndex and \a columnIndex of changed item.
+ * If you change an item directly in the array without calling setItem(), you
+ * need to emit this signal yourself or the graph won't get updated.
+ */
+
+// QBarDataProxyPrivate
+
+QBarDataProxyPrivate::QBarDataProxyPrivate(QBarDataProxy *q)
+ : QAbstractDataProxyPrivate(q, QAbstractDataProxy::DataTypeBar),
+ m_dataArray(new QBarDataArray)
+{
+ m_itemLabelFormat = QStringLiteral("@valueTitle: @valueLabel");
+}
+
+QBarDataProxyPrivate::~QBarDataProxyPrivate()
+{
+ clearArray();
+}
+
+void QBarDataProxyPrivate::resetArray(QBarDataArray *newArray, const QStringList *rowLabels,
+ const QStringList *columnLabels)
+{
+ if (rowLabels)
+ qptr()->setRowLabels(*rowLabels);
+ if (columnLabels)
+ qptr()->setColumnLabels(*columnLabels);
+
+ if (!newArray)
+ newArray = new QBarDataArray;
+
+ if (newArray != m_dataArray) {
+ clearArray();
+ m_dataArray = newArray;
+ }
+}
+
+void QBarDataProxyPrivate::setRow(int rowIndex, QBarDataRow *row, const QString *label)
+{
+ Q_ASSERT(rowIndex >= 0 && rowIndex < m_dataArray->size());
+
+ if (label)
+ fixRowLabels(rowIndex, 1, QStringList(*label), false);
+ if (row != m_dataArray->at(rowIndex)) {
+ clearRow(rowIndex);
+ (*m_dataArray)[rowIndex] = row;
+ }
+}
+
+void QBarDataProxyPrivate::setRows(int rowIndex, const QBarDataArray &rows, const QStringList *labels)
+{
+ QBarDataArray &dataArray = *m_dataArray;
+ Q_ASSERT(rowIndex >= 0 && (rowIndex + rows.size()) <= dataArray.size());
+ if (labels)
+ fixRowLabels(rowIndex, rows.size(), *labels, false);
+ for (int i = 0; i < rows.size(); i++) {
+ if (rows.at(i) != dataArray.at(rowIndex)) {
+ 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, const QString *label)
+{
+ int currentSize = m_dataArray->size();
+ if (label)
+ fixRowLabels(currentSize, 1, QStringList(*label), false);
+ m_dataArray->append(row);
+ return currentSize;
+}
+
+int QBarDataProxyPrivate::addRows(const QBarDataArray &rows, const QStringList *labels)
+{
+ int currentSize = m_dataArray->size();
+ if (labels)
+ fixRowLabels(currentSize, rows.size(), *labels, false);
+ for (int i = 0; i < rows.size(); i++)
+ m_dataArray->append(rows.at(i));
+ return currentSize;
+}
+
+void QBarDataProxyPrivate::insertRow(int rowIndex, QBarDataRow *row, const QString *label)
+{
+ Q_ASSERT(rowIndex >= 0 && rowIndex <= m_dataArray->size());
+ if (label)
+ fixRowLabels(rowIndex, 1, QStringList(*label), true);
+ m_dataArray->insert(rowIndex, row);
+}
+
+void QBarDataProxyPrivate::insertRows(int rowIndex, const QBarDataArray &rows, const QStringList *labels)
+{
+ Q_ASSERT(rowIndex >= 0 && rowIndex <= m_dataArray->size());
+ if (labels)
+ fixRowLabels(rowIndex, rows.size(), *labels, true);
+ for (int i = 0; i < rows.size(); i++)
+ m_dataArray->insert(rowIndex++, rows.at(i));
+}
+
+void QBarDataProxyPrivate::removeRows(int rowIndex, int removeCount, bool removeLabels)
+{
+ Q_ASSERT(rowIndex >= 0);
+ int maxRemoveCount = m_dataArray->size() - rowIndex;
+ removeCount = qMin(removeCount, maxRemoveCount);
+ bool labelsChanged = false;
+ for (int i = 0; i < removeCount; i++) {
+ clearRow(rowIndex);
+ m_dataArray->removeAt(rowIndex);
+ if (removeLabels && m_rowLabels.size() > rowIndex) {
+ m_rowLabels.removeAt(rowIndex);
+ labelsChanged = true;
+ }
+ }
+ if (labelsChanged)
+ emit qptr()->rowLabelsChanged();
+}
+
+QBarDataProxy *QBarDataProxyPrivate::qptr()
+{
+ return static_cast<QBarDataProxy *>(q_ptr);
+}
+
+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;
+}
+
+/*!
+ * \internal
+ * Fixes the row label array to include specified labels.
+ */
+void QBarDataProxyPrivate::fixRowLabels(int startIndex, int count, const QStringList &newLabels, bool isInsert)
+{
+ bool changed = false;
+ int currentSize = m_rowLabels.size();
+
+ int newSize = newLabels.size();
+ if (startIndex >= currentSize) {
+ // Adding labels past old label array, create empty strings to fill intervening space
+ if (newSize) {
+ for (int i = currentSize; i < startIndex; i++)
+ m_rowLabels << QString();
+ // Doesn't matter if insert, append, or just change when there were no existing
+ // strings, just append new strings.
+ m_rowLabels << newLabels;
+ changed = true;
+ }
+ } else {
+ if (isInsert) {
+ int insertIndex = startIndex;
+ if (count)
+ changed = true;
+ for (int i = 0; i < count; i++) {
+ if (i < newSize)
+ m_rowLabels.insert(insertIndex++, newLabels.at(i));
+ else
+ m_rowLabels.insert(insertIndex++, QString());
+ }
+ } else {
+ // Either append or change, replace labels up to array end and then add new ones
+ int lastChangeIndex = count + startIndex;
+ int newIndex = 0;
+ for (int i = startIndex; i < lastChangeIndex; i++) {
+ if (i >= currentSize) {
+ // Label past the current size, so just append the new label
+ if (newSize < newIndex) {
+ changed = true;
+ m_rowLabels << newLabels.at(newIndex);
+ } else {
+ break; // No point appending empty strings, so just exit
+ }
+ } else if (newSize > newIndex) {
+ // Replace existing label
+ if (m_rowLabels.at(i) != newLabels.at(newIndex)) {
+ changed = true;
+ m_rowLabels[i] = newLabels.at(newIndex);
+ }
+ } else {
+ // No more new labels, so clear existing label
+ if (!m_rowLabels.at(i).isEmpty()) {
+ changed = true;
+ m_rowLabels[i] = QString();
+ }
+ }
+ newIndex++;
+ }
+ }
+ }
+ if (changed)
+ emit qptr()->rowLabelsChanged();
+}
+
+QPair<GLfloat, GLfloat> QBarDataProxyPrivate::limitValues(int startRow, int endRow,
+ int startColumn, int endColumn) const
+{
+ 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_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavis3d/data/qbardataproxy.h b/src/datavisualization/data/qbardataproxy.h
index e28f8ff0..758700df 100644
--- a/src/datavis3d/data/qbardataproxy.h
+++ b/src/datavisualization/data/qbardataproxy.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -19,85 +19,89 @@
#ifndef QBARDATAPROXY_H
#define QBARDATAPROXY_H
-#include <QtDataVis3D/qabstractdataproxy.h>
-#include <QtDataVis3D/qbardataitem.h>
+#include <QtDataVisualization/qabstractdataproxy.h>
+#include <QtDataVisualization/qbardataitem.h>
#include <QVector>
+#include <QStringList>
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
typedef QVector<QBarDataItem> QBarDataRow;
typedef QList<QBarDataRow *> QBarDataArray;
class QBarDataProxyPrivate;
-class QT_DATAVIS3D_EXPORT QBarDataProxy : public QAbstractDataProxy
+class QT_DATAVISUALIZATION_EXPORT QBarDataProxy : public QAbstractDataProxy
{
Q_OBJECT
+ Q_PROPERTY(int rowCount READ rowCount)
+ Q_PROPERTY(QStringList rowLabels READ rowLabels WRITE setRowLabels NOTIFY rowLabelsChanged)
+ Q_PROPERTY(QStringList columnLabels READ columnLabels WRITE setColumnLabels NOTIFY columnLabelsChanged)
public:
- explicit QBarDataProxy();
- explicit QBarDataProxy(QBarDataProxyPrivate *d);
+ explicit QBarDataProxy(QObject *parent = 0);
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.
+ // TODO: Replace first part of class description in docs with this once all TODOs are done:
+ /*
+ * QBarDataProxy 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;
+
+ QStringList rowLabels() const;
+ void setRowLabels(const QStringList &labels);
+ QStringList columnLabels() const;
+ void setColumnLabels(const QStringList &labels);
+
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();
void resetArray(QBarDataArray *newArray);
+ void resetArray(QBarDataArray *newArray, const QStringList &rowLabels,
+ const QStringList &columnLabels);
- // Change existing rows
void setRow(int rowIndex, QBarDataRow *row);
+ void setRow(int rowIndex, QBarDataRow *row, const QString &label);
void setRows(int rowIndex, const QBarDataArray &rows);
+ void setRows(int rowIndex, const QBarDataArray &rows, const QStringList &labels);
// 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
+ int addRow(QBarDataRow *row);
+ int addRow(QBarDataRow *row, const QString &label);
+ int addRows(const QBarDataArray &rows);
+ int addRows(const QBarDataArray &rows, const QStringList &labels);
// 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 insertRow(int rowIndex, QBarDataRow *row, const QString &label);
void insertRows(int rowIndex, const QBarDataArray &rows);
+ void insertRows(int rowIndex, const QBarDataArray &rows, const QStringList &labels);
// 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);
+ void removeRows(int rowIndex, int removeCount, bool removeLabels = true);
// 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);
@@ -107,16 +111,20 @@ signals:
void itemChanged(int rowIndex, int columnIndex); // TODO remove once itemsChanged is added?
// TODO void itemsChanged(int rowIndex, int columnIndex, int rowCount, int columnCount);
+ void rowLabelsChanged();
+ void columnLabelsChanged();
+
protected:
+ explicit QBarDataProxy(QBarDataProxyPrivate *d, QObject *parent = 0);
QBarDataProxyPrivate *dptr();
const QBarDataProxyPrivate *dptrc() const;
private:
Q_DISABLE_COPY(QBarDataProxy)
- friend class Bars3dController;
+ friend class Bars3DController;
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif // QBARDATAPROXY_H
diff --git a/src/datavis3d/data/qbardataproxy_p.h b/src/datavisualization/data/qbardataproxy_p.h
index fa6ccd0d..4d51bd5b 100644
--- a/src/datavis3d/data/qbardataproxy_p.h
+++ b/src/datavisualization/data/qbardataproxy_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -33,7 +33,7 @@
#include "qabstractdataproxy_p.h"
#include "qbardataitem.h"
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
class QBarDataProxyPrivate : public QAbstractDataProxyPrivate
{
@@ -42,28 +42,34 @@ public:
QBarDataProxyPrivate(QBarDataProxy *q);
virtual ~QBarDataProxyPrivate();
- bool resetArray(QBarDataArray *newArray);
- void setRow(int rowIndex, QBarDataRow *row);
- void setRows(int rowIndex, const QBarDataArray &rows);
+ void resetArray(QBarDataArray *newArray, const QStringList *rowLabels,
+ const QStringList *columnLabels);
+ void setRow(int rowIndex, QBarDataRow *row, const QString *label);
+ void setRows(int rowIndex, const QBarDataArray &rows, const QStringList *labels);
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);
+ int addRow(QBarDataRow *row, const QString *label);
+ int addRows(const QBarDataArray &rows, const QStringList *labels);
+ void insertRow(int rowIndex, QBarDataRow *row, const QString *label);
+ void insertRows(int rowIndex, const QBarDataArray &rows, const QStringList *labels);
+ void removeRows(int rowIndex, int removeCount, bool removeLabels);
- QPair<GLfloat, GLfloat> limitValues(int startRow, int startColumn, int rowCount, int columnCount);
+ QPair<GLfloat, GLfloat> limitValues(int startRow, int startColumn, int rowCount,
+ int columnCount) const;
private:
+ QBarDataProxy *qptr();
void clearRow(int rowIndex);
void clearArray();
+ void fixRowLabels(int startIndex, int count, const QStringList &newLabels, bool isInsert);
QBarDataArray *m_dataArray;
+ QStringList m_rowLabels;
+ QStringList m_columnLabels;
private:
friend class QBarDataProxy;
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif // QBARDATAPROXY_P_H
diff --git a/src/datavisualization/data/qheightmapsurfacedataproxy.cpp b/src/datavisualization/data/qheightmapsurfacedataproxy.cpp
new file mode 100644
index 00000000..518e69eb
--- /dev/null
+++ b/src/datavisualization/data/qheightmapsurfacedataproxy.cpp
@@ -0,0 +1,489 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 "qheightmapsurfacedataproxy_p.h"
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+// Default ranges correspond value axis defaults
+const float defaultMinValue = 0.0f;
+const float defaultMaxValue = 10.0f;
+
+/*!
+ * \class QHeightMapSurfaceDataProxy
+ * \inmodule QtDataVisualization
+ * \brief Base proxy class for Q3DSurface.
+ * \since 1.0.0
+ *
+ * QHeightMapSurfaceDataProxy takes care of surface related height map data handling. It provides a
+ * way for giving the surface plot a height map to be visualized.
+ *
+ * Since height maps do not contain values for X or Z axes, those values need to be given
+ * separately using minXValue, maxXValue, minZValue, and maxZValue properties. X-value corresponds
+ * to image horizontal direction and Z-value to the vertical. Setting any of these
+ * properties triggers asynchronous re-resolving of any existing height map.
+ *
+ * \sa QSurfaceDataProxy, {Qt Data Visualization Data Handling}
+ */
+
+/*!
+ * \qmltype HeightMapSurfaceDataProxy
+ * \inqmlmodule com.digia.QtDataVisualization 1.0
+ * \since com.digia.QtDataVisualization 1.0
+ * \ingroup datavisualization_qml
+ * \instantiates QHeightMapSurfaceDataProxy
+ * \inherits SurfaceDataProxy
+ * \brief Base proxy type for Surface3D.
+ *
+ * HeightMapSurfaceDataProxy takes care of surface related height map data handling. It provides a
+ * way for giving the surface plot a height map to be visualized.
+ *
+ * For more complete description, see QHeightMapSurfaceDataProxy.
+ *
+ * \sa {Qt Data Visualization Data Handling}
+ */
+
+/*!
+ * \qmlproperty image HeightMapSurfaceDataProxy::heightMap
+ *
+ * A height map to be visualized. Setting this property replaces current data with height map data.
+ *
+ * There are several formats the image can be given in, but if it is not in a directly usable
+ * format, a conversion is made. \note If the result seems wrong, the automatic conversion failed
+ * and you should try converting the image yourself before setting it. Preferred format is
+ * QImage::Format_RGB32 in grayscale.
+ *
+ * The height of the image is read from the red component of the pixels if the image is in grayscale,
+ * otherwise it is an average calculated from red, green and blue components of the pixels. Using
+ * grayscale images may improve data conversion speed for large images.
+ *
+ * Since height maps do not contain values for X or Z axes, those values need to be given
+ * separately using minXValue, maxXValue, minZValue, and maxZValue properties. X-value corresponds
+ * to image horizontal direction and Z-value to the vertical. Setting any of these
+ * properties triggers asynchronous re-resolving of any existing height map.
+ *
+ * Not recommended formats: all mono formats (for example QImage::Format_Mono).
+ */
+
+/*!
+ * \qmlproperty string HeightMapSurfaceDataProxy::heightMapFile
+ *
+ * A file with a height map image to be visualized. Setting this property replaces current data
+ * with height map data.
+ *
+ * \sa heightMap
+ */
+
+/*!
+ * \qmlproperty qreal HeightMapSurfaceDataProxy::minXValue
+ *
+ * The minimum X value for the generated surface points.
+ * When setting this property the corresponding maximum value is adjusted if necessary,
+ * to ensure that the range remains valid.
+ */
+
+/*!
+ * \qmlproperty qreal HeightMapSurfaceDataProxy::maxXValue
+ *
+ * The maximum X value for the generated surface points.
+ * When setting this property the corresponding minimum value is adjusted if necessary,
+ * to ensure that the range remains valid.
+ */
+
+/*!
+ * \qmlproperty qreal HeightMapSurfaceDataProxy::minZValue
+ *
+ * The minimum Z value for the generated surface points.
+ * When setting this property the corresponding maximum value is adjusted if necessary,
+ * to ensure that the range remains valid.
+ */
+
+/*!
+ * \qmlproperty qreal HeightMapSurfaceDataProxy::maxZValue
+ *
+ * The maximum Z value for the generated surface points.
+ * When setting this property the corresponding minimum value is adjusted if necessary,
+ * to ensure that the range remains valid.
+ */
+
+/*!
+ * Constructs QHeightMapSurfaceDataProxy with the given \a parent.
+ */
+QHeightMapSurfaceDataProxy::QHeightMapSurfaceDataProxy(QObject *parent) :
+ QSurfaceDataProxy(new QHeightMapSurfaceDataProxyPrivate(this), parent)
+{
+}
+
+/*!
+ * Constructs QHeightMapSurfaceDataProxy with the given \a image and \a parent. Height map is set
+ * by calling setHeighMap() with \a image.
+ *
+ * \sa heightMap
+ */
+QHeightMapSurfaceDataProxy::QHeightMapSurfaceDataProxy(const QImage &image, QObject *parent) :
+ QSurfaceDataProxy(new QHeightMapSurfaceDataProxyPrivate(this), parent)
+{
+ setHeightMap(image);
+}
+
+/*!
+ * \internal
+ */
+QHeightMapSurfaceDataProxy::QHeightMapSurfaceDataProxy(
+ QHeightMapSurfaceDataProxyPrivate *d, QObject *parent) :
+ QSurfaceDataProxy(d, parent)
+{
+}
+
+/*!
+ * Destroys QHeightMapSurfaceDataProxy.
+ */
+QHeightMapSurfaceDataProxy::~QHeightMapSurfaceDataProxy()
+{
+}
+
+/*!
+ * \property QHeightMapSurfaceDataProxy::heightMap
+ *
+ * A height map to be visualized. Setting this property replaces current data with height map data.
+ *
+ * There are several formats the image can be given in, but if it is not in a directly usable
+ * format, a conversion is made. \note If the result seems wrong, the automatic conversion failed
+ * and you should try converting the image yourself before setting it. Preferred format is
+ * QImage::Format_RGB32 in grayscale.
+ *
+ * The height of the image is read from the red component of the pixels if the image is in grayscale,
+ * otherwise it is an average calculated from red, green and blue components of the pixels. Using
+ * grayscale images may improve data conversion speed for large images.
+ *
+ * Not recommended formats: all mono formats (for example QImage::Format_Mono).
+ *
+ * The height map is resolved asynchronously. QSurfaceDataProxy::arrayReset() is emitted when the
+ * data has been resolved.
+ */
+void QHeightMapSurfaceDataProxy::setHeightMap(const QImage &image)
+{
+ dptr()->m_heightMap = image;
+
+ // We do resolving asynchronously to make qml onArrayReset handlers actually get the initial reset
+ if (!dptr()->m_resolveTimer.isActive())
+ dptr()->m_resolveTimer.start(0);
+}
+
+QImage QHeightMapSurfaceDataProxy::heightMap() const
+{
+ return dptrc()->m_heightMap;
+}
+
+/*!
+ * \property QHeightMapSurfaceDataProxy::heightMapFile
+ *
+ * A file with a height map image to be visualized. Setting this property replaces current data
+ * with height map data.
+ *
+ * \sa heightMap
+ */
+void QHeightMapSurfaceDataProxy::setHeightMapFile(const QString &filename)
+{
+ dptr()->m_heightMapFile = filename;
+ setHeightMap(QImage(filename));
+}
+
+QString QHeightMapSurfaceDataProxy::heightMapFile() const
+{
+ return dptrc()->m_heightMapFile;
+}
+
+/*!
+ * A convenience function for setting all minimum (\a minX and \a minZ) and maximum
+ * (\a maxX and \a maxZ) values at the same time. The minimum values must be smaller than the
+ * corresponding maximum value. Otherwise the values get adjusted so that they are valid.
+ */
+void QHeightMapSurfaceDataProxy::setValueRanges(float minX, float maxX, float minZ, float maxZ)
+{
+ dptr()->setValueRanges(minX, maxX, minZ, maxZ);
+}
+
+/*!
+ * \property QHeightMapSurfaceDataProxy::minXValue
+ *
+ * The minimum X value for the generated surface points.
+ * When setting this property the corresponding maximum value is adjusted if necessary,
+ * to ensure that the range remains valid.
+ */
+void QHeightMapSurfaceDataProxy::setMinXValue(float min)
+{
+ dptr()->setMinXValue(min);
+}
+
+float QHeightMapSurfaceDataProxy::minXValue() const
+{
+ return dptrc()->m_minXValue;
+}
+
+/*!
+ * \property QHeightMapSurfaceDataProxy::maxXValue
+ *
+ * The maximum X value for the generated surface points.
+ * When setting this property the corresponding minimum value is adjusted if necessary,
+ * to ensure that the range remains valid.
+ */
+void QHeightMapSurfaceDataProxy::setMaxXValue(float max)
+{
+ dptr()->setMaxXValue(max);
+}
+
+float QHeightMapSurfaceDataProxy::maxXValue() const
+{
+ return dptrc()->m_maxXValue;
+}
+
+/*!
+ * \property QHeightMapSurfaceDataProxy::minZValue
+ *
+ * The minimum Z value for the generated surface points.
+ * When setting this property the corresponding maximum value is adjusted if necessary,
+ * to ensure that the range remains valid.
+ */
+void QHeightMapSurfaceDataProxy::setMinZValue(float min)
+{
+ dptr()->setMinZValue(min);
+}
+
+float QHeightMapSurfaceDataProxy::minZValue() const
+{
+ return dptrc()->m_minZValue;
+}
+
+/*!
+ * \property QHeightMapSurfaceDataProxy::maxZValue
+ *
+ * The maximum Z value for the generated surface points.
+ * When setting this property the corresponding minimum value is adjusted if necessary,
+ * to ensure that the range remains valid.
+ */
+void QHeightMapSurfaceDataProxy::setMaxZValue(float max)
+{
+ dptr()->setMaxZValue(max);
+}
+
+float QHeightMapSurfaceDataProxy::maxZValue() const
+{
+ return dptrc()->m_maxZValue;
+}
+
+/*!
+ * \internal
+ */
+QHeightMapSurfaceDataProxyPrivate *QHeightMapSurfaceDataProxy::dptr()
+{
+ return static_cast<QHeightMapSurfaceDataProxyPrivate *>(d_ptr.data());
+}
+
+/*!
+ * \internal
+ */
+const QHeightMapSurfaceDataProxyPrivate *QHeightMapSurfaceDataProxy::dptrc() const
+{
+ return static_cast<const QHeightMapSurfaceDataProxyPrivate *>(d_ptr.data());
+}
+
+//
+// QHeightMapSurfaceDataProxyPrivate
+//
+
+QHeightMapSurfaceDataProxyPrivate::QHeightMapSurfaceDataProxyPrivate(QHeightMapSurfaceDataProxy *q)
+ : QSurfaceDataProxyPrivate(q),
+ m_minXValue(defaultMinValue),
+ m_maxXValue(defaultMaxValue),
+ m_minZValue(defaultMinValue),
+ m_maxZValue(defaultMaxValue)
+{
+ m_resolveTimer.setSingleShot(true);
+ QObject::connect(&m_resolveTimer, &QTimer::timeout,
+ this, &QHeightMapSurfaceDataProxyPrivate::handlePendingResolve);
+}
+
+QHeightMapSurfaceDataProxyPrivate::~QHeightMapSurfaceDataProxyPrivate()
+{
+}
+
+QHeightMapSurfaceDataProxy *QHeightMapSurfaceDataProxyPrivate::qptr()
+{
+ return static_cast<QHeightMapSurfaceDataProxy *>(q_ptr);
+}
+
+void QHeightMapSurfaceDataProxyPrivate::setValueRanges(float minX, float maxX, float minZ, float maxZ)
+{
+ bool changed = false;
+ if (m_minXValue != minX || m_minZValue != minZ) {
+ m_minXValue = minX;
+ m_minZValue = minZ;
+ changed = true;
+ }
+ if (m_maxXValue != maxX || minX >= maxX) {
+ if (minX >= maxX) {
+ m_maxXValue = minX + 1.0;
+ qWarning() << "Warning: Tried to set invalid range for X value range."
+ " Range automatically adjusted to a valid one:"
+ << minX << "-" << maxX << "-->" << m_minXValue << "-" << m_maxXValue;
+ } else {
+ m_maxXValue = maxX;
+ }
+ changed = true;
+ }
+ if (m_maxZValue != maxZ || minZ >= maxZ) {
+ if (minZ >= maxZ) {
+ m_maxZValue = minZ + 1.0;
+ qWarning() << "Warning: Tried to set invalid range for Z value range."
+ " Range automatically adjusted to a valid one:"
+ << minZ << "-" << maxZ << "-->" << m_minZValue << "-" << m_maxZValue;
+ } else {
+ m_maxZValue = maxZ;
+ }
+ changed = true;
+ }
+
+ if (changed && !m_resolveTimer.isActive())
+ m_resolveTimer.start(0);
+}
+
+void QHeightMapSurfaceDataProxyPrivate::setMinXValue(float min)
+{
+ if (min != m_minXValue) {
+ if (min >= m_maxXValue) {
+ qreal oldMax = m_maxXValue;
+ m_maxXValue = min + 1.0;
+ qWarning() << "Warning: Tried to set minimum X to equal or larger than maximum X for"
+ " value range. Maximum automatically adjusted to a valid one:"
+ << oldMax << "-->" << m_maxXValue;
+ }
+ m_minXValue = min;
+
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0);
+ }
+}
+
+void QHeightMapSurfaceDataProxyPrivate::setMaxXValue(float max)
+{
+ if (m_maxXValue != max) {
+ if (max <= m_minXValue) {
+ qreal oldMin = m_minXValue;
+ m_minXValue = max - 1.0;
+ qWarning() << "Warning: Tried to set maximum X to equal or smaller than minimum X for"
+ " value range. Minimum automatically adjusted to a valid one:"
+ << oldMin << "-->" << m_minXValue;
+ }
+ m_maxXValue = max;
+
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0);
+ }
+}
+
+void QHeightMapSurfaceDataProxyPrivate::setMinZValue(float min)
+{
+ if (min != m_minZValue) {
+ if (min >= m_maxZValue) {
+ qreal oldMax = m_maxZValue;
+ m_maxZValue = min + 1.0;
+ qWarning() << "Warning: Tried to set minimum Z to equal or larger than maximum Z for"
+ " value range. Maximum automatically adjusted to a valid one:"
+ << oldMax << "-->" << m_maxZValue;
+ }
+ m_minZValue = min;
+
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0);
+ }
+}
+
+void QHeightMapSurfaceDataProxyPrivate::setMaxZValue(float max)
+{
+ if (m_maxZValue != max) {
+ if (max <= m_minZValue) {
+ qreal oldMin = m_minZValue;
+ m_minZValue = max - 1.0;
+ qWarning() << "Warning: Tried to set maximum Z to equal or smaller than minimum Z for"
+ " value range. Minimum automatically adjusted to a valid one:"
+ << oldMin << "-->" << m_minZValue;
+ }
+ m_maxZValue = max;
+
+ if (!m_resolveTimer.isActive())
+ m_resolveTimer.start(0);
+ }
+}
+
+void QHeightMapSurfaceDataProxyPrivate::handlePendingResolve()
+{
+ QImage heightImage = m_heightMap;
+ // Convert to RGB32 to be sure we're reading the right bytes
+ if (heightImage.format() != QImage::Format_RGB32)
+ heightImage = heightImage.convertToFormat(QImage::Format_RGB32);
+
+ uchar *bits = heightImage.bits();
+
+ int imageHeight = heightImage.height();
+ int imageWidth = heightImage.width();
+ int bitCount = imageWidth * 4 * (imageHeight - 1);
+ int widthBits = imageWidth * 4;
+ float height = 0;
+
+ // Do not recreate array if dimensions have not changed
+ QSurfaceDataArray *dataArray = m_dataArray;
+ if (imageWidth != qptr()->columnCount() || imageHeight != dataArray->size()) {
+ dataArray = new QSurfaceDataArray;
+ dataArray->reserve(imageHeight);
+ for (int i = 0; i < imageHeight; i++) {
+ QSurfaceDataRow *newProxyRow = new QSurfaceDataRow(imageWidth);
+ dataArray->append(newProxyRow);
+ }
+ }
+
+ float xMul = (m_maxXValue - m_minXValue) / float(imageWidth - 1);
+ float zMul = (m_maxZValue - m_minZValue) / float(imageHeight - 1);
+
+ if (heightImage.isGrayscale()) {
+ // Grayscale, it's enough to read Red byte
+ for (int i = 0; i < imageHeight; i++, bitCount -= widthBits) {
+ QSurfaceDataRow &newRow = *dataArray->at(i);
+ for (int j = 0; j < imageWidth; j++)
+ newRow[j].setPosition(QVector3D((float(j) * xMul) + m_minXValue, float(bits[bitCount + (j * 4)]),
+ (float(i) * zMul) + m_minZValue));
+ }
+ } else {
+ // Not grayscale, we'll need to calculate height from RGB
+ for (int i = 0; i < imageHeight; i++, bitCount -= widthBits) {
+ QSurfaceDataRow &newRow = *dataArray->at(i);
+ for (int j = 0; j < imageWidth; j++) {
+ int nextpixel = j * 4;
+ height = (float(bits[bitCount + nextpixel])
+ + float(bits[1 + bitCount + nextpixel])
+ + float(bits[2 + bitCount + nextpixel]));
+ newRow[j].setPosition(QVector3D((float(j) * xMul) + m_minXValue, height / 3.0f,
+ (float(i) * zMul) + m_minZValue));
+ }
+ }
+ }
+
+ qptr()->resetArray(dataArray);
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualization/data/qheightmapsurfacedataproxy.h b/src/datavisualization/data/qheightmapsurfacedataproxy.h
new file mode 100644
index 00000000..3306059f
--- /dev/null
+++ b/src/datavisualization/data/qheightmapsurfacedataproxy.h
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 QHEIGHTMAPSURFACEDATAPROXY_H
+#define QHEIGHTMAPSURFACEDATAPROXY_H
+
+#include <QtDataVisualization/qsurfacedataproxy.h>
+
+#include <QImage>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class QHeightMapSurfaceDataProxyPrivate;
+
+class QT_DATAVISUALIZATION_EXPORT QHeightMapSurfaceDataProxy : public QSurfaceDataProxy
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QImage heightMap READ heightMap WRITE setHeightMap)
+ Q_PROPERTY(QString heightMapFile READ heightMapFile WRITE setHeightMapFile)
+ Q_PROPERTY(float minXValue READ minXValue WRITE setMinXValue)
+ Q_PROPERTY(float maxXValue READ maxXValue WRITE setMaxXValue)
+ Q_PROPERTY(float minZValue READ minZValue WRITE setMinZValue)
+ Q_PROPERTY(float maxZValue READ maxZValue WRITE setMaxZValue)
+
+public:
+ explicit QHeightMapSurfaceDataProxy(QObject *parent = 0);
+ explicit QHeightMapSurfaceDataProxy(const QImage &image, QObject *parent = 0);
+ virtual ~QHeightMapSurfaceDataProxy();
+
+ void setHeightMap(const QImage &image);
+ QImage heightMap() const;
+
+ void setHeightMapFile(const QString &filename);
+ QString heightMapFile() const;
+
+ void setValueRanges(float minX, float maxX, float minZ, float maxZ);
+ void setMinXValue(float min);
+ float minXValue() const;
+ void setMaxXValue(float max);
+ float maxXValue() const;
+ void setMinZValue(float min);
+ float minZValue() const;
+ void setMaxZValue(float max);
+ float maxZValue() const;
+
+protected:
+ explicit QHeightMapSurfaceDataProxy(QHeightMapSurfaceDataProxyPrivate *d, QObject *parent = 0);
+ QHeightMapSurfaceDataProxyPrivate *dptr();
+ const QHeightMapSurfaceDataProxyPrivate *dptrc() const;
+
+private:
+ Q_DISABLE_COPY(QHeightMapSurfaceDataProxy)
+
+ friend class Surface3DController;
+};
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
+#endif
diff --git a/src/datavisualization/data/qheightmapsurfacedataproxy_p.h b/src/datavisualization/data/qheightmapsurfacedataproxy_p.h
new file mode 100644
index 00000000..2d773344
--- /dev/null
+++ b/src/datavisualization/data/qheightmapsurfacedataproxy_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 QtDataVisualization 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 QtDataVisualization 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 QHEIGHTMAPSURFACEDATAPROXY_P_H
+#define QHEIGHTMAPSURFACEDATAPROXY_P_H
+
+#include "qheightmapsurfacedataproxy.h"
+#include "qsurfacedataproxy_p.h"
+#include <QTimer>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class QHeightMapSurfaceDataProxyPrivate : public QSurfaceDataProxyPrivate
+{
+ Q_OBJECT
+
+public:
+ QHeightMapSurfaceDataProxyPrivate(QHeightMapSurfaceDataProxy *q);
+ virtual ~QHeightMapSurfaceDataProxyPrivate();
+
+ void setValueRanges(float minX, float maxX, float minZ, float maxZ);
+ void setMinXValue(float min);
+ void setMaxXValue(float max);
+ void setMinZValue(float min);
+ void setMaxZValue(float max);
+private:
+ QHeightMapSurfaceDataProxy *qptr();
+ void handlePendingResolve();
+
+ QImage m_heightMap;
+ QString m_heightMapFile;
+ QTimer m_resolveTimer;
+
+ float m_minXValue;
+ float m_maxXValue;
+ float m_minZValue;
+ float m_maxZValue;
+
+ friend class QHeightMapSurfaceDataProxy;
+};
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
+#endif
diff --git a/src/datavisualization/data/qitemmodelbardatamapping.cpp b/src/datavisualization/data/qitemmodelbardatamapping.cpp
new file mode 100644
index 00000000..fc6f8f54
--- /dev/null
+++ b/src/datavisualization/data/qitemmodelbardatamapping.cpp
@@ -0,0 +1,407 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+/*!
+ * \class QItemModelBarDataMapping
+ * \inmodule QtDataVisualization
+ * \brief Item model mapping for Q3DBars.
+ * \since 1.0.0
+ *
+ * QItemModelBarDataMapping is used to map roles of QAbstractItemModel to rows, columns, and values
+ * of Q3DBars. There are three ways to use QItemModelBarDataMapping:
+ *
+ * 1) If useModelCategories property is set to true, QItemModelBarDataMapping will map rows and
+ * columns of QAbstractItemModel to rows and columns of Q3DBars, and uses the value returned for
+ * Qt::DisplayRole as bar value by default.
+ * The value role to be used can be redefined if Qt::DisplayRole is not suitable.
+ *
+ * 2) For models that do not have data already neatly sorted into rows and columns, such as
+ * QAbstractListModel based models, you can define a role from the model to map for each of row,
+ * column and value.
+ *
+ * 3) If you do not want to include all data contained in the model, or the autogenerated rows and
+ * columns are not ordered as you wish, you can specify which rows and columns should be included
+ * and in which order by defining an explicit list of categories for either or both of rows and
+ * columns.
+ *
+ * For example, assume that you have a custom QAbstractItemModel for storing various monthly values
+ * related to a business.
+ * Each item in the model has roles "year", "month", "income", and "expenses".
+ * You could do the following to display the data in a bar graph:
+ *
+ * \snippet doc_src_qtdatavisualization.cpp 3
+ *
+ * \sa QItemModelBarDataProxy, {Qt Data Visualization Data Handling}
+ */
+
+/*!
+ * \qmltype BarDataMapping
+ * \inqmlmodule com.digia.QtDataVisualization 1.0
+ * \since com.digia.QtDataVisualization 1.0
+ * \ingroup datavisualization_qml
+ * \instantiates QItemModelBarDataMapping
+ * \brief Item model mapping for Bars3D.
+ *
+ * This type is used to map roles of AbstractItemModel to rows, columns, and values of Bars3D. For
+ * more complete description, see QItemModelBarDataMapping.
+ *
+ * Usage example:
+ *
+ * \snippet doc_src_qmldatavisualization.cpp 4
+ *
+ * \sa ItemModelBarDataProxy, {Qt Data Visualization Data Handling}
+ */
+
+/*!
+ * \qmlproperty string BarDataMapping::rowRole
+ * The row role of the mapping.
+ */
+
+/*!
+ * \qmlproperty string BarDataMapping::columnRole
+ * The column role of the mapping.
+ */
+
+/*!
+ * \qmlproperty string BarDataMapping::valueRole
+ * The value role of the mapping.
+ */
+
+/*!
+ * \qmlproperty list BarDataMapping::rowCategories
+ * The row categories of the mapping. Only items with row roles that are found in this list are
+ * included when data is resolved. The rows are ordered in the same order as they are in this list.
+ */
+
+/*!
+ * \qmlproperty list BarDataMapping::columnCategories
+ * The column categories of the mapping. Only items with column roles that are found in this list are
+ * included when data is resolved. The columns are ordered in the same order as they are in this list.
+ */
+
+/*!
+ * \qmlproperty list BarDataMapping::useModelCategories
+ * When set to true, the mapping ignores row and column roles and categories, and uses
+ * the rows and columns from the model instead. Defaults to false.
+ */
+
+/*!
+ * \qmlproperty list BarDataMapping::autoRowCategories
+ * When set to true, the mapping ignores any explicitly set row categories
+ * and overwrites them with automatically generated ones whenever the
+ * data from model is resolved. Defaults to true.
+ */
+
+/*!
+ * \qmlproperty list BarDataMapping::autoColumnCategories
+ * When set to true, the mapping ignores any explicitly set column categories
+ * and overwrites them with automatically generated ones whenever the
+ * data from model is resolved. Defaults to true.
+ */
+
+/*!
+ * Constructs QItemModelBarDataMapping with the given \a parent.
+ */
+QItemModelBarDataMapping::QItemModelBarDataMapping(QObject *parent)
+ : QAbstractDataMapping(new QItemModelBarDataMappingPrivate(this), parent)
+{
+}
+
+/*!
+ * Constructs QItemModelBarDataMapping with \a valueRole and the given \a parent.
+ * This constructor is meant to be used with models that have data properly sorted
+ * in rows and columns already, so it also sets useModelCategories property to true.
+ */
+QItemModelBarDataMapping::QItemModelBarDataMapping(const QString &valueRole, QObject *parent)
+ : QAbstractDataMapping(new QItemModelBarDataMappingPrivate(this), parent)
+{
+ dptr()->m_valueRole = valueRole;
+ dptr()->m_useModelCategories = true;
+}
+
+/*!
+ * Constructs QItemModelBarDataMapping with \a rowRole, \a columnRole, \a valueRole
+ * and the given \a parent.
+ */
+QItemModelBarDataMapping::QItemModelBarDataMapping(const QString &rowRole,
+ const QString &columnRole,
+ const QString &valueRole,
+ QObject *parent)
+ : QAbstractDataMapping(new QItemModelBarDataMappingPrivate(this), parent)
+{
+ dptr()->m_rowRole = rowRole;
+ dptr()->m_columnRole = columnRole;
+ dptr()->m_valueRole = valueRole;
+}
+
+/*!
+ * Constructs QItemModelBarDataMapping with \a rowRole, \a columnRole, \a valueRole,
+ * \a rowCategories, \a columnCategories and the given \a parent. This constructor
+ * also sets autoRowCategories and autoColumnCategories to false.
+ */
+QItemModelBarDataMapping::QItemModelBarDataMapping(const QString &rowRole,
+ const QString &columnRole,
+ const QString &valueRole,
+ const QStringList &rowCategories,
+ const QStringList &columnCategories,
+ QObject *parent)
+ : QAbstractDataMapping(new QItemModelBarDataMappingPrivate(this), parent)
+{
+ dptr()->m_rowRole = rowRole;
+ dptr()->m_columnRole = columnRole;
+ dptr()->m_valueRole = valueRole;
+ dptr()->m_rowCategories = rowCategories;
+ dptr()->m_columnCategories = columnCategories;
+ dptr()->m_autoRowCategories = false;
+ dptr()->m_autoColumnCategories = false;
+}
+
+/*!
+ * Destroys QItemModelBarDataMapping.
+ */
+QItemModelBarDataMapping::~QItemModelBarDataMapping()
+{
+}
+
+/*!
+ * \property QItemModelBarDataMapping::rowRole
+ *
+ * Defines the row role for the mapping.
+ */
+void QItemModelBarDataMapping::setRowRole(const QString &role)
+{
+ if (dptr()->m_rowRole != role) {
+ dptr()->m_rowRole = role;
+ emit mappingChanged();
+ }
+}
+
+QString QItemModelBarDataMapping::rowRole() const
+{
+ return dptrc()->m_rowRole;
+}
+
+/*!
+ * \property QItemModelBarDataMapping::columnRole
+ *
+ * Defines the column role for the mapping.
+ */
+void QItemModelBarDataMapping::setColumnRole(const QString &role)
+{
+ if (dptr()->m_columnRole != role) {
+ dptr()->m_columnRole = role;
+ emit mappingChanged();
+ }
+}
+
+QString QItemModelBarDataMapping::columnRole() const
+{
+ return dptrc()->m_columnRole;
+}
+
+/*!
+ * \property QItemModelBarDataMapping::valueRole
+ *
+ * Defines the value role for the mapping.
+ */
+void QItemModelBarDataMapping::setValueRole(const QString &role)
+{
+ if (dptr()->m_valueRole != role) {
+ dptr()->m_valueRole = role;
+ emit mappingChanged();
+ }
+}
+
+QString QItemModelBarDataMapping::valueRole() const
+{
+ return dptrc()->m_valueRole;
+}
+
+/*!
+ * \property QItemModelBarDataMapping::rowCategories
+ *
+ * Defines the row categories for the mapping.
+ */
+void QItemModelBarDataMapping::setRowCategories(const QStringList &categories)
+{
+ if (dptr()->m_rowCategories != categories) {
+ dptr()->m_rowCategories = categories;
+ emit mappingChanged();
+ }
+}
+
+QStringList QItemModelBarDataMapping::rowCategories() const
+{
+ return dptrc()->m_rowCategories;
+}
+
+/*!
+ * \property QItemModelBarDataMapping::columnCategories
+ *
+ * Defines the column categories for the mapping.
+ */
+void QItemModelBarDataMapping::setColumnCategories(const QStringList &categories)
+{
+ if (dptr()->m_columnCategories != categories) {
+ dptr()->m_columnCategories = categories;
+ emit mappingChanged();
+ }
+}
+
+QStringList QItemModelBarDataMapping::columnCategories() const
+{
+ return dptrc()->m_columnCategories;
+}
+
+/*!
+ * \property QItemModelBarDataMapping::useModelCategories
+ *
+ * When set to true, the mapping ignores row and column roles and categories, and uses
+ * the rows and columns from the model instead. Defaults to false.
+ */
+void QItemModelBarDataMapping::setUseModelCategories(bool enable)
+{
+ if (dptr()->m_useModelCategories != enable) {
+ dptr()->m_useModelCategories = enable;
+ emit mappingChanged();
+ }
+}
+
+bool QItemModelBarDataMapping::useModelCategories() const
+{
+ return dptrc()->m_useModelCategories;
+}
+
+/*!
+ * \property QItemModelBarDataMapping::autoRowCategories
+ *
+ * When set to true, the mapping ignores any explicitly set row categories
+ * and overwrites them with automatically generated ones whenever the
+ * data from model is resolved. Defaults to true.
+ */
+void QItemModelBarDataMapping::setAutoRowCategories(bool enable)
+{
+ if (dptr()->m_autoRowCategories != enable) {
+ dptr()->m_autoRowCategories = enable;
+ emit mappingChanged();
+ }
+}
+
+bool QItemModelBarDataMapping::autoRowCategories() const
+{
+ return dptrc()->m_autoRowCategories;
+}
+
+/*!
+ * \property QItemModelBarDataMapping::autoColumnCategories
+ *
+ * When set to true, the mapping ignores any explicitly set column categories
+ * and overwrites them with automatically generated ones whenever the
+ * data from model is resolved. Defaults to true.
+ */
+void QItemModelBarDataMapping::setAutoColumnCategories(bool enable)
+{
+ if (dptr()->m_autoColumnCategories != enable) {
+ dptr()->m_autoColumnCategories = enable;
+ emit mappingChanged();
+ }
+}
+
+bool QItemModelBarDataMapping::autoColumnCategories() const
+{
+ return dptrc()->m_autoColumnCategories;
+}
+
+/*!
+ * Changes \a rowRole, \a columnRole, \a valueRole, \a rowCategories and \a columnCategories to the
+ * mapping.
+ */
+void QItemModelBarDataMapping::remap(const QString &rowRole,
+ const QString &columnRole,
+ const QString &valueRole,
+ const QStringList &rowCategories,
+ const QStringList &columnCategories)
+{
+ dptr()->m_rowRole = rowRole;
+ dptr()->m_columnRole = columnRole;
+ dptr()->m_valueRole = valueRole;
+ dptr()->m_rowCategories = rowCategories;
+ dptr()->m_columnCategories = columnCategories;
+
+ emit mappingChanged();
+}
+
+/*!
+ * /return index of the specified \a category in row categories list.
+ * If the row categories list is empty, -1 is returned.
+ * \note If the automatic row categories generation is in use, this method will
+ * not return valid index before the data in the model is resolved for the first time.
+ */
+int QItemModelBarDataMapping::rowCategoryIndex(const QString &category)
+{
+ return dptr()->m_rowCategories.indexOf(category);
+}
+
+/*!
+ * /return index of the specified \a category in column categories list.
+ * If the category is not found, -1 is returned.
+ * \note If the automatic column categories generation is in use, this method will
+ * not return valid index before the data in the model is resolved for the first time.
+ */
+int QItemModelBarDataMapping::columnCategoryIndex(const QString &category)
+{
+ return dptr()->m_columnCategories.indexOf(category);
+}
+
+/*!
+ * \internal
+ */
+QItemModelBarDataMappingPrivate *QItemModelBarDataMapping::dptr()
+{
+ return static_cast<QItemModelBarDataMappingPrivate *>(d_ptr.data());
+}
+
+/*!
+ * \internal
+ */
+const QItemModelBarDataMappingPrivate *QItemModelBarDataMapping::dptrc() const
+{
+ return static_cast<const QItemModelBarDataMappingPrivate *>(d_ptr.data());
+}
+
+// QItemModelBarDataMappingPrivate
+
+QItemModelBarDataMappingPrivate::QItemModelBarDataMappingPrivate(QItemModelBarDataMapping *q)
+ : QAbstractDataMappingPrivate(q, QAbstractDataProxy::DataTypeBar),
+ m_useModelCategories(false),
+ m_autoRowCategories(true),
+ m_autoColumnCategories(true)
+{
+}
+
+QItemModelBarDataMappingPrivate::~QItemModelBarDataMappingPrivate()
+{
+}
+
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
diff --git a/src/datavis3d/data/qitemmodelbardatamapping.h b/src/datavisualization/data/qitemmodelbardatamapping.h
index d9f74152..a5ef33b8 100644
--- a/src/datavis3d/data/qitemmodelbardatamapping.h
+++ b/src/datavisualization/data/qitemmodelbardatamapping.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -19,14 +19,15 @@
#ifndef QITEMMODELBARDATAMAPPING_H
#define QITEMMODELBARDATAMAPPING_H
-#include <QtDataVis3D/qdatavis3denums.h>
+#include <QtDataVisualization/qdatavisualizationenums.h>
+#include <QtDataVisualization/qabstractdatamapping.h>
#include <QStringList>
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
class QItemModelBarDataMappingPrivate;
-class QT_DATAVIS3D_EXPORT QItemModelBarDataMapping : public QObject
+class QT_DATAVISUALIZATION_EXPORT QItemModelBarDataMapping : public QAbstractDataMapping
{
Q_OBJECT
Q_PROPERTY(QString rowRole READ rowRole WRITE setRowRole)
@@ -34,21 +35,20 @@ class QT_DATAVIS3D_EXPORT QItemModelBarDataMapping : public QObject
Q_PROPERTY(QString valueRole READ valueRole WRITE setValueRole)
Q_PROPERTY(QStringList rowCategories READ rowCategories WRITE setRowCategories)
Q_PROPERTY(QStringList columnCategories READ columnCategories WRITE setColumnCategories)
+ Q_PROPERTY(bool useModelCategories READ useModelCategories WRITE setUseModelCategories)
+ Q_PROPERTY(bool autoRowCategories READ autoRowCategories WRITE setAutoRowCategories)
+ Q_PROPERTY(bool autoColumnCategories READ autoColumnCategories WRITE setAutoColumnCategories)
+
public:
- explicit QItemModelBarDataMapping();
- QItemModelBarDataMapping(const QItemModelBarDataMapping &other);
- QItemModelBarDataMapping(const QString &valueRole);
+ explicit QItemModelBarDataMapping(QObject *parent = 0);
+ QItemModelBarDataMapping(const QString &valueRole, QObject *parent = 0);
+ QItemModelBarDataMapping(const QString &rowRole, const QString &columnRole,
+ const QString &valueRole, QObject *parent = 0);
QItemModelBarDataMapping(const QString &rowRole, const QString &columnRole,
const QString &valueRole, const QStringList &rowCategories,
- const QStringList &columnCategories);
+ const QStringList &columnCategories, QObject *parent = 0);
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);
@@ -57,21 +57,34 @@ public:
QString valueRole() const;
void setRowCategories(const QStringList &categories);
- const QStringList &rowCategories() const;
+ QStringList rowCategories() const;
void setColumnCategories(const QStringList &categories);
- const QStringList &columnCategories() const;
+ QStringList columnCategories() const;
+
+ void setUseModelCategories(bool enable);
+ bool useModelCategories() const;
+ void setAutoRowCategories(bool enable);
+ bool autoRowCategories() const;
+ void setAutoColumnCategories(bool enable);
+ bool autoColumnCategories() const;
void remap(const QString &rowRole, const QString &columnRole,
const QString &valueRole, const QStringList &rowCategories,
const QStringList &columnCategories);
-signals:
- void mappingChanged();
+
+ Q_INVOKABLE int rowCategoryIndex(const QString& category);
+ Q_INVOKABLE int columnCategoryIndex(const QString& category);
+
+protected:
+ QItemModelBarDataMappingPrivate *dptr();
+ const QItemModelBarDataMappingPrivate *dptrc() const;
private:
- QScopedPointer<QItemModelBarDataMappingPrivate> d_ptr;
-};
+ Q_DISABLE_COPY(QItemModelBarDataMapping)
+ friend class BarItemModelHandler;
+};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif
diff --git a/src/datavis3d/data/qitemmodelbardatamapping_p.h b/src/datavisualization/data/qitemmodelbardatamapping_p.h
index fa1728e0..90a17fdb 100644
--- a/src/datavis3d/data/qitemmodelbardatamapping_p.h
+++ b/src/datavisualization/data/qitemmodelbardatamapping_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,20 +20,21 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization 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"
+#include "qabstractdatamapping_p.h"
#ifndef QITEMMODELBARDATAMAPPING_P_H
#define QITEMMODELBARDATAMAPPING_P_H
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
-class QItemModelBarDataMappingPrivate : public QObject
+class QItemModelBarDataMappingPrivate : public QAbstractDataMappingPrivate
{
Q_OBJECT
public:
@@ -49,11 +50,14 @@ private:
QStringList m_rowCategories;
QStringList m_columnCategories;
- QItemModelBarDataMapping *q_ptr;
+ bool m_useModelCategories;
+ bool m_autoRowCategories;
+ bool m_autoColumnCategories;
friend class QItemModelBarDataMapping;
+ friend class BarItemModelHandler;
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif
diff --git a/src/datavisualization/data/qitemmodelbardataproxy.cpp b/src/datavisualization/data/qitemmodelbardataproxy.cpp
new file mode 100644
index 00000000..b0fa74b6
--- /dev/null
+++ b/src/datavisualization/data/qitemmodelbardataproxy.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 QtDataVisualization 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 "baritemmodelhandler_p.h"
+#include <QTimer>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+/*!
+ * \class QItemModelBarDataProxy
+ * \inmodule QtDataVisualization
+ * \brief Proxy class for presenting data in item models with Q3DBars.
+ * \since 1.0.0
+ *
+ * QItemModelBarDataProxy allows you to use QAbstractItemModel derived models as a data source
+ * for Q3DBars. It uses QItemModelBarDataMapping instance to map data from the model to Q3DBars
+ * graph.
+ *
+ * Data is resolved asynchronously whenever the mapping or the model changes.
+ * QBarDataProxy::arrayReset() is emitted when the data has been resolved.
+ *
+ * \sa QItemModelBarDataMapping, {Qt Data Visualization Data Handling}
+ */
+
+/*!
+ * \qmltype ItemModelBarDataProxy
+ * \inqmlmodule com.digia.QtDataVisualization 1.0
+ * \since com.digia.QtDataVisualization 1.0
+ * \ingroup datavisualization_qml
+ * \instantiates QItemModelBarDataProxy
+ * \inherits BarDataProxy
+ * \brief Proxy class for presenting data in item models with Bars3D.
+ *
+ * This type allows you to use AbstractItemModel derived models as a data source for Bars3D.
+ *
+ * Data is resolved asynchronously whenever the mapping or the model changes.
+ * QBarDataProxy::arrayReset() is emitted when the data has been resolved.
+ *
+ * Usage example:
+ *
+ * \snippet doc_src_qmldatavisualization.cpp 7
+ *
+ * \sa BarDataProxy, BarDataMapping, {Qt Data Visualization Data Handling}
+ */
+
+/*!
+ * \qmlproperty list ItemModelBarDataProxy::itemModel
+ * The item model.
+ */
+
+/*!
+ * \qmlproperty list ItemModelBarDataProxy::activeMapping
+ * The active mapping. Modifying a mapping that is set to the proxy will trigger data set
+ * re-resolving.
+ */
+
+/*!
+ * Constructs QItemModelBarDataProxy.
+ */
+QItemModelBarDataProxy::QItemModelBarDataProxy() :
+ QBarDataProxy(new QItemModelBarDataProxyPrivate(this))
+{
+}
+
+/*!
+ * Constructs QItemModelBarDataProxy with \a itemModel and \a mapping. Proxy takes ownership of the
+ * \a mapping, but doesn't take ownership of the \a itemModel, as typically item models are owned
+ * by other controls.
+ */
+QItemModelBarDataProxy::QItemModelBarDataProxy(const QAbstractItemModel *itemModel,
+ QItemModelBarDataMapping *mapping) :
+ QBarDataProxy(new QItemModelBarDataProxyPrivate(this))
+{
+ dptr()->m_itemModelHandler->setItemModel(itemModel);
+ dptr()->m_itemModelHandler->setActiveMapping(mapping);
+}
+
+/*!
+ * Destroys QItemModelBarDataProxy.
+ */
+QItemModelBarDataProxy::~QItemModelBarDataProxy()
+{
+}
+
+/*!
+ * \property QItemModelBarDataProxy::itemModel
+ *
+ * Defines item model. Does not take ownership of the model, but does connect to it to listen for
+ * changes.
+ */
+void QItemModelBarDataProxy::setItemModel(const QAbstractItemModel *itemModel)
+{
+ dptr()->m_itemModelHandler->setItemModel(itemModel);
+}
+
+const QAbstractItemModel *QItemModelBarDataProxy::itemModel() const
+{
+ return dptrc()->m_itemModelHandler->itemModel();
+}
+
+/*!
+ * \property QItemModelBarDataProxy::activeMapping
+ *
+ * Defines data mapping. Proxy takes ownership of the \a mapping.
+ * Modifying a mapping that is set to the proxy will trigger data set re-resolving.
+ */
+void QItemModelBarDataProxy::setActiveMapping(QItemModelBarDataMapping *mapping)
+{
+ dptr()->m_itemModelHandler->setActiveMapping(mapping);
+}
+
+QItemModelBarDataMapping *QItemModelBarDataProxy::activeMapping() const
+{
+ return static_cast<QItemModelBarDataMapping *>(dptrc()->m_itemModelHandler->activeMapping());
+}
+
+/*!
+ * Transfers the ownership of the \a mapping to this proxy. The mapping is not taken to use yet.
+ * \sa setActiveMapping(), releaseMapping()
+ */
+void QItemModelBarDataProxy::addMapping(QItemModelBarDataMapping *mapping)
+{
+ dptr()->m_itemModelHandler->addMapping(mapping);
+}
+
+/*!
+ * Releases the ownership of the \a mapping back to the caller. If the mapping was the currently
+ * active one, no mapping remains active after this call.
+ */
+void QItemModelBarDataProxy::releaseMapping(QItemModelBarDataMapping *mapping)
+{
+ dptr()->m_itemModelHandler->releaseMapping(mapping);
+}
+
+/*!
+ * \return list of mappings owned by the proxy.
+ */
+QList<QItemModelBarDataMapping *> QItemModelBarDataProxy::mappings() const
+{
+ QList<QItemModelBarDataMapping *> retList;
+ QList<QAbstractDataMapping *> abstractList = dptrc()->m_itemModelHandler->mappings();
+ foreach (QAbstractDataMapping *mapping, abstractList)
+ retList.append(static_cast<QItemModelBarDataMapping *>(mapping));
+
+ return retList;
+}
+
+/*!
+ * \internal
+ */
+QItemModelBarDataProxyPrivate *QItemModelBarDataProxy::dptr()
+{
+ return static_cast<QItemModelBarDataProxyPrivate *>(d_ptr.data());
+}
+
+/*!
+ * \internal
+ */
+const QItemModelBarDataProxyPrivate *QItemModelBarDataProxy::dptrc() const
+{
+ return static_cast<const QItemModelBarDataProxyPrivate *>(d_ptr.data());
+}
+
+// QItemModelBarDataProxyPrivate
+
+QItemModelBarDataProxyPrivate::QItemModelBarDataProxyPrivate(QItemModelBarDataProxy *q)
+ : QBarDataProxyPrivate(q),
+ m_itemModelHandler(new BarItemModelHandler(q))
+{
+}
+
+QItemModelBarDataProxyPrivate::~QItemModelBarDataProxyPrivate()
+{
+ delete m_itemModelHandler;
+}
+
+QItemModelBarDataProxy *QItemModelBarDataProxyPrivate::qptr()
+{
+ return static_cast<QItemModelBarDataProxy *>(q_ptr);
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualization/data/qitemmodelbardataproxy.h b/src/datavisualization/data/qitemmodelbardataproxy.h
new file mode 100644
index 00000000..2a96f0c8
--- /dev/null
+++ b/src/datavisualization/data/qitemmodelbardataproxy.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 QtDataVisualization 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 <QtDataVisualization/qbardataproxy.h>
+#include <QtDataVisualization/qitemmodelbardatamapping.h>
+#include <QAbstractItemModel>
+#include <QStringList>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class QItemModelBarDataProxyPrivate;
+
+class QT_DATAVISUALIZATION_EXPORT QItemModelBarDataProxy : public QBarDataProxy
+{
+ Q_OBJECT
+ Q_PROPERTY(const QAbstractItemModel* itemModel READ itemModel WRITE setItemModel)
+ Q_PROPERTY(QItemModelBarDataMapping* activeMapping READ activeMapping WRITE setActiveMapping)
+
+public:
+ explicit QItemModelBarDataProxy();
+ explicit QItemModelBarDataProxy(const QAbstractItemModel *itemModel,
+ QItemModelBarDataMapping *mapping);
+ virtual ~QItemModelBarDataProxy();
+
+ void setItemModel(const QAbstractItemModel *itemModel);
+ const QAbstractItemModel *itemModel() const;
+
+ void setActiveMapping(QItemModelBarDataMapping *mapping);
+ QItemModelBarDataMapping *activeMapping() const;
+ void addMapping(QItemModelBarDataMapping *mapping);
+ void releaseMapping(QItemModelBarDataMapping *mapping);
+ QList<QItemModelBarDataMapping *> mappings() const;
+
+protected:
+ QItemModelBarDataProxyPrivate *dptr();
+ const QItemModelBarDataProxyPrivate *dptrc() const;
+
+private:
+ Q_DISABLE_COPY(QItemModelBarDataProxy)
+};
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/data/qmapdataproxy_p.h b/src/datavisualization/data/qitemmodelbardataproxy_p.h
index bf3d1d2c..fc646f0d 100644
--- a/src/datavis3d/data/qmapdataproxy_p.h
+++ b/src/datavisualization/data/qitemmodelbardataproxy_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,39 +20,39 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization 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
+#ifndef QITEMMODELBARDATAPROXY_P_H
+#define QITEMMODELBARDATAPROXY_P_H
-#include "qmapdataproxy.h"
-#include "qabstractdataproxy_p.h"
-#include "qmapdataitem.h"
+#include "qitemmodelbardataproxy.h"
+#include "qbardataproxy_p.h"
+#include <QPointer>
+#include <QTimer>
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
-class QMapDataProxyPrivate : public QAbstractDataProxyPrivate
+class BarItemModelHandler;
+
+class QItemModelBarDataProxyPrivate : public QBarDataProxyPrivate
{
Q_OBJECT
public:
- QMapDataProxyPrivate(QMapDataProxy *q);
- virtual ~QMapDataProxyPrivate();
-
- bool resetArray(QMapDataArray *newArray);
-
- QPair<GLfloat, GLfloat> limitValues();
+ QItemModelBarDataProxyPrivate(QItemModelBarDataProxy *q);
+ virtual ~QItemModelBarDataProxyPrivate();
private:
- QMapDataArray m_dataArray;
+ QItemModelBarDataProxy *qptr();
-private:
- friend class QMapDataProxy;
+ BarItemModelHandler *m_itemModelHandler;
+
+ friend class QItemModelBarDataProxy;
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
-#endif // QBARDATAPROXY_P_H
+#endif
diff --git a/src/datavisualization/data/qitemmodelscatterdatamapping.cpp b/src/datavisualization/data/qitemmodelscatterdatamapping.cpp
new file mode 100644
index 00000000..f9ef6d04
--- /dev/null
+++ b/src/datavisualization/data/qitemmodelscatterdatamapping.cpp
@@ -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 QtDataVisualization 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_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+/*!
+ * \class QItemModelScatterDataMapping
+ * \inmodule QtDataVisualization
+ * \brief Item model mapping for Q3DScatter.
+ * \since 1.0.0
+ *
+ * QItemModelScatterDataMapping is used to map roles of QAbstractItemModel to the XYZ-values
+ * of Q3DScatter points.
+ *
+ * QItemModelScatterDataMapping ignores rows and columns of the QAbstractItemModel and treats
+ * all items equally. It requires the model to provide at least three roles for the data items
+ * that can be mapped to X, Y, and Z-values for the scatter points.
+ *
+ * For example, assume that you have a custom QAbstractItemModel for storing various measurements
+ * done on material samples, providing data for roles such as "density", "hardness" and
+ * "conductivity". You could visualize these properties on a scatter graph:
+ *
+ * \snippet doc_src_qtdatavisualization.cpp 4
+ *
+ * \sa QItemModelScatterDataProxy, {Qt Data Visualization Data Handling}
+ */
+
+/*!
+ * \qmltype ScatterDataMapping
+ * \inqmlmodule com.digia.QtDataVisualization 1.0
+ * \since com.digia.QtDataVisualization 1.0
+ * \ingroup datavisualization_qml
+ * \instantiates QItemModelScatterDataMapping
+ * \brief Item model mapping for Scatter3D.
+ *
+ * This type is used to map roles of AbstractItemModel to the XYZ-values of Scatter3D points. For
+ * more complete description, see QItemModelScatterDataMapping.
+ *
+ * Usage example:
+ *
+ * \snippet doc_src_qmldatavisualization.cpp 5
+ *
+ * \sa ItemModelScatterDataProxy, {Qt Data Visualization Data Handling}
+ */
+
+/*!
+ * \qmlproperty string ScatterDataMapping::xPosRole
+ * The X position role of the mapping.
+ */
+
+/*!
+ * \qmlproperty string ScatterDataMapping::yPosRole
+ * The Y position role of the mapping.
+ */
+
+/*!
+ * \qmlproperty string ScatterDataMapping::zPosRole
+ * The Z position role of the mapping.
+ */
+
+/*!
+ * Constructs QItemModelScatterDataMapping with the given \a parent.
+ */
+QItemModelScatterDataMapping::QItemModelScatterDataMapping(QObject *parent)
+ : QAbstractDataMapping(new QItemModelScatterDataMappingPrivate(this), parent)
+{
+}
+
+/*!
+ * Constructs QItemModelScatterDataMapping with \a xPosRole, \a yPosRole, \a zPosRole
+ * and the given \a parent.
+ */
+QItemModelScatterDataMapping::QItemModelScatterDataMapping(const QString &xPosRole,
+ const QString &yPosRole,
+ const QString &zPosRole,
+ QObject *parent)
+ : QAbstractDataMapping(new QItemModelScatterDataMappingPrivate(this), parent)
+{
+ dptr()->m_xPosRole = xPosRole;
+ dptr()->m_yPosRole = yPosRole;
+ dptr()->m_zPosRole = zPosRole;
+}
+
+/*!
+ * Destroys QItemModelScatterDataMapping.
+ */
+QItemModelScatterDataMapping::~QItemModelScatterDataMapping()
+{
+}
+
+/*!
+ * \property QItemModelScatterDataMapping::xPosRole
+ *
+ * Defines the X position role for the mapping.
+ */
+void QItemModelScatterDataMapping::setXPosRole(const QString &role)
+{
+ dptr()->m_xPosRole = role;
+ emit mappingChanged();
+}
+
+QString QItemModelScatterDataMapping::xPosRole() const
+{
+ return dptrc()->m_xPosRole;
+}
+
+/*!
+ * \property QItemModelScatterDataMapping::yPosRole
+ *
+ * Defines the Y position role for the mapping.
+ */
+void QItemModelScatterDataMapping::setYPosRole(const QString &role)
+{
+ dptr()->m_yPosRole = role;
+ emit mappingChanged();
+}
+
+QString QItemModelScatterDataMapping::yPosRole() const
+{
+ return dptrc()->m_yPosRole;
+}
+
+/*!
+ * \property QItemModelScatterDataMapping::zPosRole
+ *
+ * Defines the Z position role for the mapping.
+ */
+void QItemModelScatterDataMapping::setZPosRole(const QString &role)
+{
+ dptr()->m_zPosRole = role;
+ emit mappingChanged();
+}
+
+QString QItemModelScatterDataMapping::zPosRole() const
+{
+ return dptrc()->m_zPosRole;
+}
+
+/*!
+ * Changes \a xPosRole, \a yPosRole and \a zPosRole to the mapping.
+ *
+ * Emits mappingChanged() signal after remapping.
+ */
+void QItemModelScatterDataMapping::remap(const QString &xPosRole, const QString &yPosRole,
+ const QString &zPosRole)
+{
+ dptr()->m_xPosRole = xPosRole;
+ dptr()->m_yPosRole = yPosRole;
+ dptr()->m_zPosRole = zPosRole;
+
+ emit mappingChanged();
+}
+
+/*!
+ * \internal
+ */
+QItemModelScatterDataMappingPrivate *QItemModelScatterDataMapping::dptr()
+{
+ return static_cast<QItemModelScatterDataMappingPrivate *>(d_ptr.data());
+}
+
+/*!
+ * \internal
+ */
+const QItemModelScatterDataMappingPrivate *QItemModelScatterDataMapping::dptrc() const
+{
+ return static_cast<const QItemModelScatterDataMappingPrivate *>(d_ptr.data());
+}
+
+// QItemModelScatterDataMappingPrivate
+
+QItemModelScatterDataMappingPrivate::QItemModelScatterDataMappingPrivate(
+ QItemModelScatterDataMapping *q)
+ : QAbstractDataMappingPrivate(q, QAbstractDataProxy::DataTypeScatter)
+{
+}
+
+QItemModelScatterDataMappingPrivate::~QItemModelScatterDataMappingPrivate()
+{
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
diff --git a/src/datavis3d/data/qitemmodelscatterdatamapping.h b/src/datavisualization/data/qitemmodelscatterdatamapping.h
index f4a2cfe6..62f2fefc 100644
--- a/src/datavis3d/data/qitemmodelscatterdatamapping.h
+++ b/src/datavisualization/data/qitemmodelscatterdatamapping.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -19,52 +19,44 @@
#ifndef QITEMMODELSCATTERDATAMAPPING_H
#define QITEMMODELSCATTERDATAMAPPING_H
-#include <QtDataVis3D/qdatavis3denums.h>
+#include <QtDataVisualization/qdatavisualizationenums.h>
+#include <QtDataVisualization/qabstractdatamapping.h>
#include <QObject>
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
class QItemModelScatterDataMappingPrivate;
-class QT_DATAVIS3D_EXPORT QItemModelScatterDataMapping : public QObject
+class QT_DATAVISUALIZATION_EXPORT QItemModelScatterDataMapping : public QAbstractDataMapping
{
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);
+ explicit QItemModelScatterDataMapping(QObject *parent = 0);
+ QItemModelScatterDataMapping(const QString &xPosRole, const QString &yPosRole,
+ const QString &zPosRole, QObject *parent = 0);
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();
+ void remap(const QString &xPosRole, const QString &yPosRole, const QString &zPosRole);
+
+protected:
+ QItemModelScatterDataMappingPrivate *dptr();
+ const QItemModelScatterDataMappingPrivate *dptrc() const;
private:
- QScopedPointer<QItemModelScatterDataMappingPrivate> d_ptr;
+ Q_DISABLE_COPY(QItemModelScatterDataMapping)
};
-
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif
diff --git a/src/datavis3d/data/qitemmodelscatterdatamapping_p.h b/src/datavisualization/data/qitemmodelscatterdatamapping_p.h
index 90a826c0..62ff42b4 100644
--- a/src/datavis3d/data/qitemmodelscatterdatamapping_p.h
+++ b/src/datavisualization/data/qitemmodelscatterdatamapping_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,20 +20,21 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization 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
+#include "qitemmodelscatterdatamapping.h"
+#include "qabstractdatamapping_p.h"
-class QItemModelScatterDataMappingPrivate : public QObject
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class QItemModelScatterDataMappingPrivate : public QAbstractDataMappingPrivate
{
Q_OBJECT
public:
@@ -47,11 +48,9 @@ private:
QString m_zPosRole;
//QString m_valueRole;
- QItemModelScatterDataMapping *q_ptr;
-
friend class QItemModelScatterDataMapping;
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif
diff --git a/src/datavisualization/data/qitemmodelscatterdataproxy.cpp b/src/datavisualization/data/qitemmodelscatterdataproxy.cpp
new file mode 100644
index 00000000..b037d4d1
--- /dev/null
+++ b/src/datavisualization/data/qitemmodelscatterdataproxy.cpp
@@ -0,0 +1,196 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 "scatteritemmodelhandler_p.h"
+#include <QTimer>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+/*!
+ * \class QItemModelScatterDataProxy
+ * \inmodule QtDataVisualization
+ * \brief Proxy class for presenting data in item models with Q3DScatter.
+ * \since 1.0.0
+ *
+ * QItemModelScatterDataProxy allows you to use QAbstractItemModel derived models as a data source
+ * for Q3DScatter. It maps roles defined in QItemModelScatterDataMapping to roles in the model.
+ *
+ * Data is resolved asynchronously whenever the mapping or the model changes.
+ * QScatterDataProxy::arrayReset() is emitted when the data has been resolved.
+ *
+ * /sa {Qt Data Visualization Data Handling}
+ */
+
+/*!
+ * \qmltype ItemModelScatterDataProxy
+ * \inqmlmodule com.digia.QtDataVisualization 1.0
+ * \since com.digia.QtDataVisualization 1.0
+ * \ingroup datavisualization_qml
+ * \instantiates QItemModelScatterDataProxy
+ * \inherits ScatterDataProxy
+ * \brief Proxy class for presenting data in item models with Scatter3D.
+ *
+ * This type allows you to use AbstractItemModel derived models as a data source for Scatter3D.
+ *
+ * Data is resolved asynchronously whenever the mapping or the model changes.
+ * QScatterDataProxy::arrayReset() is emitted when the data has been resolved.
+ *
+ * Usage example:
+ *
+ * \snippet doc_src_qmldatavisualization.cpp 8
+ *
+ * \sa ScatterDataProxy, ScatterDataMapping, {Qt Data Visualization Data Handling}
+ */
+
+/*!
+ * \qmlproperty list ItemModelScatterDataProxy::itemModel
+ * The item model.
+ */
+
+/*!
+ * \qmlproperty list ItemModelScatterDataProxy::activeMapping
+ * The active mapping. Modifying a mapping that is set to the proxy will trigger data set
+ * re-resolving.
+ */
+
+/*!
+ * Constructs QItemModelScatterDataProxy.
+ */
+QItemModelScatterDataProxy::QItemModelScatterDataProxy() :
+ QScatterDataProxy(new QItemModelScatterDataProxyPrivate(this))
+{
+}
+
+/*!
+ * Constructs QItemModelScatterDataProxy with \a itemModel and \a mapping. Does not take ownership
+ * of the model or the mapping, but does connect to them to listen for changes.
+ */
+QItemModelScatterDataProxy::QItemModelScatterDataProxy(const QAbstractItemModel *itemModel,
+ QItemModelScatterDataMapping *mapping) :
+ QScatterDataProxy(new QItemModelScatterDataProxyPrivate(this))
+{
+ dptr()->m_itemModelHandler->setItemModel(itemModel);
+ dptr()->m_itemModelHandler->setActiveMapping(mapping);
+}
+
+/*!
+ * Destroys QItemModelScatterDataProxy.
+ */
+QItemModelScatterDataProxy::~QItemModelScatterDataProxy()
+{
+}
+
+/*!
+ * \property QItemModelScatterDataProxy::itemModel
+ *
+ * Defines item model. Does not take ownership of the model, but does connect to it to listen for
+ * changes.
+ */
+void QItemModelScatterDataProxy::setItemModel(const QAbstractItemModel *itemModel)
+{
+ dptr()->m_itemModelHandler->setItemModel(itemModel);
+}
+
+const QAbstractItemModel *QItemModelScatterDataProxy::itemModel() const
+{
+ return dptrc()->m_itemModelHandler->itemModel();
+}
+
+/*!
+ * \property QItemModelScatterDataProxy::activeMapping
+ *
+ * Defines data mapping. Proxy takes ownership of the \a mapping.
+ * Modifying a mapping that is set to the proxy will trigger data set re-resolving.
+ */
+void QItemModelScatterDataProxy::setActiveMapping(QItemModelScatterDataMapping *mapping)
+{
+ dptr()->m_itemModelHandler->setActiveMapping(mapping);
+}
+
+QItemModelScatterDataMapping *QItemModelScatterDataProxy::activeMapping() const
+{
+ return static_cast<QItemModelScatterDataMapping *>(dptrc()->m_itemModelHandler->activeMapping());
+}
+
+/*!
+ * Transfers the ownership of the \a mapping to this proxy. The mapping is not taken to use yet.
+ * \sa setActiveMapping(), releaseMapping()
+ */
+void QItemModelScatterDataProxy::addMapping(QItemModelScatterDataMapping *mapping)
+{
+ dptr()->m_itemModelHandler->addMapping(mapping);
+}
+
+/*!
+ * Releases the ownership of the \a mapping back to the caller. If the mapping was the currently
+ * active one, no mapping remains active after this call.
+ */
+void QItemModelScatterDataProxy::releaseMapping(QItemModelScatterDataMapping *mapping)
+{
+ dptr()->m_itemModelHandler->releaseMapping(mapping);
+}
+
+/*!
+ * \return list of mappings owned by the proxy.
+ */
+QList<QItemModelScatterDataMapping *> QItemModelScatterDataProxy::mappings() const
+{
+ QList<QItemModelScatterDataMapping *> retList;
+ QList<QAbstractDataMapping *> abstractList = dptrc()->m_itemModelHandler->mappings();
+ foreach (QAbstractDataMapping *mapping, abstractList)
+ retList.append(static_cast<QItemModelScatterDataMapping *>(mapping));
+
+ return retList;
+}
+
+/*!
+ * \internal
+ */
+QItemModelScatterDataProxyPrivate *QItemModelScatterDataProxy::dptr()
+{
+ return static_cast<QItemModelScatterDataProxyPrivate *>(d_ptr.data());
+}
+
+/*!
+ * \internal
+ */
+const QItemModelScatterDataProxyPrivate *QItemModelScatterDataProxy::dptrc() const
+{
+ return static_cast<const QItemModelScatterDataProxyPrivate *>(d_ptr.data());
+}
+
+// QItemModelScatterDataProxyPrivate
+
+QItemModelScatterDataProxyPrivate::QItemModelScatterDataProxyPrivate(QItemModelScatterDataProxy *q)
+ : QScatterDataProxyPrivate(q),
+ m_itemModelHandler(new ScatterItemModelHandler(q))
+{
+}
+
+QItemModelScatterDataProxyPrivate::~QItemModelScatterDataProxyPrivate()
+{
+ delete m_itemModelHandler;
+}
+
+QItemModelScatterDataProxy *QItemModelScatterDataProxyPrivate::qptr()
+{
+ return static_cast<QItemModelScatterDataProxy *>(q_ptr);
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavis3d/data/qitemmodelscatterdataproxy.h b/src/datavisualization/data/qitemmodelscatterdataproxy.h
index f609e84b..891950c1 100644
--- a/src/datavis3d/data/qitemmodelscatterdataproxy.h
+++ b/src/datavisualization/data/qitemmodelscatterdataproxy.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -19,42 +19,44 @@
#ifndef QITEMMODELSCATTERDATAPROXY_H
#define QITEMMODELSCATTERDATAPROXY_H
-#include <QtDataVis3D/qscatterdataproxy.h>
-#include <QtDataVis3D/qitemmodelscatterdatamapping.h>
+#include <QtDataVisualization/qscatterdataproxy.h>
+#include <QtDataVisualization/qitemmodelscatterdatamapping.h>
#include <QAbstractItemModel>
#include <QStringList>
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
class QItemModelScatterDataProxyPrivate;
-class QT_DATAVIS3D_EXPORT QItemModelScatterDataProxy : public QScatterDataProxy
+class QT_DATAVISUALIZATION_EXPORT QItemModelScatterDataProxy : public QScatterDataProxy
{
Q_OBJECT
+ Q_PROPERTY(const QAbstractItemModel* itemModel READ itemModel WRITE setItemModel)
+ Q_PROPERTY(QItemModelScatterDataMapping* activeMapping READ activeMapping WRITE setActiveMapping)
public:
explicit QItemModelScatterDataProxy();
- explicit QItemModelScatterDataProxy(QAbstractItemModel *itemModel,
+ explicit QItemModelScatterDataProxy(const 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();
+ void setItemModel(const QAbstractItemModel *itemModel);
+ const QAbstractItemModel *itemModel() const;
- // 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();
+ void setActiveMapping(QItemModelScatterDataMapping *mapping);
+ QItemModelScatterDataMapping *activeMapping() const;
+ void addMapping(QItemModelScatterDataMapping *mapping);
+ void releaseMapping(QItemModelScatterDataMapping *mapping);
+ QList<QItemModelScatterDataMapping *> mappings() const;
protected:
QItemModelScatterDataProxyPrivate *dptr();
+ const QItemModelScatterDataProxyPrivate *dptrc() const;
private:
Q_DISABLE_COPY(QItemModelScatterDataProxy)
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif
diff --git a/src/datavisualization/data/qitemmodelscatterdataproxy_p.h b/src/datavisualization/data/qitemmodelscatterdataproxy_p.h
new file mode 100644
index 00000000..854062a3
--- /dev/null
+++ b/src/datavisualization/data/qitemmodelscatterdataproxy_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 QtDataVisualization 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 QtDataVisualization 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_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class ScatterItemModelHandler;
+
+class QItemModelScatterDataProxyPrivate : public QScatterDataProxyPrivate
+{
+ Q_OBJECT
+public:
+ QItemModelScatterDataProxyPrivate(QItemModelScatterDataProxy *q);
+ virtual ~QItemModelScatterDataProxyPrivate();
+
+private:
+ QItemModelScatterDataProxy *qptr();
+
+ ScatterItemModelHandler *m_itemModelHandler;
+
+ friend class QItemModelScatterDataProxy;
+};
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
+#endif
diff --git a/src/datavisualization/data/qitemmodelsurfacedatamapping.cpp b/src/datavisualization/data/qitemmodelsurfacedatamapping.cpp
new file mode 100644
index 00000000..5388ec18
--- /dev/null
+++ b/src/datavisualization/data/qitemmodelsurfacedatamapping.cpp
@@ -0,0 +1,411 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 "qitemmodelsurfacedatamapping_p.h"
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+/*!
+ * \class QItemModelSurfaceDataMapping
+ * \inmodule QtDataVisualization
+ * \brief Item model mapping for Q3DSurface.
+ * \since 1.0.0
+ *
+ * QItemModelSurfaceDataMapping is used to map roles of QAbstractItemModel to rows, columns, and values
+ * of Q3DSurface. There are three ways to use QItemModelSurfaceDataMapping:
+ *
+ * 1) If useModelCategories property is set to true, QItemModelSurfaceDataMapping will map rows and
+ * columns of QAbstractItemModel to rows and columns of Q3DSurface, and uses the value returned for
+ * Qt::DisplayRole as bar value by default.
+ * The value role to be used can be redefined if Qt::DisplayRole is not suitable.
+ *
+ * 2) For models that do not have data already neatly sorted into rows and columns, such as
+ * QAbstractListModel based models, you can define a role from the model to map for each of row,
+ * column and value.
+ *
+ * 3) If you do not want to include all data contained in the model, or the autogenerated rows and
+ * columns are not ordered as you wish, you can specify which rows and columns should be included
+ * and in which order by defining an explicit list of categories for either or both of rows and
+ * columns.
+ *
+ * For example, assume that you have a custom QAbstractItemModel storing surface topography data.
+ * Each item in the model has roles "longitude", "latitude" and "height". The item model already
+ * contains the data properly sorted so that longitudes and latitudes are first encountered in
+ * correct order, which enables us to utilize the row and column category autogeneration.
+ * You could do the following to display the data in a surface graph:
+ *
+ * \snippet doc_src_qtdatavisualization.cpp 5
+ *
+ * \sa QItemModelSurfaceDataProxy, {Qt Data Visualization Data Handling}
+ */
+
+/*!
+ * \qmltype SurfaceDataMapping
+ * \inqmlmodule com.digia.QtDataVisualization 1.0
+ * \since com.digia.QtDataVisualization 1.0
+ * \ingroup datavisualization_qml
+ * \instantiates QItemModelSurfaceDataMapping
+ * \brief Item model mapping for Surface3D.
+ *
+ * This type is used to map roles of AbstractItemModel to rows, columns, and values of Surface3D.
+ * For more complete description, see QItemModelSurfaceDataMapping.
+ *
+ * Usage example:
+ *
+ * \snippet doc_src_qmldatavisualization.cpp 6
+ *
+ * \sa ItemModelSurfaceDataProxy, {Qt Data Visualization Data Handling}
+ */
+
+/*!
+ * \qmlproperty string SurfaceDataMapping::rowRole
+ * The row role of the mapping.
+ */
+
+/*!
+ * \qmlproperty string SurfaceDataMapping::columnRole
+ * The column role of the mapping.
+ */
+
+/*!
+ * \qmlproperty string SurfaceDataMapping::valueRole
+ * The value role of the mapping.
+ */
+
+/*!
+ * \qmlproperty list SurfaceDataMapping::rowCategories
+ * The row categories of the mapping. Only items with row roles that are found in this list are
+ * included when data is resolved. The rows are ordered in the same order as they are in this list.
+ */
+
+/*!
+ * \qmlproperty list SurfaceDataMapping::columnCategories
+ * The column categories of the mapping. Only items with column roles that are found in this list are
+ * included when data is resolved. The columns are ordered in the same order as they are in this list.
+ */
+
+/*!
+ * \qmlproperty list SurfaceDataMapping::useModelCategories
+ * When set to true, the mapping ignores row and column roles and categories, and uses
+ * the rows and columns from the model instead. Defaults to false.
+ */
+
+/*!
+ * \qmlproperty list SurfaceDataMapping::autoRowCategories
+ * When set to true, the mapping ignores any explicitly set row categories
+ * and overwrites them with automatically generated ones whenever the
+ * data from model is resolved. Proxy minimum and maximum row values are also
+ * autogenerated from data when this is set to true. Defaults to true.
+ */
+
+/*!
+ * \qmlproperty list SurfaceDataMapping::autoColumnCategories
+ * When set to true, the mapping ignores any explicitly set column categories
+ * and overwrites them with automatically generated ones whenever the
+ * data from model is resolved. Proxy minimum and maximum column values are also
+ * autogenerated from data when this is set to true. Defaults to true.
+ */
+
+/*!
+ * Constructs QItemModelSurfaceDataMapping with the given \a parent.
+ */
+QItemModelSurfaceDataMapping::QItemModelSurfaceDataMapping(QObject *parent)
+ : QAbstractDataMapping(new QItemModelSurfaceDataMappingPrivate(this), parent)
+{
+}
+
+/*!
+ * Constructs QItemModelSurfaceDataMapping with \a valueRole and the given \a parent.
+ * This constructor is meant to be used with models that have data properly sorted
+ * in rows and columns already, so it also sets useModelCategories property to true.
+ */
+QItemModelSurfaceDataMapping::QItemModelSurfaceDataMapping(const QString &valueRole, QObject *parent)
+ : QAbstractDataMapping(new QItemModelSurfaceDataMappingPrivate(this), parent)
+{
+ dptr()->m_valueRole = valueRole;
+ dptr()->m_useModelCategories = true;
+}
+
+/*!
+ * Constructs QItemModelSurfaceDataMapping with \a rowRole, \a columnRole, \a valueRole
+ * and the given \a parent.
+ */
+QItemModelSurfaceDataMapping::QItemModelSurfaceDataMapping(const QString &rowRole,
+ const QString &columnRole,
+ const QString &valueRole,
+ QObject *parent)
+ : QAbstractDataMapping(new QItemModelSurfaceDataMappingPrivate(this), parent)
+{
+ dptr()->m_rowRole = rowRole;
+ dptr()->m_columnRole = columnRole;
+ dptr()->m_valueRole = valueRole;
+}
+
+/*!
+ * Constructs QItemModelSurfaceDataMapping with \a rowRole, \a columnRole, \a valueRole,
+ * \a rowCategories, \a columnCategories and the given \a parent. This constructor
+ * also sets autoRowCategories and autoColumnCategories to false.
+ */
+QItemModelSurfaceDataMapping::QItemModelSurfaceDataMapping(const QString &rowRole,
+ const QString &columnRole,
+ const QString &valueRole,
+ const QStringList &rowCategories,
+ const QStringList &columnCategories,
+ QObject *parent)
+ : QAbstractDataMapping(new QItemModelSurfaceDataMappingPrivate(this), parent)
+{
+ dptr()->m_rowRole = rowRole;
+ dptr()->m_columnRole = columnRole;
+ dptr()->m_valueRole = valueRole;
+ dptr()->m_rowCategories = rowCategories;
+ dptr()->m_columnCategories = columnCategories;
+ dptr()->m_autoRowCategories = false;
+ dptr()->m_autoColumnCategories = false;
+}
+
+/*!
+ * Destroys QItemModelSurfaceDataMapping.
+ */
+QItemModelSurfaceDataMapping::~QItemModelSurfaceDataMapping()
+{
+}
+
+/*!
+ * \property QItemModelSurfaceDataMapping::rowRole
+ *
+ * Defines the row role for the mapping.
+ */
+void QItemModelSurfaceDataMapping::setRowRole(const QString &role)
+{
+ if (dptr()->m_rowRole != role) {
+ dptr()->m_rowRole = role;
+ emit mappingChanged();
+ }
+}
+
+QString QItemModelSurfaceDataMapping::rowRole() const
+{
+ return dptrc()->m_rowRole;
+}
+
+/*!
+ * \property QItemModelSurfaceDataMapping::columnRole
+ *
+ * Defines the column role for the mapping.
+ */
+void QItemModelSurfaceDataMapping::setColumnRole(const QString &role)
+{
+ if (dptr()->m_columnRole != role) {
+ dptr()->m_columnRole = role;
+ emit mappingChanged();
+ }
+}
+
+QString QItemModelSurfaceDataMapping::columnRole() const
+{
+ return dptrc()->m_columnRole;
+}
+
+/*!
+ * \property QItemModelSurfaceDataMapping::valueRole
+ *
+ * Defines the value role for the mapping.
+ */
+void QItemModelSurfaceDataMapping::setValueRole(const QString &role)
+{
+ if (dptr()->m_valueRole != role) {
+ dptr()->m_valueRole = role;
+ emit mappingChanged();
+ }
+}
+
+QString QItemModelSurfaceDataMapping::valueRole() const
+{
+ return dptrc()->m_valueRole;
+}
+
+/*!
+ * \property QItemModelSurfaceDataMapping::rowCategories
+ *
+ * Defines the row categories for the mapping.
+ */
+void QItemModelSurfaceDataMapping::setRowCategories(const QStringList &categories)
+{
+ if (dptr()->m_rowCategories != categories) {
+ dptr()->m_rowCategories = categories;
+ emit mappingChanged();
+ }
+}
+
+QStringList QItemModelSurfaceDataMapping::rowCategories() const
+{
+ return dptrc()->m_rowCategories;
+}
+
+/*!
+ * \property QItemModelSurfaceDataMapping::columnCategories
+ *
+ * Defines the column categories for the mapping.
+ */
+void QItemModelSurfaceDataMapping::setColumnCategories(const QStringList &categories)
+{
+ if (dptr()->m_columnCategories != categories) {
+ dptr()->m_columnCategories = categories;
+ emit mappingChanged();
+ }
+}
+
+QStringList QItemModelSurfaceDataMapping::columnCategories() const
+{
+ return dptrc()->m_columnCategories;
+}
+
+/*!
+ * \property QItemModelSurfaceDataMapping::useModelCategories
+ *
+ * When set to true, the mapping ignores row and column roles and categories, and uses
+ * the rows and columns from the model instead. Defaults to false.
+ */
+void QItemModelSurfaceDataMapping::setUseModelCategories(bool enable)
+{
+ if (dptr()->m_useModelCategories != enable) {
+ dptr()->m_useModelCategories = enable;
+ emit mappingChanged();
+ }
+}
+
+bool QItemModelSurfaceDataMapping::useModelCategories() const
+{
+ return dptrc()->m_useModelCategories;
+}
+
+/*!
+ * \property QItemModelSurfaceDataMapping::autoRowCategories
+ *
+ * When set to true, the mapping ignores any explicitly set row categories
+ * and overwrites them with automatically generated ones whenever the
+ * data from model is resolved. Proxy minimum and maximum row values are also
+ * autogenerated from data when this is set to true. Defaults to true.
+ */
+void QItemModelSurfaceDataMapping::setAutoRowCategories(bool enable)
+{
+ if (dptr()->m_autoRowCategories != enable) {
+ dptr()->m_autoRowCategories = enable;
+ emit mappingChanged();
+ }
+}
+
+bool QItemModelSurfaceDataMapping::autoRowCategories() const
+{
+ return dptrc()->m_autoRowCategories;
+}
+
+/*!
+ * \property QItemModelSurfaceDataMapping::autoColumnCategories
+ *
+ * When set to true, the mapping ignores any explicitly set column categories
+ * and overwrites them with automatically generated ones whenever the
+ * data from model is resolved. Proxy minimum and maximum column values are also
+ * autogenerated from data when this is set to true. Defaults to true.
+ */
+void QItemModelSurfaceDataMapping::setAutoColumnCategories(bool enable)
+{
+ if (dptr()->m_autoColumnCategories != enable) {
+ dptr()->m_autoColumnCategories = enable;
+ emit mappingChanged();
+ }
+}
+
+bool QItemModelSurfaceDataMapping::autoColumnCategories() const
+{
+ return dptrc()->m_autoColumnCategories;
+}
+
+/*!
+ * Changes \a rowRole, \a columnRole, \a valueRole, \a rowCategories and \a columnCategories to the
+ * mapping.
+ */
+void QItemModelSurfaceDataMapping::remap(const QString &rowRole,
+ const QString &columnRole,
+ const QString &valueRole,
+ const QStringList &rowCategories,
+ const QStringList &columnCategories)
+{
+ dptr()->m_rowRole = rowRole;
+ dptr()->m_columnRole = columnRole;
+ dptr()->m_valueRole = valueRole;
+ dptr()->m_rowCategories = rowCategories;
+ dptr()->m_columnCategories = columnCategories;
+
+ emit mappingChanged();
+}
+
+/*!
+ * /return index of the specified \a category in row categories list.
+ * If the row categories list is empty, -1 is returned.
+ * \note If the automatic row categories generation is in use, this method will
+ * not return valid index before the data in the model is resolved for the first time.
+ */
+int QItemModelSurfaceDataMapping::rowCategoryIndex(const QString &category)
+{
+ return dptr()->m_rowCategories.indexOf(category);
+}
+
+/*!
+ * /return index of the specified \a category in column categories list.
+ * \note If the automatic column categories generation is in use, this method will
+ * not return valid index before the data in the model is resolved for the first time.
+ */
+int QItemModelSurfaceDataMapping::columnCategoryIndex(const QString &category)
+{
+ return dptr()->m_columnCategories.indexOf(category);
+}
+
+/*!
+ * \internal
+ */
+QItemModelSurfaceDataMappingPrivate *QItemModelSurfaceDataMapping::dptr()
+{
+ return static_cast<QItemModelSurfaceDataMappingPrivate *>(d_ptr.data());
+}
+
+/*!
+ * \internal
+ */
+const QItemModelSurfaceDataMappingPrivate *QItemModelSurfaceDataMapping::dptrc() const
+{
+ return static_cast<const QItemModelSurfaceDataMappingPrivate *>(d_ptr.data());
+}
+
+// QItemModelSurfaceDataMappingPrivate
+
+QItemModelSurfaceDataMappingPrivate::QItemModelSurfaceDataMappingPrivate(QItemModelSurfaceDataMapping *q)
+ : QAbstractDataMappingPrivate(q, QAbstractDataProxy::DataTypeSurface),
+ m_useModelCategories(false),
+ m_autoRowCategories(true),
+ m_autoColumnCategories(true)
+{
+}
+
+QItemModelSurfaceDataMappingPrivate::~QItemModelSurfaceDataMappingPrivate()
+{
+}
+
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
diff --git a/src/datavisualization/data/qitemmodelsurfacedatamapping.h b/src/datavisualization/data/qitemmodelsurfacedatamapping.h
new file mode 100644
index 00000000..7e8817bf
--- /dev/null
+++ b/src/datavisualization/data/qitemmodelsurfacedatamapping.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 QITEMMODELSURFACEDATAMAPPING_H
+#define QITEMMODELSURFACEDATAMAPPING_H
+
+#include <QtDataVisualization/qdatavisualizationenums.h>
+#include <QtDataVisualization/qabstractdatamapping.h>
+#include <QStringList>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class QItemModelSurfaceDataMappingPrivate;
+
+class QT_DATAVISUALIZATION_EXPORT QItemModelSurfaceDataMapping : public QAbstractDataMapping
+{
+ 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)
+ Q_PROPERTY(bool useModelCategories READ useModelCategories WRITE setUseModelCategories)
+ Q_PROPERTY(bool autoRowCategories READ autoRowCategories WRITE setAutoRowCategories)
+ Q_PROPERTY(bool autoColumnCategories READ autoColumnCategories WRITE setAutoColumnCategories)
+
+public:
+ explicit QItemModelSurfaceDataMapping(QObject *parent = 0);
+ QItemModelSurfaceDataMapping(const QString &valueRole, QObject *parent = 0);
+ QItemModelSurfaceDataMapping(const QString &rowRole, const QString &columnRole,
+ const QString &valueRole, QObject *parent = 0);
+ QItemModelSurfaceDataMapping(const QString &rowRole, const QString &columnRole,
+ const QString &valueRole, const QStringList &rowCategories,
+ const QStringList &columnCategories, QObject *parent = 0);
+ virtual ~QItemModelSurfaceDataMapping();
+
+ 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);
+ QStringList rowCategories() const;
+ void setColumnCategories(const QStringList &categories);
+ QStringList columnCategories() const;
+
+ void setUseModelCategories(bool enable);
+ bool useModelCategories() const;
+ void setAutoRowCategories(bool enable);
+ bool autoRowCategories() const;
+ void setAutoColumnCategories(bool enable);
+ bool autoColumnCategories() const;
+
+ void remap(const QString &rowRole, const QString &columnRole,
+ const QString &valueRole, const QStringList &rowCategories,
+ const QStringList &columnCategories);
+
+ Q_INVOKABLE int rowCategoryIndex(const QString& category);
+ Q_INVOKABLE int columnCategoryIndex(const QString& category);
+
+protected:
+ QItemModelSurfaceDataMappingPrivate *dptr();
+ const QItemModelSurfaceDataMappingPrivate *dptrc() const;
+
+private:
+ Q_DISABLE_COPY(QItemModelSurfaceDataMapping)
+
+ friend class SurfaceItemModelHandler;
+};
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
+#endif
diff --git a/src/datavisualization/data/qitemmodelsurfacedatamapping_p.h b/src/datavisualization/data/qitemmodelsurfacedatamapping_p.h
new file mode 100644
index 00000000..9896f868
--- /dev/null
+++ b/src/datavisualization/data/qitemmodelsurfacedatamapping_p.h
@@ -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 QtDataVisualization 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 QtDataVisualization 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 "qitemmodelsurfacedatamapping.h"
+#include "qabstractdatamapping_p.h"
+
+#ifndef QITEMMODELSURFACEDATAMAPPING_P_H
+#define QITEMMODELSURFACEDATAMAPPING_P_H
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class QItemModelSurfaceDataMappingPrivate : public QAbstractDataMappingPrivate
+{
+ Q_OBJECT
+public:
+ QItemModelSurfaceDataMappingPrivate(QItemModelSurfaceDataMapping *q);
+ virtual ~QItemModelSurfaceDataMappingPrivate();
+
+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;
+
+ bool m_useModelCategories;
+ bool m_autoRowCategories;
+ bool m_autoColumnCategories;
+
+ friend class QItemModelSurfaceDataMapping;
+ friend class SurfaceItemModelHandler;
+};
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
+#endif
diff --git a/src/datavisualization/data/qitemmodelsurfacedataproxy.cpp b/src/datavisualization/data/qitemmodelsurfacedataproxy.cpp
new file mode 100644
index 00000000..f6403e9b
--- /dev/null
+++ b/src/datavisualization/data/qitemmodelsurfacedataproxy.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 QtDataVisualization 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 "qitemmodelsurfacedataproxy_p.h"
+#include "surfaceitemmodelhandler_p.h"
+#include <QTimer>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+// TODO: CHECK DOCUMENTATION!
+
+/*!
+ * \class QItemModelSurfaceDataProxy
+ * \inmodule QtDataVisualization
+ * \brief Proxy class for presenting data in item models with Q3DSurface.
+ * \since 1.0.0
+ *
+ * QItemModelSurfaceDataProxy allows you to use QAbstractItemModel derived models as a data source
+ * for Q3DSurface. It maps roles defined in QItemModelSurfaceDataMapping to roles in the model.
+ *
+ * Data is resolved asynchronously whenever the mapping or the model changes.
+ * QSurfaceDataProxy::arrayReset() is emitted when the data has been resolved.
+ *
+ * /sa {Qt Data Visualization Data Handling}
+ */
+
+/*!
+ * \qmltype ItemModelSurfaceDataProxy
+ * \inqmlmodule com.digia.QtDataVisualization 1.0
+ * \since com.digia.QtDataVisualization 1.0
+ * \ingroup datavisualization_qml
+ * \instantiates QItemModelSurfaceDataProxy
+ * \inherits SurfaceDataProxy
+ * \brief Proxy class for presenting data in item models with Surface3D.
+ *
+ * This type allows you to use AbstractItemModel derived models as a data source for Surface3D.
+ *
+ * Data is resolved asynchronously whenever the mapping or the model changes.
+ * QSurfaceDataProxy::arrayReset() is emitted when the data has been resolved.
+ *
+ * Usage example:
+ *
+ * \snippet doc_src_qmldatavisualization.cpp 9
+ *
+ * \sa SurfaceDataProxy, SurfaceDataMapping, {Qt Data Visualization Data Handling}
+ */
+
+/*!
+ * \qmlproperty list ItemModelSurfaceDataProxy::itemModel
+ * The item model.
+ */
+
+/*!
+ * \qmlproperty list ItemModelSurfaceDataProxy::activeMapping
+ * The active mapping. Modifying a mapping that is set to the proxy will trigger data set
+ * re-resolving.
+ */
+
+/*!
+ * Constructs QItemModelSurfaceDataProxy.
+ */
+QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy() :
+ QSurfaceDataProxy(new QItemModelSurfaceDataProxyPrivate(this))
+{
+}
+
+/*!
+ * Constructs QItemModelSurfaceDataProxy with \a itemModel and \a mapping. Does not take ownership
+ * of the model or the mapping, but does connect to them to listen for changes.
+ */
+QItemModelSurfaceDataProxy::QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel,
+ QItemModelSurfaceDataMapping *mapping) :
+ QSurfaceDataProxy(new QItemModelSurfaceDataProxyPrivate(this))
+{
+ dptr()->m_itemModelHandler->setItemModel(itemModel);
+ dptr()->m_itemModelHandler->setActiveMapping(mapping);
+}
+
+/*!
+ * Destroys QItemModelSurfaceDataProxy.
+ */
+QItemModelSurfaceDataProxy::~QItemModelSurfaceDataProxy()
+{
+}
+
+/*!
+ * \property QItemModelSurfaceDataProxy::itemModel
+ *
+ * Defines item model. Does not take ownership of the model, but does connect to it to listen for
+ * changes.
+ */
+void QItemModelSurfaceDataProxy::setItemModel(const QAbstractItemModel *itemModel)
+{
+ dptr()->m_itemModelHandler->setItemModel(itemModel);
+}
+
+const QAbstractItemModel *QItemModelSurfaceDataProxy::itemModel() const
+{
+ return dptrc()->m_itemModelHandler->itemModel();
+}
+
+/*!
+ * \property QItemModelSurfaceDataProxy::activeMapping
+ *
+ * Defines data mapping. Proxy takes ownership of the \a mapping.
+ * Modifying a mapping that is set to the proxy will trigger data set re-resolving.
+ */
+void QItemModelSurfaceDataProxy::setActiveMapping(QItemModelSurfaceDataMapping *mapping)
+{
+ dptr()->m_itemModelHandler->setActiveMapping(mapping);
+}
+
+QItemModelSurfaceDataMapping *QItemModelSurfaceDataProxy::activeMapping() const
+{
+ return static_cast<QItemModelSurfaceDataMapping *>(dptrc()->m_itemModelHandler->activeMapping());
+}
+
+/*!
+ * Transfers the ownership of the \a mapping to this proxy. The mapping is not taken to use yet.
+ * \sa setActiveMapping(), releaseMapping()
+ */
+void QItemModelSurfaceDataProxy::addMapping(QItemModelSurfaceDataMapping *mapping)
+{
+ dptr()->m_itemModelHandler->addMapping(mapping);
+}
+
+/*!
+ * Releases the ownership of the \a mapping back to the caller. If the mapping was the currently
+ * active one, no mapping remains active after this call.
+ */
+void QItemModelSurfaceDataProxy::releaseMapping(QItemModelSurfaceDataMapping *mapping)
+{
+ dptr()->m_itemModelHandler->releaseMapping(mapping);
+}
+
+/*!
+ * \return list of mappings owned by the proxy.
+ */
+QList<QItemModelSurfaceDataMapping *> QItemModelSurfaceDataProxy::mappings() const
+{
+ QList<QItemModelSurfaceDataMapping *> retList;
+ QList<QAbstractDataMapping *> abstractList = dptrc()->m_itemModelHandler->mappings();
+ foreach (QAbstractDataMapping *mapping, abstractList)
+ retList.append(static_cast<QItemModelSurfaceDataMapping *>(mapping));
+
+ return retList;
+}
+
+/*!
+ * \internal
+ */
+QItemModelSurfaceDataProxyPrivate *QItemModelSurfaceDataProxy::dptr()
+{
+ return static_cast<QItemModelSurfaceDataProxyPrivate *>(d_ptr.data());
+}
+
+/*!
+ * \internal
+ */
+const QItemModelSurfaceDataProxyPrivate *QItemModelSurfaceDataProxy::dptrc() const
+{
+ return static_cast<const QItemModelSurfaceDataProxyPrivate *>(d_ptr.data());
+}
+
+// QItemModelSurfaceDataProxyPrivate
+
+QItemModelSurfaceDataProxyPrivate::QItemModelSurfaceDataProxyPrivate(QItemModelSurfaceDataProxy *q)
+ : QSurfaceDataProxyPrivate(q),
+ m_itemModelHandler(new SurfaceItemModelHandler(q))
+{
+}
+
+QItemModelSurfaceDataProxyPrivate::~QItemModelSurfaceDataProxyPrivate()
+{
+ delete m_itemModelHandler;
+}
+
+QItemModelSurfaceDataProxy *QItemModelSurfaceDataProxyPrivate::qptr()
+{
+ return static_cast<QItemModelSurfaceDataProxy *>(q_ptr);
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualization/data/qitemmodelsurfacedataproxy.h b/src/datavisualization/data/qitemmodelsurfacedataproxy.h
new file mode 100644
index 00000000..080bf54b
--- /dev/null
+++ b/src/datavisualization/data/qitemmodelsurfacedataproxy.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 QtDataVisualization 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 QITEMMODELSURFACEDATAPROXY_H
+#define QITEMMODELSURFACEDATAPROXY_H
+
+#include <QtDataVisualization/qsurfacedataproxy.h>
+#include <QtDataVisualization/qitemmodelsurfacedatamapping.h>
+#include <QAbstractItemModel>
+#include <QStringList>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class QItemModelSurfaceDataProxyPrivate;
+
+class QT_DATAVISUALIZATION_EXPORT QItemModelSurfaceDataProxy : public QSurfaceDataProxy
+{
+ Q_OBJECT
+ Q_PROPERTY(const QAbstractItemModel* itemModel READ itemModel WRITE setItemModel)
+ Q_PROPERTY(QItemModelSurfaceDataMapping* activeMapping READ activeMapping WRITE setActiveMapping)
+
+public:
+ explicit QItemModelSurfaceDataProxy();
+ explicit QItemModelSurfaceDataProxy(const QAbstractItemModel *itemModel,
+ QItemModelSurfaceDataMapping *mapping);
+ virtual ~QItemModelSurfaceDataProxy();
+
+ void setItemModel(const QAbstractItemModel *itemModel);
+ const QAbstractItemModel *itemModel() const;
+
+ void setActiveMapping(QItemModelSurfaceDataMapping *mapping);
+ QItemModelSurfaceDataMapping *activeMapping() const;
+ void addMapping(QItemModelSurfaceDataMapping *mapping);
+ void releaseMapping(QItemModelSurfaceDataMapping *mapping);
+ QList<QItemModelSurfaceDataMapping *> mappings() const;
+
+protected:
+ QItemModelSurfaceDataProxyPrivate *dptr();
+ const QItemModelSurfaceDataProxyPrivate *dptrc() const;
+
+private:
+ Q_DISABLE_COPY(QItemModelSurfaceDataProxy)
+};
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
+#endif
diff --git a/src/datavisualization/data/qitemmodelsurfacedataproxy_p.h b/src/datavisualization/data/qitemmodelsurfacedataproxy_p.h
new file mode 100644
index 00000000..ff9d13de
--- /dev/null
+++ b/src/datavisualization/data/qitemmodelsurfacedataproxy_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 QtDataVisualization 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 QtDataVisualization 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 QITEMMODELSURFACEDATAPROXY_P_H
+#define QITEMMODELSURFACEDATAPROXY_P_H
+
+#include "qitemmodelsurfacedataproxy.h"
+#include "qsurfacedataproxy_p.h"
+#include <QPointer>
+#include <QTimer>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class SurfaceItemModelHandler;
+
+class QItemModelSurfaceDataProxyPrivate : public QSurfaceDataProxyPrivate
+{
+ Q_OBJECT
+public:
+ QItemModelSurfaceDataProxyPrivate(QItemModelSurfaceDataProxy *q);
+ virtual ~QItemModelSurfaceDataProxyPrivate();
+
+private:
+ QItemModelSurfaceDataProxy *qptr();
+
+ SurfaceItemModelHandler *m_itemModelHandler;
+
+ friend class QItemModelSurfaceDataProxy;
+};
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/data/qscatterdataitem.cpp b/src/datavisualization/data/qscatterdataitem.cpp
index e2580339..055a9dad 100644
--- a/src/datavis3d/data/qscatterdataitem.cpp
+++ b/src/datavisualization/data/qscatterdataitem.cpp
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -18,11 +18,11 @@
#include "qscatterdataitem_p.h"
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
/*!
* \class QScatterDataItem
- * \inmodule QtDataVis3D
+ * \inmodule QtDataVisualization
* \brief The QScatterDataItem class provides a container for resolved data to be added to scatter
* graphs.
* \since 1.0.0
@@ -30,7 +30,7 @@ QT_DATAVIS3D_BEGIN_NAMESPACE
* 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}
+ * \sa QScatterDataProxy, {Qt Data Visualization C++ Classes}
*/
/*!
@@ -42,12 +42,18 @@ QScatterDataItem::QScatterDataItem()
{
}
+/*!
+ * Constructs QScatterDataItem with \a position.
+ */
QScatterDataItem::QScatterDataItem(const QVector3D &position)
: d_ptr(0),
m_position(position)
{
}
+/*!
+ * Constructs a copy of \a other.
+ */
QScatterDataItem::QScatterDataItem(const QScatterDataItem &other)
{
operator=(other);
@@ -60,6 +66,9 @@ QScatterDataItem::~QScatterDataItem()
{
}
+/*!
+ * Assigns a copy of \a other to this object.
+ */
QScatterDataItem &QScatterDataItem::operator=(const QScatterDataItem &other)
{
m_position = other.m_position;
@@ -74,15 +83,45 @@ QScatterDataItem &QScatterDataItem::operator=(const QScatterDataItem &other)
return *this;
}
-void QScatterDataItem::setPosition(const QVector3D &position)
-{
- m_position = position;
-}
+/*!
+ * \fn void QScatterDataItem::setPosition(const QVector3D &position)
+ * Sets \a position to this data item.
+ */
-const QVector3D &QScatterDataItem::position() const
-{
- return m_position;
-}
+/*!
+ * \fn QVector3D QScatterDataItem::position() const
+ * \return position of this data item.
+ */
+
+/*!
+ * \fn void QScatterDataItem::setX(float value)
+ * Sets the X component of the item position to the \a value.
+ */
+
+/*!
+ * \fn void QScatterDataItem::setY(float value)
+ * Sets the Y component of the item position to the \a value.
+ */
+
+/*!
+ * \fn void QScatterDataItem::setZ(float value)
+ * Sets the Z component of the item position to the \a value.
+ */
+
+/*!
+ * \fn float QScatterDataItem::x() const
+ * \return the X component of the position of this data item.
+ */
+
+/*!
+ * \fn float QScatterDataItem::y() const
+ * \return the Y component of the position of this data item.
+ */
+
+/*!
+ * \fn float QScatterDataItem::z() const
+ * \return the Z component of the position of this data item.
+ */
//void QScatterDataItem::setSize(qreal size)
//{
@@ -94,6 +133,9 @@ const QVector3D &QScatterDataItem::position() const
// return m_size;
//}
+/*!
+ * \internal
+ */
void QScatterDataItem::createExtraData()
{
if (!d_ptr)
@@ -108,4 +150,4 @@ QScatterDataItemPrivate::~QScatterDataItemPrivate()
{
}
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavis3d/data/qscatterdataitem.h b/src/datavisualization/data/qscatterdataitem.h
index 82383ae6..29154259 100644
--- a/src/datavis3d/data/qscatterdataitem.h
+++ b/src/datavisualization/data/qscatterdataitem.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -19,14 +19,14 @@
#ifndef QSCATTERDATAITEM_H
#define QSCATTERDATAITEM_H
-#include <QtDataVis3D/qdatavis3denums.h>
+#include <QtDataVisualization/qdatavisualizationenums.h>
#include <QVector3D>
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
class QScatterDataItemPrivate;
-class QT_DATAVIS3D_EXPORT QScatterDataItem
+class QT_DATAVISUALIZATION_EXPORT QScatterDataItem
{
public:
QScatterDataItem();
@@ -36,8 +36,14 @@ public:
QScatterDataItem &operator=(const QScatterDataItem &other);
- void setPosition(const QVector3D &position);
- const QVector3D &position() const;
+ inline void setPosition(const QVector3D &position) { m_position = position; }
+ inline QVector3D position() const { return m_position; }
+ inline void setX(float value) { m_position.setX(value); }
+ inline void setY(float value) { m_position.setY(value); }
+ inline void setZ(float value) { m_position.setZ(value); }
+ inline float x() const { return m_position.x(); }
+ inline float y() const { return m_position.y(); }
+ inline float z() const { return m_position.z(); }
//void setSize(qreal size);
//qreal size() const;
@@ -52,6 +58,6 @@ private:
//qreal m_size;
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif
diff --git a/src/datavis3d/data/qscatterdataitem_p.h b/src/datavisualization/data/qscatterdataitem_p.h
index 3718a185..acc67347 100644
--- a/src/datavis3d/data/qscatterdataitem_p.h
+++ b/src/datavisualization/data/qscatterdataitem_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -29,10 +29,10 @@
#ifndef QSCATTERDATAITEM_P_H
#define QSCATTERDATAITEM_P_H
-#include "datavis3dglobal_p.h"
+#include "datavisualizationglobal_p.h"
#include "qscatterdataitem.h"
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
class QScatterDataItemPrivate
{
@@ -46,6 +46,6 @@ protected:
friend class QScatterDataItem;
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif
diff --git a/src/datavisualization/data/qscatterdataproxy.cpp b/src/datavisualization/data/qscatterdataproxy.cpp
new file mode 100644
index 00000000..4d83da8d
--- /dev/null
+++ b/src/datavisualization/data/qscatterdataproxy.cpp
@@ -0,0 +1,367 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+/*!
+ * \class QScatterDataProxy
+ * \inmodule QtDataVisualization
+ * \brief Base proxy class for Q3DScatter.
+ * \since 1.0.0
+ *
+ * QScatterDataProxy handles adding, inserting, changing and removing data items.
+ *
+ * QScatterDataProxy takes ownership of all QScatterDataArrays and QScatterDataItems passed to it.
+ *
+ * QScatterDataProxy supports the following format tags for QAbstractDataProxy::setItemLabelFormat():
+ * \table
+ * \row
+ * \li @xTitle \li Title from X axis
+ * \row
+ * \li @yTitle \li Title from Y axis
+ * \row
+ * \li @zTitle \li Title from Z axis
+ * \row
+ * \li @xLabel \li Item value formatted using the same format the X axis attached to the graph uses,
+ * see \l{Q3DValueAxis::setLabelFormat()} for more information.
+ * \row
+ * \li @yLabel \li Item value formatted using the same format the Y axis attached to the graph uses,
+ * see \l{Q3DValueAxis::setLabelFormat()} for more information.
+ * \row
+ * \li @zLabel \li Item value formatted using the same format the Z axis attached to the graph uses,
+ * see \l{Q3DValueAxis::setLabelFormat()} for more information.
+ * \endtable
+ *
+ * For example:
+ * \snippet doc_src_qtdatavisualization.cpp 2
+ *
+ * /sa {Qt Data Visualization Data Handling}
+ */
+
+/*!
+ * \qmltype ScatterDataProxy
+ * \inqmlmodule com.digia.QtDataVisualization 1.0
+ * \since com.digia.QtDataVisualization 1.0
+ * \ingroup datavisualization_qml
+ * \instantiates QScatterDataProxy
+ * \inherits AbstractDataProxy
+ * \brief Base proxy class for Scatter3D.
+ *
+ * This type handles adding, inserting, changing and removing data items.
+ *
+ * This type is uncreatable, but contains properties that are exposed via subtypes.
+ *
+ * For more complete description, see QScatterDataProxy.
+ *
+ * \sa ItemModelScatterDataProxy, {Qt Data Visualization Data Handling}
+ */
+
+/*!
+ * \qmlproperty int ScatterDataProxy::itemCount
+ * Item count in the array.
+ */
+
+/*!
+ * Constructs QScatterDataProxy with the given \a parent.
+ */
+QScatterDataProxy::QScatterDataProxy(QObject *parent) :
+ QAbstractDataProxy(new QScatterDataProxyPrivate(this), parent)
+{
+}
+
+/*!
+ * \internal
+ */
+QScatterDataProxy::QScatterDataProxy(QScatterDataProxyPrivate *d, QObject *parent) :
+ QAbstractDataProxy(d, parent)
+{
+}
+
+/*!
+ * Destroys QScatterDataProxy.
+ */
+QScatterDataProxy::~QScatterDataProxy()
+{
+}
+
+/*!
+ * Takes ownership of the \a newArray. Clears the existing array and if the \a newArray is
+ * different than the existing array. If it's the same array, this just triggers arrayReset()
+ * signal.
+ * Passing null array deletes the old array and creates a new empty array.
+ */
+void QScatterDataProxy::resetArray(QScatterDataArray *newArray)
+{
+ if (dptr()->m_dataArray != newArray)
+ dptr()->resetArray(newArray);
+
+ emit arrayReset();
+}
+
+/*!
+ * Changes a single item at \a index with \a item.
+ */
+void QScatterDataProxy::setItem(int index, const QScatterDataItem &item)
+{
+ dptr()->setItem(index, item);
+ emit itemsChanged(index, 1);
+}
+
+/*!
+ * Changes items starting from \a index with \a items.
+ */
+void QScatterDataProxy::setItems(int index, const QScatterDataArray &items)
+{
+ dptr()->setItems(index, items);
+ emit itemsChanged(index, items.size());
+}
+
+/*!
+ * Adds a single \a item to the end of the array.
+ *
+ * \return index of the added item.
+ */
+int QScatterDataProxy::addItem(const QScatterDataItem &item)
+{
+ int addIndex = dptr()->addItem(item);
+ emit itemsAdded(addIndex, 1);
+ return addIndex;
+}
+
+/*!
+ * Adds \a items to the end of the array.
+ *
+ * \return index of the first added item.
+ */
+int QScatterDataProxy::addItems(const QScatterDataArray &items)
+{
+ int addIndex = dptr()->addItems(items);
+ emit itemsAdded(addIndex, items.size());
+ return addIndex;
+}
+
+/*!
+ * Inserts a single \a item to \a index. If index is equal to data array size, item is added to
+ * the array.
+ */
+void QScatterDataProxy::insertItem(int index, const QScatterDataItem &item)
+{
+ dptr()->insertItem(index, item);
+ emit itemsInserted(index, 1);
+}
+
+/*!
+ * Inserts \a items to \a index. If index is equal to data array size, items are added to the array.
+ */
+void QScatterDataProxy::insertItems(int index, const QScatterDataArray &items)
+{
+ dptr()->insertItems(index, items);
+ emit itemsInserted(index, items.size());
+}
+
+/*!
+ * Removes \a removeCount items starting from \a index. Attempting to remove items past the end of
+ * the array does nothing.
+ */
+void QScatterDataProxy::removeItems(int index, int removeCount)
+{
+ dptr()->removeItems(index, removeCount);
+ emit itemsRemoved(index, removeCount);
+}
+
+/*!
+ * \property QScatterDataProxy::itemCount
+ *
+ * \return item count in the array.
+ */
+int QScatterDataProxy::itemCount() const
+{
+ return dptrc()->m_dataArray->size();
+}
+
+/*!
+ * \return pointer to the data array.
+ */
+const QScatterDataArray *QScatterDataProxy::array() const
+{
+ return dptrc()->m_dataArray;
+}
+
+/*!
+ * \return pointer to the item at \a index. It is guaranteed to be valid only until next call
+ * that modifies data.
+ */
+const QScatterDataItem *QScatterDataProxy::itemAt(int index) const
+{
+ return &dptrc()->m_dataArray->at(index);
+}
+
+/*!
+ * \internal
+ */
+QScatterDataProxyPrivate *QScatterDataProxy::dptr()
+{
+ return static_cast<QScatterDataProxyPrivate *>(d_ptr.data());
+}
+
+/*!
+ * \internal
+ */
+const QScatterDataProxyPrivate *QScatterDataProxy::dptrc() const
+{
+ return static_cast<const QScatterDataProxyPrivate *>(d_ptr.data());
+}
+
+/*!
+ * \fn void QScatterDataProxy::arrayReset()
+ *
+ * Emitted when data array is reset.
+ * If you change the whole array contents without calling resetArray(), you need to
+ * emit this signal yourself or the graph won't get updated.
+ */
+
+/*!
+ * \fn void QScatterDataProxy::itemsAdded(int startIndex, int count)
+ *
+ * Emitted when items have been added. Provides \a startIndex and \a count of items added.
+ * If you add items directly to the array without calling addItem() or addItems(), you
+ * need to emit this signal yourself or the graph won't get updated.
+ */
+
+/*!
+ * \fn void QScatterDataProxy::itemsChanged(int startIndex, int count)
+ *
+ * Emitted when items have changed. Provides \a startIndex and \a count of changed items.
+ * If you change items directly in the array without calling setItem() or setItems(), you
+ * need to emit this signal yourself or the graph won't get updated.
+ */
+
+/*!
+ * \fn void QScatterDataProxy::itemsRemoved(int startIndex, int count)
+ *
+ * Emitted when items have been removed. Provides \a startIndex and \a count of items removed.
+ * Index may be over current array size if removed from end.
+ * If you remove items directly from the array without calling removeItems(), you
+ * need to emit this signal yourself or the graph won't get updated.
+ */
+
+/*!
+ * \fn void QScatterDataProxy::itemsInserted(int startIndex, int count)
+ *
+ * Emitted when items have been inserted. Provides \a startIndex and \a count of inserted items.
+ * If you insert items directly into the array without calling insertItem() or insertItems(), you
+ * need to emit this signal yourself or the graph won't get updated.
+ */
+
+// QScatterDataProxyPrivate
+
+QScatterDataProxyPrivate::QScatterDataProxyPrivate(QScatterDataProxy *q)
+ : QAbstractDataProxyPrivate(q, QAbstractDataProxy::DataTypeScatter),
+ m_dataArray(new QScatterDataArray)
+{
+ m_itemLabelFormat = QStringLiteral("(@xLabel, @yLabel, @zLabel)");
+}
+
+QScatterDataProxyPrivate::~QScatterDataProxyPrivate()
+{
+ m_dataArray->clear();
+ delete m_dataArray;
+}
+
+void QScatterDataProxyPrivate::resetArray(QScatterDataArray *newArray)
+{
+ if (!newArray)
+ newArray = new QScatterDataArray;
+
+ if (newArray != m_dataArray) {
+ m_dataArray->clear();
+ delete m_dataArray;
+ m_dataArray = newArray;
+ }
+}
+
+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);
+ }
+ return limits;
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavis3d/data/qscatterdataproxy.h b/src/datavisualization/data/qscatterdataproxy.h
index 9e139c00..178bc900 100644
--- a/src/datavis3d/data/qscatterdataproxy.h
+++ b/src/datavisualization/data/qscatterdataproxy.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -19,60 +19,59 @@
#ifndef QSCATTERDATAPROXY_H
#define QSCATTERDATAPROXY_H
-#include <QtDataVis3D/qabstractdataproxy.h>
-#include <QtDataVis3D/qscatterdataitem.h>
+#include <QtDataVisualization/qabstractdataproxy.h>
+#include <QtDataVisualization/qscatterdataitem.h>
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
typedef QVector<QScatterDataItem> QScatterDataArray;
class QScatterDataProxyPrivate;
-class QT_DATAVIS3D_EXPORT QScatterDataProxy : public QAbstractDataProxy
+class QT_DATAVISUALIZATION_EXPORT QScatterDataProxy : public QAbstractDataProxy
{
Q_OBJECT
+ Q_PROPERTY(int itemCount READ itemCount)
+
public:
- explicit QScatterDataProxy();
- explicit QScatterDataProxy(QScatterDataProxyPrivate *d);
+ explicit QScatterDataProxy(QObject *parent = 0);
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.
+ // TODO: Replace first part of class description in docs with this once all TODOs are done:
+ /*
+ * QScatterDataProxy handles adding, inserting, changing and removing data items.
+ * 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
+ int addItem(const QScatterDataItem &item);
+ int addItems(const QScatterDataArray &items);
- // 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 itemsRemoved(int startIndex, int count);
void itemsInserted(int startIndex, int count);
protected:
+ explicit QScatterDataProxy(QScatterDataProxyPrivate *d, QObject *parent = 0);
QScatterDataProxyPrivate *dptr();
const QScatterDataProxyPrivate *dptrc() const;
@@ -82,6 +81,6 @@ private:
friend class Scatter3DController;
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif
diff --git a/src/datavis3d/data/qscatterdataproxy_p.h b/src/datavisualization/data/qscatterdataproxy_p.h
index 526845fd..9920e3a7 100644
--- a/src/datavis3d/data/qscatterdataproxy_p.h
+++ b/src/datavisualization/data/qscatterdataproxy_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -33,7 +33,7 @@
#include "qabstractdataproxy_p.h"
#include "qscatterdataitem.h"
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
class QScatterDataProxyPrivate : public QAbstractDataProxyPrivate
{
@@ -42,7 +42,7 @@ public:
QScatterDataProxyPrivate(QScatterDataProxy *q);
virtual ~QScatterDataProxyPrivate();
- bool resetArray(QScatterDataArray *newArray);
+ void resetArray(QScatterDataArray *newArray);
void setItem(int index, const QScatterDataItem &item);
void setItems(int index, const QScatterDataArray &items);
int addItem(const QScatterDataItem &item);
@@ -55,11 +55,10 @@ public:
private:
QScatterDataArray *m_dataArray;
- QString m_itemLabelFormat;
friend class QScatterDataProxy;
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif // QBARDATAPROXY_P_H
diff --git a/src/datavisualization/data/qsurfacedataitem.cpp b/src/datavisualization/data/qsurfacedataitem.cpp
new file mode 100644
index 00000000..19f8f347
--- /dev/null
+++ b/src/datavisualization/data/qsurfacedataitem.cpp
@@ -0,0 +1,143 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 "qsurfacedataitem_p.h"
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+/*!
+ * \class QSurfaceDataItem
+ * \inmodule QtDataVisualization
+ * \brief The QSurfaceDataItem class provides a container for resolved data to be added to surface
+ * graphs.
+ * \since 1.0.0
+ *
+ * A QSurfaceDataItem holds data for a single vertex in surface graph.
+ * Surface data proxies parse data into QSurfaceDataItem instances for visualizing.
+ *
+ * \sa QSurfaceDataProxy, {Qt Data Visualization C++ Classes}
+ */
+
+/*!
+ * Constructs QSurfaceDataItem.
+ */
+QSurfaceDataItem::QSurfaceDataItem()
+ : d_ptr(0) // private data doesn't exist by default (optimization)
+
+{
+}
+
+/*!
+ * Constructs QSurfaceDataItem with \a position.
+ */
+QSurfaceDataItem::QSurfaceDataItem(const QVector3D &position)
+ : d_ptr(0),
+ m_position(position)
+{
+}
+
+/*!
+ * Constructs a copy of \a other.
+ */
+QSurfaceDataItem::QSurfaceDataItem(const QSurfaceDataItem &other)
+{
+ operator=(other);
+}
+
+/*!
+ * Destroys QSurfaceDataItem.
+ */
+QSurfaceDataItem::~QSurfaceDataItem()
+{
+}
+
+/*!
+ * Assigns a copy of \a other to this object.
+ */
+QSurfaceDataItem &QSurfaceDataItem::operator=(const QSurfaceDataItem &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;
+}
+
+/*!
+ * \fn void QSurfaceDataItem::setPosition(const QVector3D &position)
+ * Sets \a position to this data item.
+ */
+
+/*!
+ * \fn QVector3D QSurfaceDataItem::position() const
+ * \return position of this data item.
+ */
+
+/*!
+ * \fn void QSurfaceDataItem::setX(float value)
+ * Sets the X component of the item position to the \a value.
+ */
+
+/*!
+ * \fn void QSurfaceDataItem::setY(float value)
+ * Sets the Y component of the item position to the \a value.
+ */
+
+/*!
+ * \fn void QSurfaceDataItem::setZ(float value)
+ * Sets the Z component of the item position to the \a value.
+ */
+
+/*!
+ * \fn float QSurfaceDataItem::x() const
+ * \return the X component of the position of this data item.
+ */
+
+/*!
+ * \fn float QSurfaceDataItem::y() const
+ * \return the Y component of the position of this data item.
+ */
+
+/*!
+ * \fn float QSurfaceDataItem::z() const
+ * \return the Z component of the position of this data item.
+ */
+
+/*!
+ * \internal
+ */
+void QSurfaceDataItem::createExtraData()
+{
+ if (!d_ptr)
+ d_ptr = new QSurfaceDataItemPrivate;
+}
+
+QSurfaceDataItemPrivate::QSurfaceDataItemPrivate()
+{
+}
+
+QSurfaceDataItemPrivate::~QSurfaceDataItemPrivate()
+{
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualization/data/qsurfacedataitem.h b/src/datavisualization/data/qsurfacedataitem.h
new file mode 100644
index 00000000..dbc849d3
--- /dev/null
+++ b/src/datavisualization/data/qsurfacedataitem.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 QtDataVisualization 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 QSURFACEDATAITEM_H
+#define QSURFACEDATAITEM_H
+
+#include <QtDataVisualization/qdatavisualizationenums.h>
+#include <QVector3D>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class QSurfaceDataItemPrivate;
+
+class QT_DATAVISUALIZATION_EXPORT QSurfaceDataItem
+{
+public:
+ QSurfaceDataItem();
+ QSurfaceDataItem(const QVector3D &position);
+ QSurfaceDataItem(const QSurfaceDataItem &other);
+ ~QSurfaceDataItem();
+
+ QSurfaceDataItem &operator=(const QSurfaceDataItem &other);
+
+ inline void setPosition(const QVector3D &position) { m_position = position; }
+ inline QVector3D position() const { return m_position; }
+ inline void setX(float value) { m_position.setX(value); }
+ inline void setY(float value) { m_position.setY(value); }
+ inline void setZ(float value) { m_position.setZ(value); }
+ inline float x() const { return m_position.x(); }
+ inline float y() const { return m_position.y(); }
+ inline float z() const { return m_position.z(); }
+
+protected:
+ virtual void createExtraData();
+
+ QSurfaceDataItemPrivate *d_ptr;
+
+private:
+ QVector3D m_position;
+};
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/data/qmapdataitem_p.h b/src/datavisualization/data/qsurfacedataitem_p.h
index 2926e3ef..d13679a8 100644
--- a/src/datavis3d/data/qmapdataitem_p.h
+++ b/src/datavisualization/data/qsurfacedataitem_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,33 +20,32 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization 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
+#ifndef QSURFACEDATAITEM_P_H
+#define QSURFACEDATAITEM_P_H
-#include "datavis3dglobal_p.h"
-#include "qmapdataitem.h"
-#include "qbardataitem_p.h"
+#include "datavisualizationglobal_p.h"
+#include "qsurfacedataitem.h"
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
-class QMapDataItemPrivate : public QBarDataItemPrivate
+class QSurfaceDataItemPrivate
{
public:
- QMapDataItemPrivate();
- virtual ~QMapDataItemPrivate();
+ QSurfaceDataItemPrivate();
+ virtual ~QSurfaceDataItemPrivate();
- // TODO stores other data for map items besides position
+ // TODO stores other data for surface items besides position
protected:
- friend class QMapDataItem;
+ friend class QSurfaceDataItem;
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif
diff --git a/src/datavisualization/data/qsurfacedataproxy.cpp b/src/datavisualization/data/qsurfacedataproxy.cpp
new file mode 100644
index 00000000..72f33de7
--- /dev/null
+++ b/src/datavisualization/data/qsurfacedataproxy.cpp
@@ -0,0 +1,289 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 "qsurfacedataproxy.h"
+#include "qsurfacedataproxy_p.h"
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+/*!
+ * \class QSurfaceDataProxy
+ * \inmodule QtDataVisualization
+ * \brief Base proxy class for Q3DSurface.
+ * \since 1.0.0
+ *
+ * QSurfaceDataProxy takes care of surface related data handling. The QSurfaceDataProxy handles the data
+ * in rows and for this it provides two auxiliary typedefs. QSurfaceDataArray is a QList for
+ * controlling the rows. For rows there is a QVector QSurfaceDataRow which contains QSurfaceDataItem
+ * objects. See Q3DSurface documentation and basic sample code there how to feed the data for the
+ * QSurfaceDataProxy.
+ *
+ * All rows must have same number of items.
+ *
+ * When determining what rows and columns are visible, the first item in each row and the first item in
+ * each column determine if the whole row or column is visible, even if other items in the row or column
+ * individually have different X- or Z-coordinates.
+ *
+ * \note Surfaces with less than two rows or columns are not considered valid surfaces and will
+ * not get rendered.
+ *
+ * QSurfaceDataProxy supports the following format tags for QAbstractDataProxy::setItemLabelFormat():
+ * \table
+ * \row
+ * \li @xTitle \li Title from X axis
+ * \row
+ * \li @yTitle \li Title from Y axis
+ * \row
+ * \li @zTitle \li Title from Z axis
+ * \row
+ * \li @xLabel \li Item value formatted using the same format as the X axis attached to the graph uses,
+ * see \l{Q3DValueAxis::setLabelFormat()} for more information.
+ * \row
+ * \li @yLabel \li Item value formatted using the same format as the Y axis attached to the graph uses,
+ * see \l{Q3DValueAxis::setLabelFormat()} for more information.
+ * \row
+ * \li @zLabel \li Item value formatted using the same format as the Z axis attached to the graph uses,
+ * see \l{Q3DValueAxis::setLabelFormat()} for more information.
+ * \endtable
+ *
+ * \sa {Qt Data Visualization Data Handling}
+ */
+
+/*!
+ * \qmltype SurfaceDataProxy
+ * \inqmlmodule com.digia.QtDataVisualization 1.0
+ * \since com.digia.QtDataVisualization 1.0
+ * \ingroup datavisualization_qml
+ * \instantiates QSurfaceDataProxy
+ * \inherits AbstractDataProxy
+ * \brief Base proxy class for Surface3D.
+ *
+ * This type handles surface data items. The data is arranged into rows and columns, and all rows must have
+ * the same number of columns.
+ *
+ * This type is uncreatable, but contains properties that are exposed via subtypes.
+ *
+ * For more complete description, see QSurfaceDataProxy.
+ *
+ * \sa ItemModelSurfaceDataProxy, {Qt Data Visualization Data Handling}
+ */
+
+/*!
+ * \qmlproperty int SurfaceDataProxy::rowCount
+ * Number of the rows in the array.
+ */
+
+/*!
+ * \qmlproperty int SurfaceDataProxy::columnCount
+ * Number of the columns in the array.
+ */
+
+/*!
+ * Constructs QSurfaceDataProxy with the given \a parent.
+ */
+QSurfaceDataProxy::QSurfaceDataProxy(QObject *parent) :
+ QAbstractDataProxy(new QSurfaceDataProxyPrivate(this), parent)
+{
+}
+
+/*!
+ * \internal
+ */
+QSurfaceDataProxy::QSurfaceDataProxy(QSurfaceDataProxyPrivate *d, QObject *parent) :
+ QAbstractDataProxy(d, parent)
+{
+}
+
+/*!
+ * Destroys QSurfaceDataProxy.
+ */
+QSurfaceDataProxy::~QSurfaceDataProxy()
+{
+}
+
+/*!
+ * Takes ownership of the \a newArray. Clears the existing array and if the \a newArray is
+ * different than the existing array. If it's the same array, this just triggers arrayReset()
+ * signal.
+ * Passing null array deletes the old array and creates a new empty array.
+ * All rows in \a newArray must be of same length.
+ */
+void QSurfaceDataProxy::resetArray(QSurfaceDataArray *newArray)
+{
+ if (dptr()->m_dataArray != newArray) {
+ dptr()->resetArray(newArray);
+ }
+ emit arrayReset();
+}
+
+/*!
+ * \return pointer to the data array.
+ */
+const QSurfaceDataArray *QSurfaceDataProxy::array() const
+{
+ return dptrc()->m_dataArray;
+}
+
+/*!
+ * \property QSurfaceDataProxy::rowCount
+ *
+ * \return number of rows in the data.
+ */
+int QSurfaceDataProxy::rowCount() const
+{
+ return dptrc()->m_dataArray->size();
+}
+
+/*!
+ * \property QSurfaceDataProxy::columnCount
+ *
+ * \return number of items in the columns.
+ */
+int QSurfaceDataProxy::columnCount() const
+{
+ if (dptrc()->m_dataArray->size() > 0)
+ return dptrc()->m_dataArray->at(0)->size();
+ else
+ return 0;
+}
+
+/*!
+ * \return pointer to the item at \a index. It is guaranteed to be valid only until next call that
+ * modifies data.
+ */
+const QSurfaceDataItem *QSurfaceDataProxy::itemAt(int index) const
+{
+ return &dptrc()->m_dataArray->at(index)->at(2);
+}
+
+/*!
+ * \internal
+ */
+QSurfaceDataProxyPrivate *QSurfaceDataProxy::dptr()
+{
+ return static_cast<QSurfaceDataProxyPrivate *>(d_ptr.data());
+}
+
+/*!
+ * \internal
+ */
+const QSurfaceDataProxyPrivate *QSurfaceDataProxy::dptrc() const
+{
+ return static_cast<const QSurfaceDataProxyPrivate *>(d_ptr.data());
+}
+
+/*!
+ * \fn void QSurfaceDataProxy::arrayReset()
+ *
+ * Emitted when data array is reset.
+ * If you change the whole array contents without calling resetArray(), you need to
+ * emit this signal yourself or the graph won't get updated.
+ */
+
+//
+// QSurfaceDataProxyPrivate
+//
+
+QSurfaceDataProxyPrivate::QSurfaceDataProxyPrivate(QSurfaceDataProxy *q)
+ : QAbstractDataProxyPrivate(q, QAbstractDataProxy::DataTypeSurface),
+ m_dataArray(new QSurfaceDataArray)
+{
+ m_itemLabelFormat = QStringLiteral("@yLabel (@xLabel, @zLabel)");
+}
+
+QSurfaceDataProxyPrivate::~QSurfaceDataProxyPrivate()
+{
+ clearArray();
+}
+
+void QSurfaceDataProxyPrivate::resetArray(QSurfaceDataArray *newArray)
+{
+ if (!newArray)
+ newArray = new QSurfaceDataArray;
+
+ if (newArray != m_dataArray) {
+ clearArray();
+ m_dataArray = newArray;
+ }
+}
+
+QSurfaceDataProxy *QSurfaceDataProxyPrivate::qptr()
+{
+ return static_cast<QSurfaceDataProxy *>(q_ptr);
+}
+
+void QSurfaceDataProxyPrivate::limitValues(QVector3D &minValues, QVector3D &maxValues)
+{
+ qreal min = 0.0;
+ qreal max = 0.0;
+
+ int rows = m_dataArray->size();
+ int columns = 0;
+ if (rows)
+ columns = m_dataArray->at(0)->size();
+
+ if (rows && columns) {
+ min = m_dataArray->at(0)->at(0).y();
+ max = m_dataArray->at(0)->at(0).y();
+ }
+
+ for (int i = 0; i < rows; i++) {
+ QSurfaceDataRow *row = m_dataArray->at(i);
+ if (row) {
+ for (int j = 0; j < columns; j++) {
+ qreal itemValue = m_dataArray->at(i)->at(j).y();
+ if (min > itemValue)
+ min = itemValue;
+ if (max < itemValue)
+ max = itemValue;
+ }
+ }
+ }
+
+ minValues.setY(min);
+ maxValues.setY(max);
+ if (columns) {
+ minValues.setX(m_dataArray->at(0)->at(0).x());
+ minValues.setZ(m_dataArray->at(0)->at(0).z());
+ maxValues.setX(m_dataArray->at(0)->last().x());
+ maxValues.setZ(m_dataArray->last()->at(0).z());
+ } else {
+ minValues.setX(0.0f);
+ minValues.setZ(0.0f);
+ maxValues.setX(0.0f);
+ maxValues.setZ(0.0f);
+ }
+}
+
+void QSurfaceDataProxyPrivate::clearRow(int rowIndex)
+{
+ if (m_dataArray->at(rowIndex)) {
+ delete m_dataArray->at(rowIndex);
+ (*m_dataArray)[rowIndex] = 0;
+ }
+}
+
+void QSurfaceDataProxyPrivate::clearArray()
+{
+ for (int i = 0; i < m_dataArray->size(); i++)
+ clearRow(i);
+ m_dataArray->clear();
+ delete m_dataArray;
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualization/data/qsurfacedataproxy.h b/src/datavisualization/data/qsurfacedataproxy.h
new file mode 100644
index 00000000..460fa437
--- /dev/null
+++ b/src/datavisualization/data/qsurfacedataproxy.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 QtDataVisualization 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 QSURFACEDATAPROXY_H
+#define QSURFACEDATAPROXY_H
+
+#include <QtDataVisualization/qabstractdataproxy.h>
+#include <QtDataVisualization/qsurfacedataitem.h>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+typedef QVector<QSurfaceDataItem> QSurfaceDataRow;
+typedef QList<QSurfaceDataRow *> QSurfaceDataArray;
+
+class QSurfaceDataProxyPrivate;
+
+class QT_DATAVISUALIZATION_EXPORT QSurfaceDataProxy : public QAbstractDataProxy
+{
+ Q_OBJECT
+
+ Q_PROPERTY(int rowCount READ rowCount)
+ Q_PROPERTY(int columnCount READ columnCount)
+
+public:
+ explicit QSurfaceDataProxy(QObject *parent = 0);
+ virtual ~QSurfaceDataProxy();
+
+ int rowCount() const;
+ int columnCount() const;
+ const QSurfaceDataArray *array() const;
+ const QSurfaceDataItem *itemAt(int index) const;
+
+ void resetArray(QSurfaceDataArray *newArray);
+
+signals:
+ void arrayReset();
+
+protected:
+ explicit QSurfaceDataProxy(QSurfaceDataProxyPrivate *d, QObject *parent = 0);
+ QSurfaceDataProxyPrivate *dptr();
+ const QSurfaceDataProxyPrivate *dptrc() const;
+
+private:
+ Q_DISABLE_COPY(QSurfaceDataProxy)
+
+ friend class Surface3DController;
+};
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
+#endif // QSURFACEDATAPROXY_H
diff --git a/src/datavisualization/data/qsurfacedataproxy_p.h b/src/datavisualization/data/qsurfacedataproxy_p.h
new file mode 100644
index 00000000..4c8c2820
--- /dev/null
+++ b/src/datavisualization/data/qsurfacedataproxy_p.h
@@ -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 QtDataVisualization 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 QtDataVisualization 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 QSURFACEDATAPROXY_P_H
+#define QSURFACEDATAPROXY_P_H
+
+#include "qsurfacedataproxy.h"
+#include "qabstractdataproxy_p.h"
+
+#include <QSize>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class QSurfaceDataProxyPrivate : public QAbstractDataProxyPrivate
+{
+ Q_OBJECT
+public:
+ QSurfaceDataProxyPrivate(QSurfaceDataProxy *q);
+ virtual ~QSurfaceDataProxyPrivate();
+
+ void resetArray(QSurfaceDataArray *newArray);
+
+ void limitValues(QVector3D &minValues, QVector3D &maxValues);
+
+protected:
+ QSurfaceDataArray *m_dataArray;
+
+private:
+ QSurfaceDataProxy *qptr();
+ void clearRow(int rowIndex);
+ void clearArray();
+
+ friend class QSurfaceDataProxy;
+};
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
+#endif // QSURFACEDATAPROXY_P_H
diff --git a/src/datavisualization/data/scatteritemmodelhandler.cpp b/src/datavisualization/data/scatteritemmodelhandler.cpp
new file mode 100644
index 00000000..34230ae0
--- /dev/null
+++ b/src/datavisualization/data/scatteritemmodelhandler.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 QtDataVisualization 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 "scatteritemmodelhandler_p.h"
+#include <QTimer>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+ScatterItemModelHandler::ScatterItemModelHandler(QItemModelScatterDataProxy *proxy, QObject *parent)
+ : AbstractItemModelHandler(parent),
+ m_proxy(proxy),
+ m_proxyArray(0)
+{
+}
+
+ScatterItemModelHandler::~ScatterItemModelHandler()
+{
+}
+
+// Resolve entire item model into QScatterDataArray.
+void ScatterItemModelHandler::resolveModel()
+{
+ QItemModelScatterDataMapping *mapping = static_cast<QItemModelScatterDataMapping *>(m_activeMapping);
+ if (m_itemModel.isNull() || !mapping) {
+ m_proxy->resetArray(0);
+ m_proxyArray = 0;
+ return;
+ }
+
+ static const int noRoleIndex = -1;
+
+ QHash<int, QByteArray> roleHash = m_itemModel->roleNames();
+ const int xPosRole = roleHash.key(mapping->xPosRole().toLatin1(), noRoleIndex);
+ const int yPosRole = roleHash.key(mapping->yPosRole().toLatin1(), noRoleIndex);
+ const int zPosRole = roleHash.key(mapping->zPosRole().toLatin1(), noRoleIndex);
+ const int columnCount = m_itemModel->columnCount();
+ const int rowCount = m_itemModel->rowCount();
+ const int totalCount = rowCount * columnCount;
+ int runningCount = 0;
+
+ // If dimensions have changed, recreate the array
+ if (m_proxyArray != m_proxy->array() || totalCount != m_proxyArray->size())
+ m_proxyArray = new QScatterDataArray(totalCount);
+
+ // Parse data into newProxyArray
+ for (int i = 0; i < rowCount; i++) {
+ for (int j = 0; j < columnCount; j++) {
+ QModelIndex index = m_itemModel->index(i, j);
+ 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();
+ (*m_proxyArray)[runningCount].setPosition(QVector3D(xPos, yPos, zPos));
+ runningCount++;
+ }
+ }
+
+ m_proxy->resetArray(m_proxyArray);
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualization/data/scatteritemmodelhandler_p.h b/src/datavisualization/data/scatteritemmodelhandler_p.h
new file mode 100644
index 00000000..9b8a19a2
--- /dev/null
+++ b/src/datavisualization/data/scatteritemmodelhandler_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 QtDataVisualization 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 QtDataVisualization 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 SCATTERITEMMODELHANDLER_P_H
+#define SCATTERITEMMODELHANDLER_P_H
+
+#include "abstractitemmodelhandler_p.h"
+#include "qitemmodelscatterdataproxy.h"
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class ScatterItemModelHandler : public AbstractItemModelHandler
+{
+ Q_OBJECT
+public:
+ ScatterItemModelHandler(QItemModelScatterDataProxy *proxy, QObject *parent = 0);
+ virtual ~ScatterItemModelHandler();
+
+protected:
+ void virtual resolveModel();
+
+ QItemModelScatterDataProxy *m_proxy; // Not owned
+ QScatterDataArray *m_proxyArray; // Not owned
+};
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
+#endif
diff --git a/src/datavisualization/data/scatterrenderitem.cpp b/src/datavisualization/data/scatterrenderitem.cpp
new file mode 100644
index 00000000..83c66583
--- /dev/null
+++ b/src/datavisualization/data/scatterrenderitem.cpp
@@ -0,0 +1,42 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+ScatterRenderItem::ScatterRenderItem()
+ : AbstractRenderItem(),
+ m_visible(false)
+{
+}
+
+ScatterRenderItem::ScatterRenderItem(const ScatterRenderItem &other)
+ : AbstractRenderItem(other),
+ m_visible(false)
+{
+ m_position = other.m_position;
+}
+
+ScatterRenderItem::~ScatterRenderItem()
+{
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavis3d/data/scatterrenderitem_p.h b/src/datavisualization/data/scatterrenderitem_p.h
index 47cfeed2..58e91e96 100644
--- a/src/datavis3d/data/scatterrenderitem_p.h
+++ b/src/datavisualization/data/scatterrenderitem_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -29,40 +29,48 @@
#ifndef SCATTERRENDERITEM_P_H
#define SCATTERRENDERITEM_P_H
-#include "barrenderitem_p.h"
+#include "abstractrenderitem_p.h"
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
class Scatter3DRenderer;
-class ScatterRenderItem : public BarRenderItem
+class ScatterRenderItem : public AbstractRenderItem
{
public:
ScatterRenderItem();
+ ScatterRenderItem(const ScatterRenderItem &other);
virtual ~ScatterRenderItem();
inline const QVector3D &position() const { return m_position; }
- inline void setPosition(const QVector3D &pos) { m_position = pos; }
+ inline void setPosition(const QVector3D &pos);
+
+ inline bool isVisible() const { return m_visible; }
+ inline void setVisible(bool visible) { m_visible = visible; }
//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;
+ bool m_visible;
//qreal m_size; // TODO in case we need a fourth variable that adjusts scatter item size
friend class QScatterDataItem;
};
+void ScatterRenderItem::setPosition(const QVector3D &pos)
+{
+ if (m_position != pos) {
+ m_position = pos;
+ // Force reformatting on next access by setting label string to null string
+ if (!m_selectionLabel.isNull())
+ setSelectionLabel(QString());
+ }
+}
+
typedef QVector<ScatterRenderItem> ScatterRenderItemArray;
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif
diff --git a/src/datavisualization/data/surfaceitemmodelhandler.cpp b/src/datavisualization/data/surfaceitemmodelhandler.cpp
new file mode 100644
index 00000000..70482162
--- /dev/null
+++ b/src/datavisualization/data/surfaceitemmodelhandler.cpp
@@ -0,0 +1,144 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 "surfaceitemmodelhandler_p.h"
+#include "qitemmodelsurfacedatamapping_p.h"
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+SurfaceItemModelHandler::SurfaceItemModelHandler(QItemModelSurfaceDataProxy *proxy, QObject *parent)
+ : AbstractItemModelHandler(parent),
+ m_proxy(proxy),
+ m_proxyArray(0)
+{
+}
+
+SurfaceItemModelHandler::~SurfaceItemModelHandler()
+{
+}
+
+// Resolve entire item model into QSurfaceDataArray.
+void SurfaceItemModelHandler::resolveModel()
+{
+ QItemModelSurfaceDataMapping *mapping = static_cast<QItemModelSurfaceDataMapping *>(m_activeMapping);
+ if (m_itemModel.isNull() || !mapping) {
+ m_proxy->resetArray(0);
+ m_proxyArray = 0;
+ return;
+ }
+
+ if (!mapping->useModelCategories()
+ && (mapping->rowRole().isEmpty() || mapping->columnRole().isEmpty())) {
+ m_proxy->resetArray(0);
+ m_proxyArray = 0;
+ return;
+ }
+
+ QHash<int, QByteArray> roleHash = m_itemModel->roleNames();
+
+ // Default to display role if no mapping
+ int valueRole = roleHash.key(mapping->valueRole().toLatin1(), Qt::DisplayRole);
+ int rowCount = m_itemModel->rowCount();
+ int columnCount = m_itemModel->columnCount();
+
+ if (mapping->useModelCategories()) {
+ // If dimensions have changed, recreate the array
+ if (m_proxyArray != m_proxy->array() || columnCount != m_proxy->columnCount()
+ || rowCount != m_proxyArray->size()) {
+ m_proxyArray = new QSurfaceDataArray;
+ m_proxyArray->reserve(rowCount);
+ for (int i = 0; i < rowCount; i++)
+ m_proxyArray->append(new QSurfaceDataRow(columnCount));
+ }
+ for (int i = 0; i < rowCount; i++) {
+ QSurfaceDataRow &newProxyRow = *m_proxyArray->at(i);
+ for (int j = 0; j < columnCount; j++) {
+ newProxyRow[j].setPosition(
+ QVector3D(m_itemModel->headerData(j, Qt::Horizontal).toFloat(),
+ m_itemModel->index(i, j).data(valueRole).toFloat(),
+ m_itemModel->headerData(i, Qt::Vertical).toFloat()));
+ }
+ }
+ } else {
+ int rowRole = roleHash.key(mapping->rowRole().toLatin1());
+ int columnRole = roleHash.key(mapping->columnRole().toLatin1());
+
+ bool generateRows = mapping->autoRowCategories();
+ bool generateColumns = mapping->autoColumnCategories();
+
+ QStringList rowList;
+ QStringList columnList;
+ // For detecting duplicates in categories generation, using QHashes should be faster than
+ // simple QStringList::contains() check.
+ QHash<QString, bool> rowListHash;
+ QHash<QString, bool> columnListHash;
+
+ // 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);
+ QString rowRoleStr = index.data(rowRole).toString();
+ QString columnRoleStr = index.data(columnRole).toString();
+ itemValueMap[rowRoleStr][columnRoleStr] = index.data(valueRole).toReal();
+ if (generateRows && !rowListHash.value(rowRoleStr, false)) {
+ rowListHash.insert(rowRoleStr, true);
+ rowList << rowRoleStr;
+ }
+ if (generateColumns && !columnListHash.value(columnRoleStr, false)) {
+ columnListHash.insert(columnRoleStr, true);
+ columnList << columnRoleStr;
+ }
+ }
+ }
+
+ if (generateRows)
+ mapping->dptr()->m_rowCategories = rowList;
+ else
+ rowList = mapping->rowCategories();
+
+ if (generateColumns)
+ mapping->dptr()->m_columnCategories = columnList;
+ else
+ columnList = mapping->columnCategories();
+
+ // If dimensions have changed, recreate the array
+ if (m_proxyArray != m_proxy->array() || columnList.size() != m_proxy->columnCount()
+ || rowList.size() != m_proxyArray->size()) {
+ m_proxyArray = new QSurfaceDataArray;
+ m_proxyArray->reserve(rowList.size());
+ for (int i = 0; i < rowList.size(); i++)
+ m_proxyArray->append(new QSurfaceDataRow(columnList.size()));
+ }
+ // Create data array from itemValueMap
+ for (int i = 0; i < rowList.size(); i++) {
+ QString rowKey = rowList.at(i);
+ QSurfaceDataRow &newProxyRow = *m_proxyArray->at(i);
+ for (int j = 0; j < columnList.size(); j++) {
+ newProxyRow[j].setPosition(QVector3D(columnList.at(j).toFloat(),
+ itemValueMap[rowKey][columnList.at(j)],
+ rowList.at(i).toFloat()));
+ }
+ }
+ }
+
+ m_proxy->resetArray(m_proxyArray);
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualization/data/surfaceitemmodelhandler_p.h b/src/datavisualization/data/surfaceitemmodelhandler_p.h
new file mode 100644
index 00000000..bcf642c5
--- /dev/null
+++ b/src/datavisualization/data/surfaceitemmodelhandler_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 QtDataVisualization 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 QtDataVisualization 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 SURFACEITEMMODELHANDLER_P_H
+#define SURFACEITEMMODELHANDLER_P_H
+
+#include "abstractitemmodelhandler_p.h"
+#include "qitemmodelsurfacedataproxy.h"
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class SurfaceItemModelHandler : public AbstractItemModelHandler
+{
+ Q_OBJECT
+public:
+ SurfaceItemModelHandler(QItemModelSurfaceDataProxy *proxy, QObject *parent = 0);
+ virtual ~SurfaceItemModelHandler();
+
+protected:
+ void virtual resolveModel();
+
+ QItemModelSurfaceDataProxy *m_proxy; // Not owned
+ QSurfaceDataArray *m_proxyArray; // Not owned
+};
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
+#endif
diff --git a/src/datavisualization/datavisualization.pro b/src/datavisualization/datavisualization.pro
new file mode 100644
index 00000000..87857062
--- /dev/null
+++ b/src/datavisualization/datavisualization.pro
@@ -0,0 +1,27 @@
+TARGET = QtDataVisualization
+QT = core gui
+
+DEFINES += QT_DATAVISUALIZATION_LIBRARY
+
+QMAKE_DOCS = $$PWD/doc/qtdatavisualization.qdocconf
+
+load(qt_module)
+
+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)
+include($$PWD/input/input.pri)
+
+android {
+ CONFIG += static
+}
+
+OTHER_FILES += doc/qtdatavisualization.qdocconf \
+ doc/src/* \
+ doc/images/* \
+ doc/snippets/* \
+ global/*.qdoc
+
diff --git a/src/datavisualization/doc/images/q3dbars-minimal.png b/src/datavisualization/doc/images/q3dbars-minimal.png
new file mode 100644
index 00000000..fff8d415
--- /dev/null
+++ b/src/datavisualization/doc/images/q3dbars-minimal.png
Binary files differ
diff --git a/src/datavisualization/doc/images/q3dscatter-minimal.png b/src/datavisualization/doc/images/q3dscatter-minimal.png
new file mode 100644
index 00000000..1c3290b3
--- /dev/null
+++ b/src/datavisualization/doc/images/q3dscatter-minimal.png
Binary files differ
diff --git a/src/datavisualization/doc/images/q3dsurface-minimal.png b/src/datavisualization/doc/images/q3dsurface-minimal.png
new file mode 100644
index 00000000..119cdfb9
--- /dev/null
+++ b/src/datavisualization/doc/images/q3dsurface-minimal.png
Binary files differ
diff --git a/src/datavisualization/doc/qtdatavisualization.qdocconf b/src/datavisualization/doc/qtdatavisualization.qdocconf
new file mode 100644
index 00000000..e3189604
--- /dev/null
+++ b/src/datavisualization/doc/qtdatavisualization.qdocconf
@@ -0,0 +1,51 @@
+include($QT_INSTALL_DOCS/global/qt-module-defaults.qdocconf)
+
+project = QtDataVisualization
+description = Qt Data Visualization Reference Documentation
+version = 1.0.0
+
+exampledirs += ../../../examples \
+ snippets
+
+headerdirs += ..
+imagedirs += ../images \
+ images
+sourcedirs += ..
+
+depends += qtcore \
+ qtgui
+
+qhp.projects = qtdatavisualization
+
+qhp.qtdatavisualization.file = qtdatavisualization.qhp
+qhp.qtdatavisualization.namespace = org.qt-project.qtdatavisualization.1.0.0
+qhp.qtdatavisualization.virtualFolder = qtdatavisualization
+qhp.qtdatavisualization.indexTitle = Qt Data Visualization
+qhp.qtdatavisualization.indexRoot =
+
+qhp.qtdatavisualization.filterAttributes = qtdatavisualization 1.0.0 qtrefdoc
+qhp.qtdatavisualization.customFilters.Qt.name = QtDataVisualization 1.0.0
+qhp.qtdatavisualization.customFilters.Qt.filterAttributes = qtdatavisualization 1.0.0
+qhp.qtdatavisualization.subprojects = classes
+qhp.qtdatavisualization.subprojects.classes.title = C++ Classes
+qhp.qtdatavisualization.subprojects.classes.indexTitle = Qt Data Visualization C++ Classes
+qhp.qtdatavisualization.subprojects.classes.selectors = class fake:headerfile
+qhp.qtdatavisualization.subprojects.classes.sortPages = true
+
+
+HTML.footer = \
+ "<div class=\"footer\">\n" \
+ " <p>\n" \
+ " <acronym title=\"Copyright\">&copy;</acronym> 2013 Digia. Qt and Qt logos are\n" \
+ " trademarks of of Digia Corporation in Finland and/or other countries worldwide.\n" \
+ " </p>\n" \
+ " All other trademarks are property of their respective owners.\n" \
+ " <br />\n" \
+ " <p>\n" \
+ " Licensees holding valid Qt Enterprise licenses may use this document in accordance\n" \
+ " with the Qt Enterprise License Agreement provided with the Software or,\n" \
+ " alternatively, in accordance with the terms contained in a written agreement\n" \
+ " between you and Digia.\n" \
+ " </p>\n" \
+ "</div>\n"
+
diff --git a/src/datavisualization/doc/snippets/doc_src_q3dbars_construction.cpp b/src/datavisualization/doc/snippets/doc_src_q3dbars_construction.cpp
new file mode 100644
index 00000000..a5615601
--- /dev/null
+++ b/src/datavisualization/doc/snippets/doc_src_q3dbars_construction.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 QtDataVisualization 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
+**
+****************************************************************************/
+
+//! [3]
+#include <QtDataVisualization>
+
+using namespace QtDataVisualization;
+
+int main(int argc, char **argv)
+{
+ QGuiApplication app(argc, argv);
+
+ //! [4]
+ Q3DBars *bars = new Q3DBars();
+ //! [4]
+ //! [0]
+ bars->rowAxis()->setRange(0, 4);
+ bars->columnAxis()->setRange(0, 4);
+ //! [0]
+ //! [1]
+ QBarDataRow data;
+ data << 1.0 << 3.0 << 7.5 << 5.0 << 2.2;
+ bars->activeDataProxy()->addRow(&data);
+ //! [1]
+ //! [2]
+ bars->show();
+ //! [2]
+
+ return app.exec();
+}
+//! [3]
diff --git a/src/datavis3d/doc/snippets/doc_src_q3dbars_construction.cpp b/src/datavisualization/doc/snippets/doc_src_q3dscatter_construction.cpp
index 09979d8c..b2f48921 100644
--- a/src/datavis3d/doc/snippets/doc_src_q3dbars_construction.cpp
+++ b/src/datavisualization/doc/snippets/doc_src_q3dscatter_construction.cpp
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -17,23 +17,24 @@
****************************************************************************/
//! [3]
-#include <QtDataVis3D>
+#include <QtDataVisualization>
+
+using namespace QtDataVisualization;
int main(int argc, char **argv)
{
QGuiApplication app(argc, argv);
//! [0]
- Q3DBars bars;
- bars.setupSampleSpace(5, 5);
+ Q3DScatter *scatter = new Q3DScatter();
//! [0]
//! [1]
- QVector<float> data;
- data << 1.0f << 3.0f << 7.5f << 5.0f << 2.2f;
- bars.addDataRow(data);
+ QScatterDataArray data;
+ data << QVector3D(1.0f, 0.5f, 1.0f) << QVector3D(-1.0f, -0.5f, -1.0f) << QVector3D(0.5f, 0.0f, 0.0f);
+ scatter->activeDataProxy()->addItems(data);
//! [1]
//! [2]
- bars.show();
+ scatter->show();
//! [2]
return app.exec();
diff --git a/src/datavisualization/doc/snippets/doc_src_q3dsurface_construction.cpp b/src/datavisualization/doc/snippets/doc_src_q3dsurface_construction.cpp
new file mode 100644
index 00000000..33b6cf37
--- /dev/null
+++ b/src/datavisualization/doc/snippets/doc_src_q3dsurface_construction.cpp
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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
+**
+****************************************************************************/
+
+//! [5]
+#include <QtDataVisualization>
+
+using namespace QtDataVisualization;
+
+int main(int argc, char **argv)
+{
+ QGuiApplication app(argc, argv);
+
+ //! [0]
+ Q3DSurface surface;
+ //! [0]
+ //! [1]
+ QSurfaceDataArray *data = new QSurfaceDataArray;
+ QSurfaceDataRow *dataRow = new QSurfaceDataRow;
+ //! [1]
+
+ //! [2]
+ *dataRow << 0.1 << 1.8 << 0.4;
+ *data << dataRow;
+ //! [2]
+
+ //! [3]
+ surface.activeDataProxy()->resetArray(data);
+ //! [3]
+ //! [4]
+ surface.show();
+ //! [4]
+
+ return app.exec();
+}
+//! [5]
diff --git a/src/datavisualization/doc/snippets/doc_src_qmldatavisualization.cpp b/src/datavisualization/doc/snippets/doc_src_qmldatavisualization.cpp
new file mode 100644
index 00000000..f4446e17
--- /dev/null
+++ b/src/datavisualization/doc/snippets/doc_src_qmldatavisualization.cpp
@@ -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 QtDataVisualization 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
+**
+****************************************************************************/
+
+//! [0]
+import com.digia.QtDataVisualization 1.0
+//! [0]
+
+//! [1]
+Bars3D {
+ rows: 4
+ columns: 4
+ dataProxy: barProxy // an ItemModelBarDataProxy
+ barSpacing: Qt.size(0.5, 0.5)
+ barSpacingRelative: false
+ itemLabelFormat: "@valueTitle for @colLabel, @rowLabel: @valueLabel"
+}
+//! [1]
+
+//! [2]
+Scatter3D {
+ dataProxy: scatterProxy // an ItemModelScatterDataProxy
+ itemLabelFormat: "X:@xLabel Y:@yLabel Z:@zLabel"
+ axisX.segmentCount: 2
+ axisX.subSegmentCount: 2
+ axisX.labelFormat: "%.2f"
+ axisZ.segmentCount: 2
+ axisZ.subSegmentCount: 2
+ axisZ.labelFormat: "%.2f"
+ axisY.segmentCount: 3
+ axisY.subSegmentCount: 2
+ axisY.labelFormat: "%.2f"
+}
+//! [2]
+
+//! [3]
+Surface3D {
+ dataProxy: surfaceProxy // an ItemModelSurfaceDataProxy
+ axisX.min: 0.0
+ axisX.max: 10.0
+ axisZ.min: 0.0
+ axisZ.max: 10.0
+ axisY.min: 0.0
+ axisY.max: 5.0
+ axisX.segmentCount: 5
+ axisX.subSegmentCount: 2
+ axisX.labelFormat: "%i"
+ axisZ.segmentCount: 5
+ axisZ.subSegmentCount: 2
+ axisZ.labelFormat: "%i"
+ axisY.segmentCount: 5
+ axisY.labelFormat: "%.1f"
+}
+//! [3]
+
+//! [4]
+BarDataMapping {
+ id: barMapping
+ rowRole: "year"
+ columnRole: "city"
+ valueRole: "expenses"
+ rowCategories: ["2010", "2011", "2012", "2013"]
+ columnCategories: ["Oulu", "Rauma", "Helsinki", "Tampere"]
+}
+//! [4]
+
+//! [5]
+ScatterDataMapping {
+ id: scatterMapping
+ xPosRole: "xPos"
+ yPosRole: "yPos"
+ zPosRole: "zPos"
+}
+//! [5]
+
+//! [6]
+SurfaceDataMapping {
+ id: surfaceMapping
+ rowRole: "latitude"
+ columnRole: "longitude"
+ valueRole: "population"
+}
+//! [6]
+
+//! [7]
+ItemModelBarDataProxy {
+ id: barProxy
+ activeMapping: barMapping // a BarDataMapping
+ itemModel: dataModel // a ListModel
+}
+//! [7]
+
+//! [8]
+ItemModelScatterDataProxy {
+ id: scatterProxy
+ activeMapping: scatterMapping // a ScatterDataMapping
+ itemModel: dataModel // a ListModel
+}
+//! [8]
+
+//! [9]
+ItemModelSurfaceDataProxy {
+ id: surfaceProxy
+ activeMapping: surfaceMapping // a SurfaceDataMapping
+ itemModel: dataModel // a ListModel
+}
+//! [9]
diff --git a/src/datavisualization/doc/snippets/doc_src_qtdatavisualization.cpp b/src/datavisualization/doc/snippets/doc_src_qtdatavisualization.cpp
new file mode 100644
index 00000000..2f3d6a98
--- /dev/null
+++ b/src/datavisualization/doc/snippets/doc_src_qtdatavisualization.cpp
@@ -0,0 +1,118 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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
+**
+****************************************************************************/
+
+//! [0]
+#include <QtDataVisualization>
+
+using namespace QtDataVisualization;
+//! [0]
+
+//! [1]
+proxy->setItemLabelFormat(QStringLiteral("@valueTitle for (@rowLabel, @colLabel): %.1f"));
+//! [1]
+
+//! [2]
+proxy->setItemLabelFormat(QStringLiteral("@xTitle: @xValue, @yTitle: @yValue, @zTitle: @zValue"));
+//! [2]
+
+//! [3]
+// By defining row and column categories, you tell the mapping which row and column each item
+// belongs to. The categories must match the data stored in the model in the roles you define
+// for row and column mapping. In this example we expect "year" role to return four digit year
+// and "month" to return three letter designation for the month.
+//
+// An example of an item in model would be:
+// Requested role -> Returned data
+// "year" -> "2006" // Matches the first row category, so this item is added to the first row.
+// "month" -> "jan" // Matches the first column category, so this item is added as first item in the row.
+// "income" -> "12.1"
+// "expenses" -> "9.2"
+QStringList years;
+QStringList months;
+years << "2006" << "2007" << "2008" << "2009" << "2010" << "2011" << "2012";
+months << "jan" << "feb" << "mar" << "apr" << "may" << "jun" << "jul" << "aug" << "sep" << "oct" << "nov" << "dec";
+
+QItemModelBarDataMapping *mapping = new QItemModelBarDataMapping(QStringLiteral("year"), // Row role
+ QStringLiteral("month"), // Column role
+ QStringLiteral("income"), // Value role
+ years, // Row categories
+ months); // Column categories
+
+QItemModelBarDataProxy *proxy = new QItemModelBarDataProxy(customModel, mapping);
+
+//...
+
+// To display different data later, you can simply change the mapping of the current
+// mapping object, or set another mapping object.
+proxy->activeMapping()->setValueRole(QStringLiteral("expenses"));
+//! [3]
+
+//! [4]
+// Map "density" value to X-axis, "hardness" to Y-axis and "conductivity" to Z-axis.
+QItemModelScatterDataMapping *mapping = new QItemModelScatterDataMapping(QStringLiteral("density"),
+ QStringLiteral("hardness"),
+ QStringLiteral("conductivity"))
+
+QItemModelScatterDataProxy *proxy = new QItemModelScatterDataProxy(customModel, mapping);
+//! [4]
+
+//! [5]
+QItemModelSurfaceDataMapping *mapping = new QItemModelSurfaceDataMapping(QStringLiteral("longitude"), // Row role
+ QStringLiteral("latitude"), // Column role
+ QStringLiteral("height")); // value role
+
+QItemModelSurfaceDataProxy *proxy = new QItemModelSurfaceDataProxy(customModel, mapping);
+//! [5]
+
+//! [6]
+qmake
+make
+//! [6]
+
+//! [7]
+qmake CONFIG+=static
+make
+//! [7]
+
+//! [8]
+qmake
+make
+./qmlsurface
+//! [8]
+
+//! [9]
+Q3DBars *graph = new Q3DBars();
+QWidget *container = QWidget::createWindowContainer(graph);
+//! [9]
+
+//! [10]
+Q3DBars graph;
+QBarDataProxy *newProxy = new QBarDataProxy;
+
+QBarDataArray *dataArray = new QBarDataArray;
+dataArray->reserve(10);
+for (int i = 0; i < 10; i++) {
+ QBarDataRow *dataRow = new QBarDataRow(5);
+ for (int j = 0; j < 5; j++)
+ (*dataRow)[j].setValue(myData->getValue(i, j));
+ dataArray->append(dataRow);
+}
+
+newProxy->resetArray(dataArray);
+graph->setActiveDataProxy(newProxy);
+//! [10]
diff --git a/src/datavis3d/doc/snippets/doc_src_qtdatavis3d.pro b/src/datavisualization/doc/snippets/doc_src_qtdatavisualization.pro
index ba0f320b..81555f88 100644
--- a/src/datavis3d/doc/snippets/doc_src_qtdatavis3d.pro
+++ b/src/datavisualization/doc/snippets/doc_src_qtdatavisualization.pro
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -17,5 +17,5 @@
****************************************************************************/
#! [0]
-QT += datavis3d
+QT += datavisualization
#! [0]
diff --git a/src/datavisualization/doc/src/qtdatavisualization-index.qdoc b/src/datavisualization/doc/src/qtdatavisualization-index.qdoc
new file mode 100644
index 00000000..f2245c12
--- /dev/null
+++ b/src/datavisualization/doc/src/qtdatavisualization-index.qdoc
@@ -0,0 +1,78 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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
+**
+****************************************************************************/
+
+/*!
+ \title Qt Data Visualization
+ \page qtdatavisualization-index.html
+ \brief QtDataVisualization module provides functionality for 3D visualization.
+
+ Qt Data Visualization module provides a way to visualize data in 3D.
+
+ \section1 Features
+
+ \list
+ \li Multiple data visualization options: 3D Bars, 3D Scatter, and 3D Surface
+ \li 2D slice views of the 3D data
+ \li Interactive data: Rotate, zoom, and highlight data using mouse or touch
+ \li Uses OpenGL for rendering the data
+ \li QML2 support
+ \li Customizable axes for data - control viewable data window with axis ranges
+ \li Customizable input handling (upcoming feature - not supported in technology preview)
+ \li Customizable scene handling - full control of cameras and lights (upcoming feature -
+ not supported in technology preview)
+ \li Customizable themes (upcoming feature - not supported in technology preview)
+ \endlist
+
+ \section1 Getting Started
+
+ To import Qt Data Visualization QML types, add the following import statement to your \c .qml
+ file:
+
+ \snippet doc_src_qmldatavisualization.cpp 0
+
+ If you intend to use Qt Data Visualization C++ classes in your application, use the
+ following include and using directives:
+
+ \snippet doc_src_qtdatavisualization.cpp 0
+
+ \note If you are using a few classes from this module, we recommend including those specific
+ classes only instead of the whole module.
+
+ To link against Qt Data Visualization module, add this line to your \c qmake project file:
+
+ \snippet doc_src_qtdatavisualization.pro 0
+
+ See \l{Qt Data Visualization Getting Started}{Getting started} page for further information
+ how to use Qt Data Visualization in your application.
+
+ \section1 Articles
+ \list
+ \li \l{Qt Data Visualization Data Handling}{Data input}
+ \li \l{Qt Data Visualization Interacting with Data}{Interacting with visualized data}
+ \endlist
+
+ \section1 References
+ \list
+ \li \l{Qt Data Visualization C++ Classes}
+ \li \l{Qt Data Visualization QML Types}
+ \endlist
+
+ Qt Data Visualization comes with the following examples:
+
+ \annotatedlist qtdatavisualization_examples
+*/
diff --git a/src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc b/src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc
new file mode 100644
index 00000000..7a0d2c4a
--- /dev/null
+++ b/src/datavisualization/doc/src/qtdatavisualization-qml-abstractdeclarative.qdoc
@@ -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 QtDataVisualization 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
+**
+****************************************************************************/
+
+/*!
+ \qmltype AbstractGraph3D
+ \inqmlmodule com.digia.QtDataVisualization 1.0
+ \since com.digia.QtDataVisualization 1.0
+ \ingroup datavisualization_qml
+ \brief Base type for 3D visualizations.
+
+ This type is the base type for all 3D visualizations in QtDataVisualization.
+
+ It resides in the data visualization module that can be imported like this:
+
+ \snippet doc_src_qmldatavisualization.cpp 0
+
+ Note that this type is uncreatable, but contains properties that are shared between
+ the 3D visualizations.
+
+ \sa Bars3D, Scatter3D, Surface3D, {Qt Data Visualization C++ Classes}
+ */
+
+/*!
+ \qmlproperty AbstractGraph3D.SelectionMode AbstractGraph3D::selectionMode
+ Active selection mode in the visualization.
+ */
+/*!
+ \qmlproperty AbstractGraph3D.LabelStyle AbstractGraph3D::labelStyle
+ Label style.
+ */
+
+/*!
+ \qmlproperty AbstractGraph3D.ShadowQuality AbstractGraph3D::shadowQuality
+ Shadow quality.
+ */
+
+/*!
+ \qmlproperty AbstractGraph3D.CameraPreset AbstractGraph3D::cameraPreset
+ Camera preset.
+ */
+
+/*!
+ \qmlproperty AbstractGraph3D.Theme AbstractGraph3D::theme
+ Theme of the graph. Theme affects visualization colors, label colors, text color, background color, window
+ color and grid color. Lighting is also adjusted by themes.
+ */
+
+/*!
+ \qmlproperty font AbstractGraph3D::font
+ Font used for labels.
+ */
+
+/*!
+ \qmlproperty bool AbstractGraph3D::gridVisible
+ Grid visibility. If false, grid lines are not drawn.
+ */
+
+/*!
+ \qmlproperty bool AbstractGraph3D::backgroundVisible
+ Background visibility. If false, background is not drawn.
+ */
+
+/*!
+ \qmlproperty string AbstractGraph3D::itemLabelFormat
+ Label format of single item labels, e.g. a selected datapoint.
+ */
diff --git a/src/datavisualization/doc/src/qtdatavisualization-qml-bars3d.qdoc b/src/datavisualization/doc/src/qtdatavisualization-qml-bars3d.qdoc
new file mode 100644
index 00000000..213542b9
--- /dev/null
+++ b/src/datavisualization/doc/src/qtdatavisualization-qml-bars3d.qdoc
@@ -0,0 +1,136 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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
+**
+****************************************************************************/
+
+/*!
+ * \qmltype Bars3D
+ * \inherits AbstractGraph3D
+ * \inqmlmodule com.digia.QtDataVisualization 1.0
+ * \since com.digia.QtDataVisualization 1.0
+ * \ingroup datavisualization_qml
+ * \brief 3D bar graph.
+ *
+ * This type enables developers to render bar graphs in 3D with Qt Quick 2.
+ *
+ * You will need to import data visualization module to use this type:
+ *
+ * \snippet doc_src_qmldatavisualization.cpp 0
+ *
+ * After that you can use Bars3D in your qml files:
+ *
+ * \snippet doc_src_qmldatavisualization.cpp 1
+ *
+ * See \l{Qt Quick 2 Bars Example} for more thorough usage example.
+ *
+ * \sa ItemModelBarDataProxy, Scatter3D, Surface3D, {Qt Data Visualization C++ Classes}
+ */
+
+/*!
+ * \qmlmethod void Bars3D::setBarColor(const QColor &baseColor, bool uniform)
+ * Set bar color using your own color. \a baseColor sets the base color of a bar. The \a uniform
+ * -flag is used to define if color needs to be uniform throughout bar's length, or will the colors
+ * be applied by height, starting with dark at the bottom. It is \c true by default.
+ *
+ * Calling this method overrides colors from theme.
+ *
+ * \sa AbstractGraph3D::theme
+ *
+ * \warning This method is subject to change.
+ */
+
+/*!
+ * \qmlproperty BarDataProxy Bars3D::dataProxy
+ * The active data proxy.
+ *
+ * If a proxy is not given, a temporary default proxy is created and activated.
+ * This temporary proxy is destroyed if another proxy is explicitly set active via this property.
+ */
+
+/*!
+ * \qmlproperty CategoryAxis3D Bars3D::rowAxis
+ * A user-defined row axis.
+ *
+ * If an axis is not given, a temporary default axis with no labels is created.
+ * This temporary axis is destroyed if another axis is explicitly set to same orientation.
+ */
+
+/*!
+ * \qmlproperty ValueAxis3D Bars3D::valueAxis
+ * A user-defined value axis.
+ *
+ * If an axis is not given, a temporary default axis with no labels and automatically adjusting
+ * range is created.
+ * This temporary axis is destroyed if another axis is explicitly set to same orientation.
+ */
+
+/*!
+ * \qmlproperty CategoryAxis3D Bars3D::columnAxis
+ * A user-defined column axis.
+ *
+ * If an axis is not given, a temporary default axis with no labels is created.
+ * This temporary axis is destroyed if another axis is explicitly set to same orientation.
+ */
+
+
+/*!
+ * \qmlproperty Bars3D.MeshStyle Bars3D::barType
+ * Bar object type.
+ */
+
+/*!
+ * \qmlproperty real Bars3D::barThickness
+ * Bar thickness ratio between X and Z dimensions. 1.0 means bars are as wide as they are deep, 0.5
+ * makes them twice as deep as they are wide.
+ */
+
+/*!
+ * \qmlproperty size Bars3D::barSpacing
+ * Bar spacing in X and Z dimensions.
+ */
+
+/*!
+ * \qmlproperty bool Bars3D::barSpacingRelative
+ * Relative or absolute bar spacing.
+ */
+
+/*!
+ * \qmlproperty bool Bars3D::barSmoothingEnabled
+ * Bar smoothing. If false, bar shading is flat.
+ */
+
+/*!
+ * \qmlproperty string Bars3D::meshFileName
+ * Override bar type with a mesh object.
+ * \note Object needs to be in Wavefront obj format and include vertices, normals and UVs.
+ * It also needs to be in triangles.
+ */
+
+/*!
+ * \qmlproperty int Bars3D::rows
+ * Row count of data window.
+ */
+
+/*!
+ * \qmlproperty int Bars3D::columns
+ * Column count of data window.
+ */
+
+/*!
+ * \qmlproperty point Bars3D::selectedBarPos
+ * Position of the selected bar in data window. Only one bar can be selected at a time.
+ * To clear selection, specify an illegal position, e.g. Qt.point(-1.0, -1.0).
+ */
diff --git a/src/datavisualization/doc/src/qtdatavisualization-qml-colorgradient.qdoc b/src/datavisualization/doc/src/qtdatavisualization-qml-colorgradient.qdoc
new file mode 100644
index 00000000..f8edf492
--- /dev/null
+++ b/src/datavisualization/doc/src/qtdatavisualization-qml-colorgradient.qdoc
@@ -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 QtDataVisualization 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
+**
+****************************************************************************/
+
+/*!
+ \qmltype ColorGradientStop
+ \inqmlmodule com.digia.QtDataVisualization 1.0
+ \since com.digia.QtDataVisualization 1.0
+ \ingroup datavisualization_qml
+ \brief Defines the color at a position in ColorGradient.
+
+ Defines the color at a position in a ColorGradient.
+
+ \sa ColorGradient
+*/
+
+/*!
+ \qmlproperty real ColorGradientStop::position
+
+ The position property describes the position of this gradient stop.
+
+ The default position is 0.0.
+
+ \sa ColorGradient
+*/
+
+/*!
+ \qmlproperty color ColorGradientStop::color
+
+ The color property describes the color color of this gradient stop.
+
+ The default color is black.
+
+ \sa ColorGradient
+*/
+
+/*!
+ \qmltype ColorGradient
+ \inqmlmodule com.digia.QtDataVisualization 1.0
+ \since com.digia.QtDataVisualization 1.0
+ \ingroup datavisualization_qml
+ \brief Defines a color gradient.
+
+ A gradient is defined by two or more colors, which will be blended seamlessly.
+
+ The colors are specified as a set of ColorGradientStop child items, each of
+ which defines a position on the gradient from 0.0 to 1.0 and a color.
+ The position of each ColorGradientStop is defined by setting its
+ \l{ColorGradientStop::}{position} property; its color is defined using its
+ \l{ColorGradientStop::}{color} property.
+
+ A gradient without any gradient stops falls back to QLinearGradient default,
+ which is black at 0.0 and white at 1.0.
+
+ \sa ColorGradientStop
+*/
+
+/*!
+ \qmlproperty list<ColorGradientStop> ColorGradient::stops
+ \default
+
+ This property holds the gradient stops describing the gradient.
+
+ By default, this property contains an empty list.
+
+ To set the gradient stops, define them as children of the ColorGradient.
+*/
diff --git a/src/datavisualization/doc/src/qtdatavisualization-qml-scatter3d.qdoc b/src/datavisualization/doc/src/qtdatavisualization-qml-scatter3d.qdoc
new file mode 100644
index 00000000..2839468e
--- /dev/null
+++ b/src/datavisualization/doc/src/qtdatavisualization-qml-scatter3d.qdoc
@@ -0,0 +1,105 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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
+**
+****************************************************************************/
+
+/*!
+ \qmltype Scatter3D
+ \inherits AbstractGraph3D
+ \inqmlmodule com.digia.QtDataVisualization 1.0
+ \since com.digia.QtDataVisualization 1.0
+ \ingroup datavisualization_qml
+ \brief 3D scatter graph.
+
+ This type enables developers to render scatter graphs in 3D with Qt Quick 2.
+
+ You will need to import data visualization module to use this type:
+
+ \snippet doc_src_qmldatavisualization.cpp 0
+
+ After that you can use Scatter3D in your qml files:
+
+ \snippet doc_src_qmldatavisualization.cpp 2
+
+ See \l{Qt Quick 2 Scatter Example} for more thorough usage example.
+
+ \sa ItemModelScatterDataProxy, Bars3D, Surface3D, {Qt Data Visualization C++ Classes}
+ */
+
+/*!
+ * \qmlmethod void Scatter3D::setObjectColor(const QColor &baseColor, bool uniform)
+ * Set item color using your own colors. \a baseColor sets the base color of a item. The \a uniform
+ * -flag is used to define if color needs to be uniform throughout item's length, or will the colors
+ * be applied by height. It is \c true by default.
+ *
+ * Calling this method overrides colors from theme.
+ *
+ * \sa AbstractGraph3D::theme
+ *
+ * \warning This method is subject to change.
+ */
+
+/*!
+ \qmlproperty ScatterDataProxy Scatter3D::dataProxy
+ The active data proxy.
+
+ If a proxy is not given, a temporary default proxy is created and activated.
+ This temporary proxy is destroyed if another proxy is explicitly set active via this property.
+ */
+
+/*!
+ \qmlproperty ValueAxis3D Scatter3D::axisX
+ A user-defined X axis.
+
+ If an axis is not given, a temporary default axis with no labels and automatically adjusting
+ range is created.
+ This temporary axis is destroyed if another axis is explicitly set to same orientation.
+ */
+
+/*!
+ \qmlproperty ValueAxis3D Scatter3D::axisY
+ A user-defined Y axis.
+
+ If an axis is not given, a temporary default axis with no labels and automatically adjusting
+ range is created.
+ This temporary axis is destroyed if another axis is explicitly set to same orientation.
+ */
+
+/*!
+ \qmlproperty ValueAxis3D Scatter3D::axisZ
+ A user-defined Z axis.
+
+ If an axis is not given, a temporary default axis with no labels and automatically adjusting
+ range is created.
+ This temporary axis is destroyed if another axis is explicitly set to same orientation.
+ */
+
+/*!
+ \qmlproperty Scatter3D.MeshStyle Scatter3D::objectType
+ Dot object type.
+ */
+
+/*!
+ \qmlproperty bool Scatter3D::objectSmoothingEnabled
+ Dot smoothing. If false, dot shading is flat.
+ */
+
+/*!
+ \qmlproperty string Scatter3D::meshFileName
+ Override object type with a mesh object.
+ \note Object needs to be in Wavefront obj format and include vertices, normals and UVs.
+ It also needs to be in triangles.
+ */
diff --git a/src/datavisualization/doc/src/qtdatavisualization-qml-surface3d.qdoc b/src/datavisualization/doc/src/qtdatavisualization-qml-surface3d.qdoc
new file mode 100644
index 00000000..3669c1cd
--- /dev/null
+++ b/src/datavisualization/doc/src/qtdatavisualization-qml-surface3d.qdoc
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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
+**
+****************************************************************************/
+
+/*!
+ \qmltype Surface3D
+ \inherits AbstractGraph3D
+ \inqmlmodule com.digia.QtDataVisualization 1.0
+ \since com.digia.QtDataVisualization 1.0
+ \ingroup datavisualization_qml
+ \brief 3D surface graph.
+
+ This type enables developers to render surface plots in 3D with Qt Quick 2.
+
+ You will need to import data visualization module to use this type:
+
+ \snippet doc_src_qmldatavisualization.cpp 0
+
+ After that you can use Surface3D in your qml files:
+
+ \snippet doc_src_qmldatavisualization.cpp 3
+
+ See \l{Qt Quick 2 Surface Example} for more thorough usage example.
+
+ \sa ItemModelSurfaceDataProxy, Bars3D, Scatter3D, {Qt Data Visualization C++ Classes}
+ */
+
+/*!
+ \qmlproperty SurfaceDataProxy Surface3D::dataProxy
+ The active data proxy.
+
+ If a proxy is not given, a temporary default proxy is created and activated.
+ This temporary proxy is destroyed if another proxy is explicitly set active via this property.
+ */
+
+/*!
+ \qmlproperty ValueAxis3D Surface3D::axisX
+ A user-defined X axis.
+
+ If an axis is not given, a temporary default axis with no labels and automatically adjusting
+ range is created.
+ This temporary axis is destroyed if another axis is explicitly set to same orientation.
+ */
+
+/*!
+ \qmlproperty ValueAxis3D Surface3D::axisY
+ A user-defined Y axis.
+
+ If an axis is not given, a temporary default axis with no labels and automatically adjusting
+ range is created.
+ This temporary axis is destroyed if another axis is explicitly set to same orientation.
+ */
+
+/*!
+ \qmlproperty ValueAxis3D Surface3D::axisZ
+ A user-defined Z axis.
+
+ If an axis is not given, a temporary default axis with no labels and automatically adjusting
+ range is created.
+ This temporary axis is destroyed if another axis is explicitly set to same orientation.
+ */
+
+/*!
+ \qmlproperty bool Surface3D::smoothSurfaceEnabled
+ Smoothing of surface. If false, shading of the surface is flat.
+ */
+
+/*!
+ \qmlproperty bool Surface3D::surfaceGridEnabled
+ Surface grid visibility. If false, no surface grid is drawn.
+ */
+
+/*!
+ \qmlproperty ColorGradient Surface3D::gradient
+ The current surface gradient. Setting this property replaces the previous gradient.
+ */
diff --git a/src/datavisualization/doc/src/qtdatavisualization.qdoc b/src/datavisualization/doc/src/qtdatavisualization.qdoc
new file mode 100644
index 00000000..45087e9d
--- /dev/null
+++ b/src/datavisualization/doc/src/qtdatavisualization.qdoc
@@ -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 QtDataVisualization 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
+**
+****************************************************************************/
+
+/*!
+ \module QtDataVisualization
+ \title Qt Data Visualization C++ Classes
+ \ingroup modules
+
+ \brief The QtDataVisualization module provides functionality for 3D visualization.
+*/
+
+/*!
+ \group datavisualization_qml
+ \title Qt Data Visualization QML Types
+
+ \brief QML types for the Qt Data Visualization API.
+
+ Qt Data Visualization functionality can be accessed via these QML types.
+
+ \section1 QML Types
+*/
+
+/*!
+ \page qtdatavisualization_getting_started.html
+ \title Qt Data Visualization Getting Started
+
+ \section1 Building Qt Data Visualization
+
+ To build Qt Data Visualization module, set up a command prompt with an environment for
+ building Qt applications, navigate to the directory containing \c qtdatavisualization.pro,
+ and give the following commands:
+
+ \snippet doc_src_qtdatavisualization.cpp 6
+
+ \note The \c make tool name may vary depending on your target platform.
+ E.g. make/nmake/mingw32-make/...
+
+ To build a statically linked version of the Qt Data Visualization module, give the following
+ commands:
+
+ \snippet doc_src_qtdatavisualization.cpp 7
+
+ \section1 Running examples
+
+ Qt Data Visualization examples are found under \c examples subdirectory. To build and run a
+ single example, e.g. the qmlsurface example, navigate to the example directory and give the
+ following commands:
+
+ \snippet doc_src_qtdatavisualization.cpp 8
+
+ \note On some platforms, such as Windows, the executable can be generated under debug or
+ release folders, depending on your build.
+
+ \section1 Creating a simple application
+
+ To create a simple application, start by creating a new Qt Gui Application project in Qt
+ Creator and add this line to the \c .pro file of the project:
+
+ \snippet doc_src_qtdatavisualization.pro 0
+
+ In the \c main.cpp file, include the module headers and declare namespace usage:
+
+ \snippet doc_src_qtdatavisualization.cpp 0
+
+ Then, add the sample code found in one of the following pages, depending on what kind of
+ visualization you are interested in: \l{How to construct a minimal Q3DBars graph},
+ \l{How to construct a minimal Q3DScatter graph}, or
+ \l{How to construct a minimal Q3DSurface graph}.
+
+ To use Qt Data Visualization graphs in widget based applications, you can use
+ QWidget::createWindowContainer() function to wrap the graph into a widget:
+
+ \snippet doc_src_qtdatavisualization.cpp 9
+
+ For further code examples, see one of the Qt Data Visualization examples:
+
+ \annotatedlist qtdatavisualization_examples
+*/
+
+/*!
+ \page qtdatavisualization_data_handling.html
+ \title Qt Data Visualization Data Handling
+
+ \section1 Data proxies
+
+ The data users wish to visualize comes in many formats, all of which cannot obviously be
+ directly supported. Therefore Qt Data Visualization implements data proxies into which
+ user can feed their data in a known format. Each visualization type has a basic proxy type,
+ which takes data in a format suitable for that visualization.
+ For example, the basic proxy for Q3DBars is QBarDataProxy, which stores rows of QBarDataItem
+ objects. Each QBarDataItem stores a single bar value. Additional typedefs are provided for
+ QBarDataArray and QBarDataRow containers.
+
+ This code snipped shows how to use basic proxy when your data is stored in some hypothetical
+ \c myData object:
+
+ \snippet doc_src_qtdatavisualization.cpp 10
+
+ \note The graph objects can own more than one data proxy, but only one proxy can be
+ active at a time. If you need to switch back and forth between two different sets of data,
+ it may be more efficient to store each set in different proxy and just change the active
+ proxy, rather than reset the data in one proxy every time you need to switch.
+
+ \section1 Item models and data mapping
+
+ For common use cases, Qt Data Visualization offers specialized proxies. One such case is having
+ data in an item model (QAbstractItemModel subclass), which is a common way to store data in
+ Qt applications. Each of the visualization types offers a special proxy and a corresponding mapping
+ class for this purpose, e.g. QItemModelBarDataProxy and QItemModelBarDataMapping for Q3DBars.
+ These proxies are simple to use - just give them a pointer to the item model containing the
+ data and the mapping object containing rules how to map the data into format the basic proxy can
+ digest.
+
+ Mapping objects work with item model roles. Each data item in the model can have different
+ values for different roles. For example, with QItemModelBarDataMapping you can specify which
+ role is used to determine which row the item belongs to, which role does the same for columns,
+ and which role specifies the value of the item. When the proxy resolves the data from the model,
+ it uses these mappings to generate the rows and columns of the bar graph.
+
+ Depending on the visualization type, mapping classes may support other functionality as well,
+ such as QItemModelBarDataMapping optionally mapping QAbstractItemModel rows and columns directly
+ into bar graph rows and columns. See individual mapping classes for more information and examples
+ how to use them: QItemModelBarDataMapping, QItemModelScatterDataMapping, and
+ QItemModelSurfaceDataMapping.
+
+ \section1 Other custom proxies
+
+ QHeightMapSurfaceDataProxy is a specialized proxy for generating a surface graph from a
+ heightmap image. See QHeightMapSurfaceDataProxy documentation for more information.
+
+ The \l{Custom Proxy Example}{Custom Proxy} example shows how a custom proxy can be created. It
+ defines a custom data set based on variant lists and an extension of the basic proxy to resolve
+ that data with an associated mapper.
+
+ \section1 Dealing with real-time data
+
+ When you have a data set that updates rapidly, it is important to handle data properly to
+ ensure good performance. Since memory allocation is a costly operation, always use
+ QList::reserve() and QVector::resize() where possible to avoid reallocations when constructing
+ the array to give to the proxy. If you need to change the entire data set for each frame,
+ it is in most cases best to re-use the existing array - especially if the array dimensions do not
+ change. If you need to add, insert, remove, or change several rows or items for each frame, it
+ is always more efficient to do it with one method call instead of multiple calls affecting
+ a single row or item each. For example, adding ten rows with a single QBarDataProxy::addRows() call
+ is much more efficient than ten separate QBarDataProxy::addRow() calls.
+
+ Bars renderer is optimized to access only data that is within data window and thus should not
+ suffer noticeable slowdown even if more data is continually added to the proxy.
+
+ Due to the unsorted nature of the scatter data, any change in the data window ranges requires
+ all data points to be checked for visibility, which can cause increasing slowdown if data is
+ continually added to the proxy.
+
+ Surface data, while on item level similar to scatter data, is already assigned into rows and
+ columns, so the surface renderer can do some optimization by making assumption that the data in
+ rows and columns is sorted along their respective axes, but it is nowhere near as efficient
+ as in bars case. Surface rendering can suffer significant slowdown if the data size grows unchecked.
+
+ For the best performance with the scatter and surface graphs, only keep the data you need in the
+ proxy.
+
+ \note Data handling is not yet fully optimized in the technology preview version.
+*/
+
+/*!
+ \page qtdatavisualization_interacting_with_data.html
+ \title Qt Data Visualization Interacting with Data
+
+ \section1 Interacting with data
+
+ You can interact with the rendered graph with either mouse or touch to rotate, zoom, or select
+ data. For the mouse controls, see Q3DInputHandler documentation, and for the touch controls,
+ see QTouch3DInputHandler documentation.
+
+ \note In the technology preview version, default input handlers cannot be replaced or even accessed
+ via public API. This feature is planned for the final release.
+
+ \section1 Data selection modes
+
+ All visualization types support selecting single data item - a bar, a scatter item, or a surface
+ vertex - using mouse, touch, and programmatically via the graph APIs. The selected item is highlighted
+ in the rendered graph, and selecting causes emission of a graph specific signal for this purpose,
+ e.g. Q3DBars::selectedBarPosChanged(), which the application can handle.
+
+ \note Surface graph doesn't have fully implemented selection API yet, it only supports
+ selection with mouse and touch in the technology preview version.
+
+ Bar and surface graphs support slice selection modes, where the selected row or column is drawn
+ in a separate viewport as a pseudo-2D graph. This makes it easier to see the actual values of
+ single row or column.
+
+ Bar graph additionally supports simply highlighting the whole row and/or column of the selected bar
+ without opening the slice view.
+*/
diff --git a/src/datavisualization/engine/abstract3dcontroller.cpp b/src/datavisualization/engine/abstract3dcontroller.cpp
new file mode 100644
index 00000000..bfdc375e
--- /dev/null
+++ b/src/datavisualization/engine/abstract3dcontroller.cpp
@@ -0,0 +1,1056 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 "q3dabstractaxis_p.h"
+#include "q3dvalueaxis.h"
+#include "q3dcategoryaxis.h"
+#include "abstract3drenderer_p.h"
+#include "q3dcamera.h"
+#include "q3dlight.h"
+#include "qabstractdataproxy_p.h"
+#include "qabstract3dinputhandler_p.h"
+#include "qtouch3dinputhandler.h"
+
+#include <QThread>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+Abstract3DController::Abstract3DController(QRect boundRect, QObject *parent) :
+ QObject(parent),
+ m_boundingRect(boundRect.x(), boundRect.y(), boundRect.width(), boundRect.height()),
+ m_theme(),
+ m_font(QFont(QStringLiteral("Arial"))),
+ m_selectionMode(QDataVis::SelectionModeItem),
+ m_shadowQuality(QDataVis::ShadowQualityMedium),
+ m_labelStyle(QDataVis::LabelStyleTransparent),
+ m_isBackgroundEnabled(true),
+ m_isGridEnabled(true),
+ m_scene(new Q3DScene()),
+ m_activeInputHandler(0),
+ m_axisX(0),
+ m_axisY(0),
+ m_axisZ(0),
+ m_renderer(0),
+ m_isDataDirty(true),
+ m_data(0),
+ m_renderPending(false)
+{
+ m_theme.useTheme(QDataVis::ThemeQt);
+
+ // Populate the scene
+ m_scene->activeLight()->setPosition(defaultLightPos);
+
+ // Create initial default input handler
+ QAbstract3DInputHandler *inputHandler;
+ inputHandler = new QTouch3DInputHandler();
+ inputHandler->d_ptr->m_isDefaultHandler = true;
+ setActiveInputHandler(inputHandler);
+ connect(inputHandler, &QAbstract3DInputHandler::inputStateChanged, this,
+ &Abstract3DController::emitNeedRender);
+ connect(m_scene, &Q3DScene::needRender, this,
+ &Abstract3DController::emitNeedRender);
+}
+
+Abstract3DController::~Abstract3DController()
+{
+ // Renderer can be in another thread, don't delete it directly in that case
+ if (m_renderer && m_renderer->thread() != QThread::currentThread())
+ m_renderer->deleteLater();
+ else
+ delete m_renderer;
+ delete m_scene;
+}
+
+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.boundingRectChanged || m_changeTracker.sizeChanged) {
+ m_renderer->updateBoundingRect(m_boundingRect);
+ m_changeTracker.boundingRectChanged = false;
+ m_changeTracker.sizeChanged = false;
+ }
+
+ if (m_changeTracker.positionChanged) {
+ m_renderer->updatePosition(m_boundingRect);
+ m_changeTracker.positionChanged = false;
+ }
+
+ m_renderer->updateScene(m_scene);
+
+ 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.labelStyleChanged) {
+ m_renderer->updateLabelStyle(m_labelStyle);
+ m_changeTracker.labelStyleChanged = 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(Q3DAbstractAxis::AxisOrientationX, m_axisX->type());
+ m_changeTracker.axisXTypeChanged = false;
+ }
+
+ if (m_changeTracker.axisYTypeChanged) {
+ m_renderer->updateAxisType(Q3DAbstractAxis::AxisOrientationY, m_axisY->type());
+ m_changeTracker.axisYTypeChanged = false;
+ }
+
+ if (m_changeTracker.axisZTypeChanged) {
+ m_renderer->updateAxisType(Q3DAbstractAxis::AxisOrientationZ, m_axisZ->type());
+ m_changeTracker.axisZTypeChanged = false;
+ }
+
+ if (m_changeTracker.axisXTitleChanged) {
+ m_renderer->updateAxisTitle(Q3DAbstractAxis::AxisOrientationX, m_axisX->title());
+ m_changeTracker.axisXTitleChanged = false;
+ }
+
+ if (m_changeTracker.axisYTitleChanged) {
+ m_renderer->updateAxisTitle(Q3DAbstractAxis::AxisOrientationY, m_axisY->title());
+ m_changeTracker.axisYTitleChanged = false;
+ }
+
+ if (m_changeTracker.axisZTitleChanged) {
+ m_renderer->updateAxisTitle(Q3DAbstractAxis::AxisOrientationZ, m_axisZ->title());
+ m_changeTracker.axisZTitleChanged = false;
+ }
+
+ if (m_changeTracker.axisXLabelsChanged) {
+ m_renderer->updateAxisLabels(Q3DAbstractAxis::AxisOrientationX, m_axisX->labels());
+ m_changeTracker.axisXLabelsChanged = false;
+ }
+
+ if (m_changeTracker.axisYLabelsChanged) {
+ m_renderer->updateAxisLabels(Q3DAbstractAxis::AxisOrientationY, m_axisY->labels());
+ m_changeTracker.axisYLabelsChanged = false;
+ }
+ if (m_changeTracker.axisZLabelsChanged) {
+ m_renderer->updateAxisLabels(Q3DAbstractAxis::AxisOrientationZ, m_axisZ->labels());
+ m_changeTracker.axisZLabelsChanged = false;
+ }
+
+ if (m_changeTracker.axisXRangeChanged) {
+ m_renderer->updateAxisRange(Q3DAbstractAxis::AxisOrientationX, m_axisX->min(),
+ m_axisX->max());
+ m_changeTracker.axisXRangeChanged = false;
+ }
+
+ if (m_changeTracker.axisYRangeChanged) {
+ m_renderer->updateAxisRange(Q3DAbstractAxis::AxisOrientationY, m_axisY->min(),
+ m_axisY->max());
+ m_changeTracker.axisYRangeChanged = false;
+ }
+
+ if (m_changeTracker.axisZRangeChanged) {
+ m_renderer->updateAxisRange(Q3DAbstractAxis::AxisOrientationZ, m_axisZ->min(),
+ m_axisZ->max());
+ m_changeTracker.axisZRangeChanged = false;
+ }
+
+ if (m_changeTracker.axisXSegmentCountChanged) {
+ m_changeTracker.axisXSegmentCountChanged = false;
+ if (m_axisX->type() & Q3DAbstractAxis::AxisTypeValue) {
+ Q3DValueAxis *valueAxisX = static_cast<Q3DValueAxis *>(m_axisX);
+ m_renderer->updateAxisSegmentCount(Q3DAbstractAxis::AxisOrientationX,
+ valueAxisX->segmentCount());
+ }
+ }
+
+ if (m_changeTracker.axisYSegmentCountChanged) {
+ m_changeTracker.axisYSegmentCountChanged = false;
+ if (m_axisY->type() & Q3DAbstractAxis::AxisTypeValue) {
+ Q3DValueAxis *valueAxisY = static_cast<Q3DValueAxis *>(m_axisY);
+ m_renderer->updateAxisSegmentCount(Q3DAbstractAxis::AxisOrientationY,
+ valueAxisY->segmentCount());
+ }
+ }
+
+ if (m_changeTracker.axisZSegmentCountChanged) {
+ m_changeTracker.axisZSegmentCountChanged = false;
+ if (m_axisZ->type() & Q3DAbstractAxis::AxisTypeValue) {
+ Q3DValueAxis *valueAxisZ = static_cast<Q3DValueAxis *>(m_axisZ);
+ m_renderer->updateAxisSegmentCount(Q3DAbstractAxis::AxisOrientationZ,
+ valueAxisZ->segmentCount());
+ }
+ }
+
+ if (m_changeTracker.axisXSubSegmentCountChanged) {
+ m_changeTracker.axisXSubSegmentCountChanged = false;
+ if (m_axisX->type() & Q3DAbstractAxis::AxisTypeValue) {
+ Q3DValueAxis *valueAxisX = static_cast<Q3DValueAxis *>(m_axisX);
+ m_renderer->updateAxisSubSegmentCount(Q3DAbstractAxis::AxisOrientationX,
+ valueAxisX->subSegmentCount());
+ }
+ }
+
+ if (m_changeTracker.axisYSubSegmentCountChanged) {
+ m_changeTracker.axisYSubSegmentCountChanged = false;
+ if (m_axisY->type() & Q3DAbstractAxis::AxisTypeValue) {
+ Q3DValueAxis *valueAxisY = static_cast<Q3DValueAxis *>(m_axisY);
+ m_renderer->updateAxisSubSegmentCount(Q3DAbstractAxis::AxisOrientationY,
+ valueAxisY->subSegmentCount());
+ }
+ }
+
+ if (m_changeTracker.axisZSubSegmentCountChanged) {
+ m_changeTracker.axisZSubSegmentCountChanged = false;
+ if (m_axisZ->type() & Q3DAbstractAxis::AxisTypeValue) {
+ Q3DValueAxis *valueAxisZ = static_cast<Q3DValueAxis *>(m_axisZ);
+ m_renderer->updateAxisSubSegmentCount(Q3DAbstractAxis::AxisOrientationZ,
+ valueAxisZ->subSegmentCount());
+ }
+ }
+
+ if (m_changeTracker.axisXLabelFormatChanged) {
+ m_changeTracker.axisXLabelFormatChanged = false;
+ if (m_axisX->type() & Q3DAbstractAxis::AxisTypeValue) {
+ Q3DValueAxis *valueAxisX = static_cast<Q3DValueAxis *>(m_axisX);
+ m_renderer->updateAxisLabelFormat(Q3DAbstractAxis::AxisOrientationX,
+ valueAxisX->labelFormat());
+ }
+ }
+
+ if (m_changeTracker.axisYLabelFormatChanged) {
+ m_changeTracker.axisYLabelFormatChanged = false;
+ if (m_axisY->type() & Q3DAbstractAxis::AxisTypeValue) {
+ Q3DValueAxis *valueAxisY = static_cast<Q3DValueAxis *>(m_axisY);
+ m_renderer->updateAxisLabelFormat(Q3DAbstractAxis::AxisOrientationY,
+ valueAxisY->labelFormat());
+ }
+ }
+
+ if (m_changeTracker.axisZLabelFormatChanged) {
+ m_changeTracker.axisZLabelFormatChanged = false;
+ if (m_axisZ->type() & Q3DAbstractAxis::AxisTypeValue) {
+ Q3DValueAxis *valueAxisZ = static_cast<Q3DValueAxis *>(m_axisZ);
+ m_renderer->updateAxisLabelFormat(Q3DAbstractAxis::AxisOrientationZ,
+ valueAxisZ->labelFormat());
+ }
+ }
+}
+
+void Abstract3DController::render(const GLuint defaultFboHandle)
+{
+ m_renderPending = false;
+
+ // If not initialized, do nothing.
+ if (!m_renderer)
+ return;
+
+ m_renderer->render(defaultFboHandle);
+
+#ifdef DISPLAY_RENDER_SPEED
+ // To get meaningful framerate, don't just do render on demand.
+ emitNeedRender();
+#endif
+}
+
+void Abstract3DController::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ if (m_activeInputHandler)
+ m_activeInputHandler->mouseDoubleClickEvent(event);
+
+ emitNeedRender();
+}
+
+void Abstract3DController::touchEvent(QTouchEvent *event)
+{
+ if (m_activeInputHandler)
+ m_activeInputHandler->touchEvent(event);
+
+ emitNeedRender();
+}
+
+void Abstract3DController::mousePressEvent(QMouseEvent *event, const QPoint &mousePos)
+{
+ if (m_activeInputHandler)
+ m_activeInputHandler->mousePressEvent(event, mousePos);
+
+ emitNeedRender();
+}
+
+void Abstract3DController::mouseReleaseEvent(QMouseEvent *event, const QPoint &mousePos)
+{
+ if (m_activeInputHandler)
+ m_activeInputHandler->mouseReleaseEvent(event, mousePos);
+
+ emitNeedRender();
+}
+
+void Abstract3DController::mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos)
+{
+ if (m_activeInputHandler)
+ m_activeInputHandler->mouseMoveEvent(event, mousePos);
+
+ emitNeedRender();
+}
+
+void Abstract3DController::wheelEvent(QWheelEvent *event)
+{
+ if (m_activeInputHandler)
+ m_activeInputHandler->wheelEvent(event);
+
+ emitNeedRender();
+}
+
+void Abstract3DController::setSize(const int width, const int height)
+{
+ m_boundingRect.setWidth(width);
+ m_boundingRect.setHeight(height);
+ m_scene->setViewportSize(width, height);
+
+ m_changeTracker.boundingRectChanged = true;
+ emitNeedRender();
+}
+
+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_scene->setViewport(boundingRect);
+
+ m_changeTracker.boundingRectChanged = true;
+ emitNeedRender();
+}
+
+void Abstract3DController::setWidth(const int width)
+{
+ m_boundingRect.setWidth(width);
+ m_scene->setViewportSize(width, m_scene->viewport().height());
+
+ m_changeTracker.sizeChanged = true;
+ emitNeedRender();
+}
+
+int Abstract3DController::width()
+{
+ return m_boundingRect.width();
+}
+
+void Abstract3DController::setHeight(const int height)
+{
+ m_boundingRect.setHeight(height);
+ m_scene->setViewportSize(m_scene->viewport().width(), height);
+
+ m_changeTracker.sizeChanged = true;
+ emitNeedRender();
+}
+
+int Abstract3DController::height()
+{
+ return m_boundingRect.height();
+}
+
+void Abstract3DController::setX(const int x)
+{
+ m_boundingRect.setX(x);
+
+ m_changeTracker.positionChanged = true;
+ emitNeedRender();
+}
+
+int Abstract3DController::x()
+{
+ return m_boundingRect.x();
+}
+
+void Abstract3DController::setY(const int y)
+{
+ m_boundingRect.setY(y);
+
+ m_changeTracker.positionChanged = true;
+ emitNeedRender();
+}
+
+int Abstract3DController::y()
+{
+ return m_boundingRect.y();
+}
+
+QRect Abstract3DController::primarySubViewport() const
+{
+ return m_scene->primarySubViewport();
+}
+
+void Abstract3DController::setPrimarySubViewport(const QRect &primarySubViewport)
+{
+ m_scene->setPrimarySubViewport(primarySubViewport);
+}
+
+QRect Abstract3DController::secondarySubViewport() const
+{
+ return m_scene->secondarySubViewport();
+}
+
+void Abstract3DController::setSecondarySubViewport(const QRect &secondarySubViewport)
+{
+ m_scene->setSecondarySubViewport(secondarySubViewport);
+}
+
+void Abstract3DController::updateDevicePixelRatio(qreal ratio)
+{
+ m_scene->setDevicePixelRatio(ratio);
+}
+
+void Abstract3DController::setAxisX(Q3DAbstractAxis *axis)
+{
+ setAxisHelper(Q3DAbstractAxis::AxisOrientationX, axis, &m_axisX);
+}
+
+Q3DAbstractAxis *Abstract3DController::axisX()
+{
+ return m_axisX;
+}
+
+void Abstract3DController::setAxisY(Q3DAbstractAxis *axis)
+{
+ setAxisHelper(Q3DAbstractAxis::AxisOrientationY, axis, &m_axisY);
+}
+
+Q3DAbstractAxis *Abstract3DController::axisY()
+{
+ return m_axisY;
+}
+
+void Abstract3DController::setAxisZ(Q3DAbstractAxis *axis)
+{
+ setAxisHelper(Q3DAbstractAxis::AxisOrientationZ, axis, &m_axisZ);
+}
+
+Q3DAbstractAxis *Abstract3DController::axisZ()
+{
+ return m_axisZ;
+}
+
+void Abstract3DController::addAxis(Q3DAbstractAxis *axis)
+{
+ Q_ASSERT(axis);
+ Abstract3DController *owner = qobject_cast<Abstract3DController *>(axis->parent());
+ if (owner != this) {
+ Q_ASSERT_X(!owner, "addAxis", "Axis already attached to a graph.");
+ axis->setParent(this);
+ }
+ if (!m_axes.contains(axis))
+ m_axes.append(axis);
+}
+
+void Abstract3DController::releaseAxis(Q3DAbstractAxis *axis)
+{
+ if (axis && m_axes.contains(axis)) {
+ // Clear the default status from released default axes
+ if (axis->d_ptr->isDefaultAxis())
+ axis->d_ptr->setDefaultAxis(false);
+
+ // If the axis is in use, replace it with a temporary one
+ switch (axis->orientation()) {
+ case Q3DAbstractAxis::AxisOrientationX:
+ setAxisX(0);
+ break;
+ case Q3DAbstractAxis::AxisOrientationY:
+ setAxisY(0);
+ break;
+ case Q3DAbstractAxis::AxisOrientationZ:
+ setAxisZ(0);
+ break;
+ default:
+ break;
+ }
+
+ m_axes.removeAll(axis);
+ axis->setParent(0);
+ }
+}
+
+QList<Q3DAbstractAxis *> Abstract3DController::axes() const
+{
+ return m_axes;
+}
+
+QAbstractDataProxy *Abstract3DController::activeDataProxy() const
+{
+ return m_data;
+}
+
+void Abstract3DController::addDataProxy(QAbstractDataProxy *proxy)
+{
+ Q_ASSERT(proxy);
+ Abstract3DController *owner = qobject_cast<Abstract3DController *>(proxy->parent());
+ if (owner != this) {
+ Q_ASSERT_X(!owner, "addDataProxy", "Proxy already attached to a graph.");
+ proxy->setParent(this);
+ }
+ if (!m_dataProxies.contains(proxy))
+ m_dataProxies.append(proxy);
+}
+
+void Abstract3DController::releaseDataProxy(QAbstractDataProxy *proxy)
+{
+ if (proxy && m_dataProxies.contains(proxy)) {
+ // Clear the default status from released default proxies
+ if (proxy->d_ptr->isDefaultProxy())
+ proxy->d_ptr->setDefaultProxy(false);
+
+ // If the proxy is in use, replace it with a temporary one
+ if (m_data == proxy)
+ setActiveDataProxy(0);
+
+ m_dataProxies.removeAll(proxy);
+ proxy->setParent(0);
+ }
+}
+
+QList<QAbstractDataProxy *> Abstract3DController::dataProxies() const
+{
+ return m_dataProxies;
+}
+
+void Abstract3DController::setActiveDataProxy(QAbstractDataProxy *proxy)
+{
+ // If existing proxy is the default proxy, delete it
+ if (m_data) {
+ if (m_data->d_ptr->isDefaultProxy()) {
+ m_dataProxies.removeAll(m_data);
+ delete m_data;
+ } else {
+ // Disconnect the old proxy from use
+ QObject::disconnect(m_data, 0, this, 0);
+ }
+ }
+
+ // Assume ownership and activate
+ addDataProxy(proxy);
+ m_data = proxy;
+ m_isDataDirty = true;
+ emitNeedRender();
+}
+
+void Abstract3DController::addInputHandler(QAbstract3DInputHandler *inputHandler)
+{
+ Q_ASSERT(inputHandler);
+ Abstract3DController *owner = qobject_cast<Abstract3DController *>(inputHandler->parent());
+ if (owner != this) {
+ Q_ASSERT_X(!owner, "addInputHandler", "Input handler already attached to another component.");
+ inputHandler->setParent(this);
+ }
+
+ if (!m_inputHandlers.contains(inputHandler))
+ m_inputHandlers.append(inputHandler);
+}
+
+void Abstract3DController::releaseInputHandler(QAbstract3DInputHandler *inputHandler)
+{
+ if (inputHandler && m_inputHandlers.contains(inputHandler)) {
+ // Clear the default status from released default input handler
+ if (inputHandler->d_ptr->m_isDefaultHandler)
+ inputHandler->d_ptr->m_isDefaultHandler = false;
+
+ // If the input handler is in use, remove it
+ if (m_activeInputHandler == inputHandler)
+ setActiveInputHandler(0);
+
+ m_inputHandlers.removeAll(inputHandler);
+ inputHandler->setParent(0);
+ }
+}
+
+void Abstract3DController::setActiveInputHandler(QAbstract3DInputHandler *inputHandler)
+{
+ if (inputHandler == m_activeInputHandler)
+ return;
+
+ // If existing input handler is the default input handler, delete it
+ if (m_activeInputHandler) {
+ if (m_activeInputHandler->d_ptr->m_isDefaultHandler) {
+ m_inputHandlers.removeAll(m_activeInputHandler);
+ delete m_activeInputHandler;
+ } else {
+ // Disconnect the old input handler from the scene
+ m_activeInputHandler->setScene(0);
+ }
+ }
+
+ // Assume ownership and connect to this controller's scene
+ if (inputHandler)
+ addInputHandler(inputHandler);
+
+ m_activeInputHandler = inputHandler;
+ if (m_activeInputHandler)
+ m_activeInputHandler->setScene(m_scene);
+
+ // Notify change of input handler
+ emit activeInputHandlerChanged(m_activeInputHandler);
+}
+
+QAbstract3DInputHandler* Abstract3DController::activeInputHandler()
+{
+ return m_activeInputHandler;
+}
+
+int Abstract3DController::zoomLevel()
+{
+ return m_scene->activeCamera()->zoomLevel();
+}
+
+void Abstract3DController::setZoomLevel(int zoomLevel)
+{
+ m_scene->activeCamera()->setZoomLevel(zoomLevel);
+
+ m_changeTracker.zoomLevelChanged = true;
+ emitNeedRender();
+}
+
+void Abstract3DController::setObjectColor(const QColor &baseColor, bool uniform)
+{
+ m_theme.m_baseColor = baseColor;
+ m_theme.m_uniformColor = uniform;
+
+ m_changeTracker.themeChanged = true;
+ emitNeedRender();
+}
+
+QColor Abstract3DController::objectColor() const
+{
+ return m_theme.m_baseColor;
+}
+
+void Abstract3DController::setTheme(QDataVis::Theme theme)
+{
+ m_theme.useTheme(theme);
+
+ m_changeTracker.themeChanged = true;
+ emitNeedRender();
+}
+
+Theme Abstract3DController::theme()
+{
+ return m_theme;
+}
+
+void Abstract3DController::setFont(const QFont &font)
+{
+ m_font = font;
+
+ m_changeTracker.fontChanged = true;
+ emitNeedRender();
+}
+
+QFont Abstract3DController::font()
+{
+ return m_font;
+}
+
+void Abstract3DController::setSelectionMode(QDataVis::SelectionMode mode)
+{
+ m_selectionMode = mode;
+ m_changeTracker.selectionModeChanged = true;
+ emitNeedRender();
+}
+
+QDataVis::SelectionMode Abstract3DController::selectionMode()
+{
+ return m_selectionMode;
+}
+
+void Abstract3DController::setShadowQuality(QDataVis::ShadowQuality quality)
+{
+ m_shadowQuality = quality;
+
+ m_changeTracker.shadowQualityChanged = true;
+ emit shadowQualityChanged(m_shadowQuality);
+ emitNeedRender();
+}
+
+QDataVis::ShadowQuality Abstract3DController::shadowQuality()
+{
+ return m_shadowQuality;
+}
+
+void Abstract3DController::setLabelStyle(QDataVis::LabelStyle style)
+{
+ m_labelStyle = style;
+
+ m_changeTracker.labelStyleChanged = true;
+ emitNeedRender();
+}
+
+QDataVis::LabelStyle Abstract3DController::labelStyle()
+{
+ return m_labelStyle;
+}
+
+void Abstract3DController::setBackgroundEnabled(bool enable)
+{
+ m_isBackgroundEnabled = enable;
+ m_changeTracker.backgroundEnabledChanged = true;
+ emitNeedRender();
+}
+
+bool Abstract3DController::backgroundEnabled()
+{
+ return m_isBackgroundEnabled;
+}
+
+void Abstract3DController::setGridEnabled(bool enable)
+{
+ m_isGridEnabled = enable;
+ m_changeTracker.gridEnabledChanged = true;
+ emitNeedRender();
+}
+
+bool Abstract3DController::gridEnabled()
+{
+ return m_isGridEnabled;
+}
+
+bool Abstract3DController::isSlicingActive()
+{
+ return m_scene->isSlicingActive();
+}
+
+void Abstract3DController::setSlicingActive(bool isSlicing)
+{
+ m_scene->setSlicingActive(isSlicing);
+ emitNeedRender();
+}
+
+QDataVis::InputState Abstract3DController::inputState()
+{
+ if (m_activeInputHandler)
+ return m_activeInputHandler->inputState();
+ else
+ return QDataVis::InputStateNone;
+}
+
+QPoint Abstract3DController::inputPosition()
+{
+ if (m_activeInputHandler)
+ return m_activeInputHandler->inputPosition();
+ else
+ return QPoint(0,0);
+}
+
+void Abstract3DController::setMeshFileName(const QString &fileName)
+{
+ m_objFile = fileName;
+ m_changeTracker.objFileChanged = true;
+ emitNeedRender();
+}
+
+QString Abstract3DController::meshFileName()
+{
+ return m_objFile;
+}
+
+Q3DScene *Abstract3DController::scene()
+{
+ return m_scene;
+}
+
+void Abstract3DController::handleAxisTitleChanged(const QString &title)
+{
+ Q_UNUSED(title)
+ handleAxisTitleChangedBySender(sender());
+}
+
+void Abstract3DController::handleAxisTitleChangedBySender(QObject *sender)
+{
+ if (sender == m_axisX)
+ m_changeTracker.axisXTitleChanged = true;
+ else if (sender == m_axisY)
+ m_changeTracker.axisYTitleChanged = true;
+ else if (sender == m_axisZ)
+ m_changeTracker.axisZTitleChanged = true;
+ else
+ qWarning() << __FUNCTION__ << "invoked for invalid axis";
+ emitNeedRender();
+}
+
+void Abstract3DController::handleAxisLabelsChanged()
+{
+ handleAxisLabelsChangedBySender(sender());
+}
+
+void Abstract3DController::handleAxisLabelsChangedBySender(QObject *sender)
+{
+ if (sender == m_axisX)
+ m_changeTracker.axisXLabelsChanged = true;
+ else if (sender == m_axisY)
+ m_changeTracker.axisYLabelsChanged = true;
+ else if (sender == m_axisZ)
+ m_changeTracker.axisZLabelsChanged = true;
+ else
+ qWarning() << __FUNCTION__ << "invoked for invalid axis";
+ emitNeedRender();
+}
+
+void Abstract3DController::handleAxisRangeChanged(qreal min, qreal max)
+{
+ Q_UNUSED(min)
+ Q_UNUSED(max)
+ handleAxisRangeChangedBySender(sender());
+}
+
+void Abstract3DController::handleAxisRangeChangedBySender(QObject *sender)
+{
+ if (sender == m_axisX) {
+ m_isDataDirty = true;
+ m_changeTracker.axisXRangeChanged = true;
+ } else if (sender == m_axisY) {
+ m_isDataDirty = true;
+ m_changeTracker.axisYRangeChanged = true;
+ } else if (sender == m_axisZ) {
+ m_isDataDirty = true;
+ m_changeTracker.axisZRangeChanged = true;
+ } else {
+ qWarning() << __FUNCTION__ << "invoked for invalid axis";
+ }
+ emitNeedRender();
+}
+
+void Abstract3DController::handleAxisSegmentCountChanged(int count)
+{
+ Q_UNUSED(count)
+ handleAxisSegmentCountChangedBySender(sender());
+}
+
+void Abstract3DController::handleAxisSegmentCountChangedBySender(QObject *sender)
+{
+ if (sender == m_axisX)
+ m_changeTracker.axisXSegmentCountChanged = true;
+ else if (sender == m_axisY)
+ m_changeTracker.axisYSegmentCountChanged = true;
+ else if (sender == m_axisZ)
+ m_changeTracker.axisZSegmentCountChanged = true;
+ else
+ qWarning() << __FUNCTION__ << "invoked for invalid axis";
+ emitNeedRender();
+}
+
+void Abstract3DController::handleAxisSubSegmentCountChanged(int count)
+{
+ Q_UNUSED(count)
+ handleAxisSubSegmentCountChangedBySender(sender());
+}
+
+void Abstract3DController::handleAxisSubSegmentCountChangedBySender(QObject *sender)
+{
+ if (sender == m_axisX)
+ m_changeTracker.axisXSubSegmentCountChanged = true;
+ else if (sender == m_axisY)
+ m_changeTracker.axisYSubSegmentCountChanged = true;
+ else if (sender == m_axisZ)
+ m_changeTracker.axisZSubSegmentCountChanged = true;
+ else
+ qWarning() << __FUNCTION__ << "invoked for invalid axis";
+ emitNeedRender();
+}
+
+void Abstract3DController::handleAxisAutoAdjustRangeChanged(bool autoAdjust)
+{
+ QObject *sender = QObject::sender();
+ if (sender != m_axisX && sender != m_axisY && sender != m_axisZ)
+ return;
+
+ Q3DAbstractAxis *axis = static_cast<Q3DAbstractAxis*>(sender);
+ handleAxisAutoAdjustRangeChangedInOrientation(axis->orientation(), autoAdjust);
+}
+
+void Abstract3DController::handleAxisLabelFormatChanged(const QString &format)
+{
+ Q_UNUSED(format)
+ handleAxisLabelFormatChangedBySender(sender());
+}
+
+void Abstract3DController::handleAxisLabelFormatChangedBySender(QObject *sender)
+{
+ // Label format changing needs to dirty the data so that labels are reset.
+ if (sender == m_axisX) {
+ m_isDataDirty = true;
+ m_changeTracker.axisXLabelFormatChanged = true;
+ } else if (sender == m_axisY) {
+ m_isDataDirty = true;
+ m_changeTracker.axisYLabelFormatChanged = true;
+ } else if (sender == m_axisZ) {
+ m_isDataDirty = true;
+ m_changeTracker.axisZLabelFormatChanged = true;
+ } else {
+ qWarning() << __FUNCTION__ << "invoked for invalid axis";
+ }
+ emitNeedRender();
+}
+
+void Abstract3DController::setAxisHelper(Q3DAbstractAxis::AxisOrientation orientation,
+ Q3DAbstractAxis *axis, Q3DAbstractAxis **axisPtr)
+{
+ // Setting null axis indicates using default axis
+ if (!axis)
+ axis = createDefaultAxis(orientation);
+
+ // If old axis is default axis, delete it
+ Q3DAbstractAxis *oldAxis = *axisPtr;
+ if (oldAxis) {
+ if (oldAxis->d_ptr->isDefaultAxis()) {
+ m_axes.removeAll(oldAxis);
+ delete oldAxis;
+ oldAxis = 0;
+ } else {
+ // Disconnect the old axis from use
+ QObject::disconnect(oldAxis, 0, this, 0);
+ oldAxis->d_ptr->setOrientation(Q3DAbstractAxis::AxisOrientationNone);
+ }
+ }
+
+ // Assume ownership
+ addAxis(axis);
+
+ // Connect the new axis
+ *axisPtr = axis;
+
+ axis->d_ptr->setOrientation(orientation);
+
+ QObject::connect(axis, &Q3DAbstractAxis::titleChanged,
+ this, &Abstract3DController::handleAxisTitleChanged);
+ QObject::connect(axis, &Q3DAbstractAxis::labelsChanged,
+ this, &Abstract3DController::handleAxisLabelsChanged);
+ QObject::connect(axis, &Q3DAbstractAxis::rangeChanged,
+ this, &Abstract3DController::handleAxisRangeChanged);
+ QObject::connect(axis, &Q3DAbstractAxis::autoAdjustRangeChanged,
+ this, &Abstract3DController::handleAxisAutoAdjustRangeChanged);
+
+ if (orientation == Q3DAbstractAxis::AxisOrientationX)
+ m_changeTracker.axisXTypeChanged = true;
+ else if (orientation == Q3DAbstractAxis::AxisOrientationY)
+ m_changeTracker.axisYTypeChanged = true;
+ else if (orientation == Q3DAbstractAxis::AxisOrientationZ)
+ m_changeTracker.axisZTypeChanged = true;
+
+ handleAxisTitleChangedBySender(axis);
+ handleAxisLabelsChangedBySender(axis);
+ handleAxisRangeChangedBySender(axis);
+ handleAxisAutoAdjustRangeChangedInOrientation(axis->orientation(),
+ axis->isAutoAdjustRange());
+
+ if (axis->type() & Q3DAbstractAxis::AxisTypeValue) {
+ Q3DValueAxis *valueAxis = static_cast<Q3DValueAxis *>(axis);
+ QObject::connect(valueAxis, &Q3DValueAxis::segmentCountChanged,
+ this, &Abstract3DController::handleAxisSegmentCountChanged);
+ QObject::connect(valueAxis, &Q3DValueAxis::subSegmentCountChanged,
+ this, &Abstract3DController::handleAxisSubSegmentCountChanged);
+ QObject::connect(valueAxis, &Q3DValueAxis::labelFormatChanged,
+ this, &Abstract3DController::handleAxisLabelFormatChanged);
+
+ handleAxisSegmentCountChangedBySender(valueAxis);
+ handleAxisSubSegmentCountChangedBySender(valueAxis);
+ handleAxisLabelFormatChangedBySender(valueAxis);
+ }
+}
+
+Q3DAbstractAxis *Abstract3DController::createDefaultAxis(Q3DAbstractAxis::AxisOrientation orientation)
+{
+ Q_UNUSED(orientation)
+
+ // The default default axis is a value axis. If the graph type has a different default axis
+ // for some orientation, this function needs to be overridden.
+ Q3DAbstractAxis *defaultAxis = createDefaultValueAxis();
+ return defaultAxis;
+}
+
+Q3DValueAxis *Abstract3DController::createDefaultValueAxis()
+{
+ // Default value axis has single segment, empty label format, and auto scaling
+ // TODO: Grid should be also hidden, but that is not currently controlled by axis
+ Q3DValueAxis *defaultAxis = new Q3DValueAxis;
+ defaultAxis->setSegmentCount(1);
+ defaultAxis->setSubSegmentCount(1);
+ defaultAxis->setAutoAdjustRange(true);
+ defaultAxis->setLabelFormat(QString());
+ defaultAxis->d_ptr->setDefaultAxis(true);
+
+ return defaultAxis;
+}
+
+Q3DCategoryAxis *Abstract3DController::createDefaultCategoryAxis()
+{
+ // Default category axis has no labels
+ // TODO: Grid should be also hidden, but that is not currently controlled by axis.
+ Q3DCategoryAxis *defaultAxis = new Q3DCategoryAxis;
+ defaultAxis->setAutoAdjustRange(true);
+ defaultAxis->d_ptr->setDefaultAxis(true);
+ return defaultAxis;
+}
+
+void Abstract3DController::emitNeedRender()
+{
+ if (!m_renderPending) {
+ emit needRender();
+ m_renderPending = true;
+ }
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavis3d/engine/abstract3dcontroller_p.h b/src/datavisualization/engine/abstract3dcontroller_p.h
index 8f21c97f..f17c6c4d 100644
--- a/src/datavis3d/engine/abstract3dcontroller_p.h
+++ b/src/datavisualization/engine/abstract3dcontroller_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -29,16 +29,20 @@
#ifndef CONTROLLER3DBASE_H
#define CONTROLLER3DBASE_H
-#include <QObject>
-
-#include "datavis3dglobal_p.h"
+#include "datavisualizationglobal_p.h"
#include "theme_p.h"
-#include "qabstractaxis.h"
+#include "q3dabstractaxis.h"
#include "drawer_p.h"
+#include "qabstract3dinputhandler.h"
+#include "qabstractdataproxy.h"
+#include "q3dscene.h"
+#include "q3dbox.h"
+
+#include <QObject>
class QFont;
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
class CameraHelper;
class Abstract3DRenderer;
@@ -48,7 +52,7 @@ struct Abstract3DChangeBitField {
bool zoomLevelChanged : 1;
bool themeChanged : 1;
bool fontChanged : 1;
- bool labelTransparencyChanged : 1;
+ bool labelStyleChanged : 1;
bool boundingRectChanged : 1;
bool sizeChanged : 1;
bool shadowQualityChanged : 1;
@@ -74,13 +78,16 @@ struct Abstract3DChangeBitField {
bool axisXSubSegmentCountChanged : 1;
bool axisYSubSegmentCountChanged : 1;
bool axisZSubSegmentCountChanged : 1;
+ bool axisXLabelFormatChanged : 1;
+ bool axisYLabelFormatChanged : 1;
+ bool axisZLabelFormatChanged : 1;
Abstract3DChangeBitField() :
positionChanged(true),
zoomLevelChanged(true),
themeChanged(true),
fontChanged(true),
- labelTransparencyChanged(true),
+ labelStyleChanged(true),
boundingRectChanged(true),
sizeChanged(true),
shadowQualityChanged(true),
@@ -105,12 +112,15 @@ struct Abstract3DChangeBitField {
axisZSegmentCountChanged(true),
axisXSubSegmentCountChanged(true),
axisYSubSegmentCountChanged(true),
- axisZSubSegmentCountChanged(true)
+ axisZSubSegmentCountChanged(true),
+ axisXLabelFormatChanged(true),
+ axisYLabelFormatChanged(true),
+ axisZLabelFormatChanged(true)
{
}
};
-class QT_DATAVIS3D_EXPORT Abstract3DController : public QObject
+class QT_DATAVISUALIZATION_EXPORT Abstract3DController : public QObject
{
Q_OBJECT
@@ -140,22 +150,33 @@ private:
QFont m_font;
QDataVis::SelectionMode m_selectionMode;
QDataVis::ShadowQuality m_shadowQuality;
- QDataVis::LabelTransparency m_labelTransparency;
+ QDataVis::LabelStyle m_labelStyle;
bool m_isBackgroundEnabled;
bool m_isGridEnabled;
QString m_objFile;
+ Q3DScene *m_scene;
+
protected:
+ QList<QAbstract3DInputHandler *> m_inputHandlers; // List of all added input handlers
+ QAbstract3DInputHandler *m_activeInputHandler;
CameraHelper *m_cameraHelper;
- int m_zoomLevel;
- QAbstractAxis *m_axisX;
- QAbstractAxis *m_axisY;
- QAbstractAxis *m_axisZ;
+ // Active axes
+ Q3DAbstractAxis *m_axisX;
+ Q3DAbstractAxis *m_axisY;
+ Q3DAbstractAxis *m_axisZ;
+
+ QList<Q3DAbstractAxis *> m_axes; // List of all added axes
Abstract3DRenderer *m_renderer;
bool m_isDataDirty;
+ QAbstractDataProxy *m_data;
+ QList<QAbstractDataProxy *> m_dataProxies;
+
+ bool m_renderPending;
+
explicit Abstract3DController(QRect boundRect, QObject *parent = 0);
- ~Abstract3DController();
+ virtual ~Abstract3DController();
public:
@@ -166,7 +187,6 @@ public:
*/
virtual void synchDataToRenderer();
-
virtual void render(const GLuint defaultFboHandle = 0);
/**
@@ -188,38 +208,47 @@ public:
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 QRect primarySubViewport() const;
+ virtual void setPrimarySubViewport(const QRect &primarySubViewport);
+
+ virtual QRect secondarySubViewport() const;
+ virtual void setSecondarySubViewport(const QRect &secondarySubViewport);
+
+ virtual void setAxisX(Q3DAbstractAxis *axis);
+ virtual Q3DAbstractAxis *axisX();
+ virtual void setAxisY(Q3DAbstractAxis *axis);
+ virtual Q3DAbstractAxis *axisY();
+ virtual void setAxisZ(Q3DAbstractAxis *axis);
+ virtual Q3DAbstractAxis *axisZ();
+ virtual void addAxis(Q3DAbstractAxis *axis);
+ virtual void releaseAxis(Q3DAbstractAxis *axis);
+ virtual QList<Q3DAbstractAxis *> axes() const; // Omits default axes
+
+ virtual void addInputHandler(QAbstract3DInputHandler *inputHandler);
+ virtual void releaseInputHandler(QAbstract3DInputHandler *inputHandler);
+ virtual void setActiveInputHandler(QAbstract3DInputHandler *inputHandler);
+ virtual QAbstract3DInputHandler *activeInputHandler();
+
+ virtual QAbstractDataProxy *activeDataProxy() const;
+ virtual void addDataProxy(QAbstractDataProxy *proxy);
+ virtual void releaseDataProxy(QAbstractDataProxy *proxy);
+ virtual QList<QAbstractDataProxy *> dataProxies() const;
+ virtual void setActiveDataProxy(QAbstractDataProxy *proxy);
+ virtual void updateDevicePixelRatio(qreal ratio);
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 color if you don't want to use themes.
+ virtual void setObjectColor(const QColor &baseColor, bool uniform = true);
+ virtual QColor objectColor() const;
// Set theme (bar colors, shaders, window color, background colors, light intensity and text
// colors are affected)
- virtual void setColorTheme(QDataVis::ColorTheme colorTheme);
+ virtual void setTheme(QDataVis::Theme theme);
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();
@@ -232,9 +261,9 @@ public:
virtual void setShadowQuality(QDataVis::ShadowQuality quality);
virtual QDataVis::ShadowQuality shadowQuality();
- // Label transparency adjustment
- virtual void setLabelTransparency(QDataVis::LabelTransparency transparency);
- virtual QDataVis::LabelTransparency labelTransparency();
+ // Label style adjustment
+ virtual void setLabelStyle(QDataVis::LabelStyle style);
+ virtual QDataVis::LabelStyle labelStyle();
// Enable or disable background mesh
virtual void setBackgroundEnabled(bool enable);
@@ -244,16 +273,36 @@ public:
virtual void setGridEnabled(bool enable);
virtual bool gridEnabled();
+ // Query input state and position
+ QDataVis::InputState inputState();
+ QPoint inputPosition();
+
+ // Enable or disable slicing mode
+ bool isSlicingActive();
+ void setSlicingActive(bool isSlicing);
+
+
// override bar type with own mesh
virtual void setMeshFileName(const QString &fileName);
virtual QString meshFileName();
- virtual void handleAxisTitleChangedBySender(QObject *sender, const QString &title);
+ Q3DScene *scene();
+
+ virtual void mouseDoubleClickEvent(QMouseEvent *event);
+ virtual void touchEvent(QTouchEvent *event);
+ virtual void mousePressEvent(QMouseEvent *event, const QPoint &mousePos);
+ virtual void mouseReleaseEvent(QMouseEvent *event, const QPoint &mousePos);
+ virtual void mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos);
+ virtual void wheelEvent(QWheelEvent *event);
+
+ virtual void handleAxisTitleChangedBySender(QObject *sender);
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;
+ virtual void handleAxisRangeChangedBySender(QObject *sender);
+ virtual void handleAxisSegmentCountChangedBySender(QObject *sender);
+ virtual void handleAxisSubSegmentCountChangedBySender(QObject *sender);
+ virtual void handleAxisAutoAdjustRangeChangedInOrientation(
+ Q3DAbstractAxis::AxisOrientation orientation, bool autoAdjust) = 0;
+ virtual void handleAxisLabelFormatChangedBySender(QObject *sender);
public slots:
void handleAxisTitleChanged(const QString &title);
@@ -262,32 +311,24 @@ public slots:
void handleAxisSegmentCountChanged(int count);
void handleAxisSubSegmentCountChanged(int count);
void handleAxisAutoAdjustRangeChanged(bool autoAdjust);
+ void handleAxisLabelFormatChanged(const QString &format);
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);
+ void activeInputHandlerChanged(QAbstract3DInputHandler *inputHandler);
+ void needRender();
+
+protected:
+ virtual Q3DAbstractAxis *createDefaultAxis(Q3DAbstractAxis::AxisOrientation orientation);
+ Q3DValueAxis *createDefaultValueAxis();
+ Q3DCategoryAxis *createDefaultCategoryAxis();
+ void emitNeedRender();
private:
- void setAxisHelper(QAbstractAxis::AxisOrientation orientation, QAbstractAxis *axis,
- QAbstractAxis **axisPtr);
+ void setAxisHelper(Q3DAbstractAxis::AxisOrientation orientation, Q3DAbstractAxis *axis,
+ Q3DAbstractAxis **axisPtr);
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif // CONTROLLER3DBASE_H
diff --git a/src/datavisualization/engine/abstract3drenderer.cpp b/src/datavisualization/engine/abstract3drenderer.cpp
new file mode 100644
index 00000000..eef810df
--- /dev/null
+++ b/src/datavisualization/engine/abstract3drenderer.cpp
@@ -0,0 +1,313 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 "q3dvalueaxis.h"
+#include "texturehelper_p.h"
+#include "utils_p.h"
+#include "q3dscene_p.h"
+#include "q3dcamera_p.h"
+#include "q3dlight_p.h"
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+Abstract3DRenderer::Abstract3DRenderer(Abstract3DController *controller)
+ : QObject(0),
+ m_controller(controller),
+ m_hasNegativeValues(false),
+ m_cachedTheme(),
+ m_cachedFont(QFont(QStringLiteral("Arial"))),
+ m_cachedLabelStyle(QDataVis::LabelStyleFromTheme),
+ m_drawer(new Drawer(m_cachedTheme, m_cachedFont, m_cachedLabelStyle)),
+ m_cachedBoundingRect(QRect(0,0,0,0)),
+ m_cachedShadowQuality(QDataVis::ShadowQualityMedium),
+ m_autoScaleAdjustment(1.0f),
+ m_cachedSelectionMode(QDataVis::SelectionModeNone),
+ m_cachedIsGridEnabled(false),
+ m_cachedIsBackgroundEnabled(false),
+ m_cachedScene(new Q3DScene())
+ #ifdef DISPLAY_RENDER_SPEED
+ , m_isFirstFrame(true),
+ m_numFrames(0)
+ #endif
+
+{
+ QObject::connect(m_drawer, &Drawer::drawerChanged, this, &Abstract3DRenderer::updateTextures);
+ QObject::connect(this, &Abstract3DRenderer::needRender, m_controller,
+ &Abstract3DController::needRender, Qt::QueuedConnection);
+}
+
+Abstract3DRenderer::~Abstract3DRenderer()
+{
+ delete m_drawer;
+ delete m_textureHelper;
+ delete m_cachedScene;
+}
+
+void Abstract3DRenderer::initializeOpenGL()
+{
+ // 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
+
+ m_textureHelper = new TextureHelper();
+ m_drawer->initializeOpenGL();
+
+ axisCacheForOrientation(Q3DAbstractAxis::AxisOrientationX).setDrawer(m_drawer);
+ axisCacheForOrientation(Q3DAbstractAxis::AxisOrientationY).setDrawer(m_drawer);
+ axisCacheForOrientation(Q3DAbstractAxis::AxisOrientationZ).setDrawer(m_drawer);
+}
+
+void Abstract3DRenderer::render(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);
+ glDisable(GL_BLEND); // For QtQuick2 blending is enabled by default, but we don't want it to be
+ }
+
+ glViewport(m_cachedScene->viewport().x(),
+ m_cachedScene->viewport().y(),
+ m_cachedScene->viewport().width(),
+ m_cachedScene->viewport().height());
+
+ 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);
+}
+
+QString Abstract3DRenderer::generateValueLabel(const QString &format, qreal value)
+{
+ QString valueLabelFormat = format;
+ Utils::ParamType valueParamType = Utils::findFormatParamType(valueLabelFormat);
+ QByteArray valueFormatArray = valueLabelFormat.toUtf8();
+ return Utils::formatLabel(valueFormatArray, valueParamType, value);
+}
+
+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::updateScene(Q3DScene *scene)
+{
+ // Synchronize the controller scene to that of the renderer, and vice versa.
+ // Controller scene had priority if both have changed same values.
+ scene->d_ptr->sync(*m_cachedScene->d_ptr);
+ m_cachedScene->d_ptr->sync(*scene->d_ptr);
+}
+
+void Abstract3DRenderer::handleShadowQualityChange()
+{
+#if !defined(QT_OPENGL_ES_2)
+ if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) {
+ 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::updateLabelStyle(QDataVis::LabelStyle style)
+{
+ m_cachedLabelStyle = style;
+ m_drawer->setStyle(style);
+}
+
+void Abstract3DRenderer::updateMeshFileName(const QString &objFileName)
+{
+ if (objFileName != m_cachedObjFile) {
+ m_cachedObjFile = objFileName;
+ loadMeshFile();
+ }
+}
+
+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;
+ // 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));
+ 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::updateAxisType(Q3DAbstractAxis::AxisOrientation orientation, Q3DAbstractAxis::AxisType type)
+{
+ axisCacheForOrientation(orientation).setType(type);
+}
+
+void Abstract3DRenderer::updateAxisTitle(Q3DAbstractAxis::AxisOrientation orientation, const QString &title)
+{
+ axisCacheForOrientation(orientation).setTitle(title);
+}
+
+void Abstract3DRenderer::updateAxisLabels(Q3DAbstractAxis::AxisOrientation orientation, const QStringList &labels)
+{
+ axisCacheForOrientation(orientation).setLabels(labels);
+}
+
+void Abstract3DRenderer::updateAxisRange(Q3DAbstractAxis::AxisOrientation orientation, qreal min, qreal max)
+{
+ AxisRenderCache &cache = axisCacheForOrientation(orientation);
+ cache.setMin(min);
+ cache.setMax(max);
+}
+
+void Abstract3DRenderer::updateAxisSegmentCount(Q3DAbstractAxis::AxisOrientation orientation, int count)
+{
+ axisCacheForOrientation(orientation).setSegmentCount(count);
+}
+
+void Abstract3DRenderer::updateAxisSubSegmentCount(Q3DAbstractAxis::AxisOrientation orientation, int count)
+{
+ axisCacheForOrientation(orientation).setSubSegmentCount(count);
+}
+
+void Abstract3DRenderer::updateAxisLabelFormat(Q3DAbstractAxis::AxisOrientation orientation, const QString &format)
+{
+ axisCacheForOrientation(orientation).setLabelFormat(format);
+}
+
+AxisRenderCache &Abstract3DRenderer::axisCacheForOrientation(Q3DAbstractAxis::AxisOrientation orientation)
+{
+ switch (orientation) {
+ case Q3DAbstractAxis::AxisOrientationX:
+ return m_axisCacheX;
+ case Q3DAbstractAxis::AxisOrientationY:
+ return m_axisCacheY;
+ case Q3DAbstractAxis::AxisOrientationZ:
+ return m_axisCacheZ;
+ default:
+ qFatal("Abstract3DRenderer::axisCacheForOrientation");
+ return m_axisCacheX;
+ }
+}
+
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavis3d/engine/abstract3drenderer_p.h b/src/datavisualization/engine/abstract3drenderer_p.h
index 3c5d1388..1c61ac07 100644
--- a/src/datavis3d/engine/abstract3drenderer_p.h
+++ b/src/datavisualization/engine/abstract3drenderer_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -31,87 +31,111 @@
#include <QtGui/QOpenGLFunctions>
#include <QtGui/QFont>
+#include <QTime>
-#include "datavis3dglobal_p.h"
+#include "datavisualizationglobal_p.h"
#include "abstract3dcontroller_p.h"
#include "axisrendercache_p.h"
#include "qabstractdataproxy.h"
-QT_DATAVIS3D_BEGIN_NAMESPACE
+//#define DISPLAY_RENDER_SPEED
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class TextureHelper;
+class Theme;
+class Drawer;
class Abstract3DRenderer : public QObject, protected QOpenGLFunctions
{
-protected:
+ Q_OBJECT
+
+private:
Abstract3DController *m_controller;
- bool m_isInitialized;
+
+protected:
bool m_hasNegativeValues;
- QRect m_cachedBoundingRect;
- QDataVis::ShadowQuality m_cachedShadowQuality;
Theme m_cachedTheme;
QFont m_cachedFont;
- QDataVis::LabelTransparency m_cachedLabelTransparency;
+ QDataVis::LabelStyle m_cachedLabelStyle;
Drawer *m_drawer;
+ QRect m_cachedBoundingRect;
+ QDataVis::ShadowQuality m_cachedShadowQuality;
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;
+ TextureHelper *m_textureHelper;
+ Q3DBox m_boundingBox;
- Abstract3DRenderer(Abstract3DController *controller);
- virtual void initializeOpenGL();
+ Q3DScene *m_cachedScene;
+
+#ifdef DISPLAY_RENDER_SPEED
+ bool m_isFirstFrame;
+ QTime m_lastFrameTime;
+ GLint m_numFrames;
+#endif
+
+ QString generateValueLabel(const QString &format, qreal value);
public:
- inline bool isInitialized() { return m_isInitialized; }
+ virtual ~Abstract3DRenderer();
- virtual void updateBoundingRect(const QRect boundingRect);
- virtual void updatePosition(const QRect boundingRect);
- virtual void handleResize();
+ void updateDataModel(QAbstractDataProxy *dataProxy);
+
+ virtual void render(GLuint defaultFboHandle);
+
+ virtual void updateBoundingRect(const QRect &boundingRect);
+ virtual void updatePosition(const QRect &boundingRect);
- virtual void updateZoomLevel(int newZoomLevel);
virtual void updateTheme(Theme theme);
virtual void updateFont(const QFont &font);
- virtual void updateLabelTransparency(QDataVis::LabelTransparency transparency);
+ virtual void updateLabelStyle(QDataVis::LabelStyle style);
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 void updateScene(Q3DScene *scene);
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);
+ virtual void updateAxisType(Q3DAbstractAxis::AxisOrientation orientation, Q3DAbstractAxis::AxisType type);
+ virtual void updateAxisTitle(Q3DAbstractAxis::AxisOrientation orientation, const QString &title);
+ virtual void updateAxisLabels(Q3DAbstractAxis::AxisOrientation orientation, const QStringList &labels);
+ virtual void updateAxisRange(Q3DAbstractAxis::AxisOrientation orientation, qreal min, qreal max);
+ virtual void updateAxisSegmentCount(Q3DAbstractAxis::AxisOrientation orientation, int count);
+ virtual void updateAxisSubSegmentCount(Q3DAbstractAxis::AxisOrientation orientation, int count);
+ virtual void updateAxisLabelFormat(Q3DAbstractAxis::AxisOrientation orientation, const QString &format);
- AxisRenderCache &axisCacheForOrientation(QAbstractAxis::AxisOrientation orientation);
+signals:
+ void needRender(); // Emit this if something in renderer causes need for another render pass.
-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;
+protected:
+ Abstract3DRenderer(Abstract3DController *controller);
+
+ virtual void initializeOpenGL();
+
+ virtual void handleShadowQualityChange();
+ virtual void handleResize();
+ virtual void loadMeshFile() = 0;
+
+ AxisRenderCache &axisCacheForOrientation(Q3DAbstractAxis::AxisOrientation orientation);
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif // ABSTRACT3DRENDERER_P_H
diff --git a/src/datavis3d/engine/axisrendercache.cpp b/src/datavisualization/engine/axisrendercache.cpp
index 4374d545..55ac0765 100644
--- a/src/datavis3d/engine/axisrendercache.cpp
+++ b/src/datavisualization/engine/axisrendercache.cpp
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -18,15 +18,17 @@
#include "axisrendercache_p.h"
#include "qmath.h"
+#include <QFontMetrics>
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
AxisRenderCache::AxisRenderCache()
- : m_type(QAbstractAxis::AxisTypeNone),
+ : m_type(Q3DAbstractAxis::AxisTypeNone),
m_min(0.0),
m_max(10.0),
m_segmentCount(5),
m_subSegmentCount(1),
+ m_font(QFont(QStringLiteral("Arial"))),
m_drawer(0),
m_segmentStep(10.0f),
m_subSegmentStep(10.0f)
@@ -42,21 +44,32 @@ AxisRenderCache::~AxisRenderCache()
void AxisRenderCache::setDrawer(Drawer *drawer)
{
m_drawer = drawer;
+ m_font = m_drawer->font();
if (m_drawer) {
QObject::connect(m_drawer, &Drawer::drawerChanged, this, &AxisRenderCache::updateTextures);
updateTextures();
}
}
-void AxisRenderCache::setType(QAbstractAxis::AxisType type)
+void AxisRenderCache::setType(Q3DAbstractAxis::AxisType type)
{
m_type = type;
- // If type is set, it means completely new axis instance, so clear all generated label items.
+ // If type is set, it means completely new axis instance, so clear all old data
+ m_labels.clear();
+ m_title.clear();
+ m_min = 0.0;
+ m_max = 10.0;
+ m_segmentCount = 5;
+ m_subSegmentCount = 1;
+ m_labelFormat.clear();
+
m_titleItem.clear();
foreach (LabelItem *label, m_labelItems)
delete label;
m_labelItems.clear();
+ m_segmentStep = 10.0f;
+ m_subSegmentStep = 10.0f;
}
void AxisRenderCache::setTitle(const QString &title)
@@ -80,14 +93,16 @@ void AxisRenderCache::setLabels(const QStringList &labels)
m_labelItems.reserve(newSize);
- if (m_drawer) {
- for (int i = 0; i < newSize; i++) {
- if (i >= oldSize)
- m_labelItems.append(new LabelItem);
+ int widest = maxLabelWidth(labels);
+
+ for (int i = 0; i < newSize; i++) {
+ if (i >= oldSize)
+ m_labelItems.append(new LabelItem);
+ if (m_drawer) {
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_drawer->generateLabelItem(*m_labelItems[i], labels.at(i), widest);
}
}
m_labels = labels;
@@ -120,16 +135,20 @@ void AxisRenderCache::setSubSegmentCount(int count)
void AxisRenderCache::updateTextures()
{
+ m_font = m_drawer->font();
+
if (m_title.isEmpty())
m_titleItem.clear();
else
m_drawer->generateLabelItem(m_titleItem, m_title);
+ int widest = maxLabelWidth(m_labels);
+
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));
+ m_drawer->generateLabelItem(*m_labelItems[i], m_labels.at(i), widest);
}
}
@@ -150,4 +169,18 @@ void AxisRenderCache::updateSubSegmentStep()
m_subSegmentStep = m_segmentStep;
}
-QT_DATAVIS3D_END_NAMESPACE
+int AxisRenderCache::maxLabelWidth(const QStringList &labels) const
+{
+ int labelWidth = 0;
+ QFont labelFont = m_font;
+ labelFont.setPointSize(textureFontSize);
+ QFontMetrics labelFM(labelFont);
+ for (int i = 0; i < labels.size(); i++) {
+ int newWidth = labelFM.width(labels.at(i));
+ if (labelWidth < newWidth)
+ labelWidth = newWidth;
+ }
+ return labelWidth;
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavis3d/engine/axisrendercache_p.h b/src/datavisualization/engine/axisrendercache_p.h
index 4b38fa20..0bb1cf92 100644
--- a/src/datavis3d/engine/axisrendercache_p.h
+++ b/src/datavisualization/engine/axisrendercache_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -29,12 +29,12 @@
#ifndef AXISRENDERCACHE_P_H
#define AXISRENDERCACHE_P_H
-#include "datavis3dglobal_p.h"
+#include "datavisualizationglobal_p.h"
#include "labelitem_p.h"
-#include "qabstractaxis_p.h"
+#include "q3dabstractaxis_p.h"
#include "drawer_p.h"
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
class AxisRenderCache : public QObject
{
@@ -45,8 +45,8 @@ public:
void setDrawer(Drawer *drawer);
- void setType(QAbstractAxis::AxisType type);
- inline QAbstractAxis::AxisType type() const { return m_type; }
+ void setType(Q3DAbstractAxis::AxisType type);
+ inline Q3DAbstractAxis::AxisType type() const { return m_type; }
void setTitle(const QString &title);
inline const QString &title() { return m_title; }
void setLabels(const QStringList &labels);
@@ -59,6 +59,8 @@ public:
inline int segmentCount() const { return m_segmentCount; }
void setSubSegmentCount(int count);
inline int subSegmentCount() const { return m_subSegmentCount; }
+ inline void setLabelFormat(const QString &format) { m_labelFormat = format; }
+ inline const QString &labelFormat() { return m_labelFormat; }
inline LabelItem &titleItem() { return m_titleItem; }
inline QList<LabelItem *> &labelItems() { return m_labelItems; }
@@ -71,15 +73,18 @@ public slots:
private:
void updateSegmentStep();
void updateSubSegmentStep();
+ int maxLabelWidth(const QStringList &labels) const;
// Cached axis values
- QAbstractAxis::AxisType m_type;
+ Q3DAbstractAxis::AxisType m_type;
QString m_title;
QStringList m_labels;
qreal m_min;
qreal m_max;
int m_segmentCount;
int m_subSegmentCount;
+ QString m_labelFormat;
+ QFont m_font;
// Renderer items
Drawer *m_drawer; // Not owned
@@ -91,6 +96,6 @@ private:
Q_DISABLE_COPY(AxisRenderCache)
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif
diff --git a/src/datavisualization/engine/bars3dcontroller.cpp b/src/datavisualization/engine/bars3dcontroller.cpp
new file mode 100644
index 00000000..50d8d030
--- /dev/null
+++ b/src/datavisualization/engine/bars3dcontroller.cpp
@@ -0,0 +1,428 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 "q3dabstractaxis_p.h"
+#include "q3dvalueaxis_p.h"
+#include "q3dcategoryaxis_p.h"
+#include "qbardataproxy_p.h"
+
+#include <QMatrix4x4>
+#include <qmath.h>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+Bars3DController::Bars3DController(QRect boundRect)
+ : Abstract3DController(boundRect),
+ m_selectedBarPos(noSelectionPoint()),
+ m_isBarSpecRelative(true),
+ m_barThicknessRatio(1.0f),
+ m_barSpacing(QSizeF(1.0, 1.0)),
+ m_renderer(0)
+{
+ // Default bar type; specific to bars
+ setBarType(QDataVis::MeshStyleBevelBars, false);
+
+ setActiveDataProxy(0);
+
+ // Setting a null axis creates a new default axis according to orientation and graph type.
+ // Note: These cannot be set in Abstract3DController constructor, as they will call virtual
+ // functions implemented by subclasses.
+ setAxisX(0);
+ setAxisY(0);
+ setAxisZ(0);
+}
+
+Bars3DController::~Bars3DController()
+{
+}
+
+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);
+ synchDataToRenderer();
+
+ QObject::connect(m_renderer, &Bars3DRenderer::selectedBarPosChanged, this,
+ &Bars3DController::handleSelectedBarPosChanged, Qt::QueuedConnection);
+ emitNeedRender();
+}
+
+void Bars3DController::synchDataToRenderer()
+{
+ Abstract3DController::synchDataToRenderer();
+
+ if (!isInitialized())
+ return;
+
+ // Notify changes to renderer
+ if (m_changeTracker.barSpecsChanged) {
+ m_renderer->updateBarSpecs(m_barThicknessRatio, m_barSpacing, m_isBarSpecRelative);
+ m_changeTracker.barSpecsChanged = false;
+ }
+
+ if (m_changeTracker.selectedBarPosChanged) {
+ m_renderer->updateSelectedBarPos(m_selectedBarPos);
+ m_changeTracker.selectedBarPosChanged = false;
+ }
+
+ if (m_isDataDirty) {
+ m_renderer->updateDataModel(static_cast<QBarDataProxy *>(m_data));
+ m_isDataDirty = false;
+ }
+}
+
+void Bars3DController::setActiveDataProxy(QAbstractDataProxy *proxy)
+{
+ // Setting null proxy indicates default proxy
+ if (!proxy) {
+ proxy = new QBarDataProxy;
+ proxy->d_ptr->setDefaultProxy(true);
+ }
+
+ Q_ASSERT(proxy->type() == QAbstractDataProxy::DataTypeBar);
+
+ Abstract3DController::setActiveDataProxy(proxy);
+
+ QBarDataProxy *barDataProxy = static_cast<QBarDataProxy *>(m_data);
+
+ QObject::connect(barDataProxy, &QBarDataProxy::arrayReset, this,
+ &Bars3DController::handleArrayReset);
+ QObject::connect(barDataProxy, &QBarDataProxy::rowsAdded, this,
+ &Bars3DController::handleRowsAdded);
+ QObject::connect(barDataProxy, &QBarDataProxy::rowsChanged, this,
+ &Bars3DController::handleRowsChanged);
+ QObject::connect(barDataProxy, &QBarDataProxy::rowsRemoved, this,
+ &Bars3DController::handleRowsRemoved);
+ QObject::connect(barDataProxy, &QBarDataProxy::rowsInserted, this,
+ &Bars3DController::handleRowsInserted);
+ QObject::connect(barDataProxy, &QBarDataProxy::itemChanged, this,
+ &Bars3DController::handleItemChanged);
+ QObject::connect(barDataProxy, &QBarDataProxy::rowLabelsChanged, this,
+ &Bars3DController::handleDataRowLabelsChanged);
+ QObject::connect(barDataProxy, &QBarDataProxy::columnLabelsChanged, this,
+ &Bars3DController::handleDataColumnLabelsChanged);
+
+ scene()->setSlicingActive(false);
+ adjustAxisRanges();
+
+ // Always clear selection on proxy change
+ setSelectedBarPos(noSelectionPoint());
+
+ handleDataRowLabelsChanged();
+ handleDataColumnLabelsChanged();
+ m_isDataDirty = true;
+ emitNeedRender();
+}
+
+void Bars3DController::handleArrayReset()
+{
+ scene()->setSlicingActive(false);
+ adjustAxisRanges();
+ m_isDataDirty = true;
+ // Clear selection unless still valid
+ setSelectedBarPos(m_selectedBarPos);
+ emitNeedRender();
+}
+
+void Bars3DController::handleRowsAdded(int startIndex, int count)
+{
+ Q_UNUSED(startIndex)
+ Q_UNUSED(count)
+ // TODO should update slice instead of deactivating?
+ scene()->setSlicingActive(false);
+ adjustAxisRanges();
+ m_isDataDirty = true;
+ emitNeedRender();
+}
+
+void Bars3DController::handleRowsChanged(int startIndex, int count)
+{
+ Q_UNUSED(startIndex)
+ Q_UNUSED(count)
+ // TODO should update slice instead of deactivating?
+ scene()->setSlicingActive(false);
+ adjustAxisRanges();
+ m_isDataDirty = true;
+ emitNeedRender();
+}
+
+void Bars3DController::handleRowsRemoved(int startIndex, int count)
+{
+ Q_UNUSED(startIndex)
+ Q_UNUSED(count)
+ // TODO should update slice instead of deactivating?
+ scene()->setSlicingActive(false);
+ adjustAxisRanges();
+ m_isDataDirty = true;
+
+ // Clear selection unless still valid
+ setSelectedBarPos(m_selectedBarPos);
+
+ emitNeedRender();
+}
+
+void Bars3DController::handleRowsInserted(int startIndex, int count)
+{
+ Q_UNUSED(startIndex)
+ Q_UNUSED(count)
+ // TODO should update slice instead of deactivating?
+ scene()->setSlicingActive(false);
+ adjustAxisRanges();
+ m_isDataDirty = true;
+ emitNeedRender();
+}
+
+void Bars3DController::handleItemChanged(int rowIndex, int columnIndex)
+{
+ Q_UNUSED(rowIndex)
+ Q_UNUSED(columnIndex)
+ // TODO should update slice instead of deactivating?
+ scene()->setSlicingActive(false);
+ adjustAxisRanges();
+ m_isDataDirty = true;
+ emitNeedRender();
+}
+
+void Bars3DController::handleDataRowLabelsChanged()
+{
+ if (m_axisX && m_data) {
+ // Grab a sublist equal to data window (no need to have more labels in axis)
+ int min = int(m_axisX->min());
+ int count = int(m_axisX->max()) - min + 1;
+ QStringList subList = static_cast<QBarDataProxy *>(m_data)->rowLabels().mid(min, count);
+ static_cast<Q3DCategoryAxis *>(m_axisX)->dptr()->setDataLabels(subList);
+ }
+}
+
+void Bars3DController::handleDataColumnLabelsChanged()
+{
+ if (m_axisZ && m_data) {
+ // Grab a sublist equal to data window (no need to have more labels in axis)
+ int min = int(m_axisZ->min());
+ int count = int(m_axisZ->max()) - min + 1;
+ QStringList subList = static_cast<QBarDataProxy *>(m_data)->columnLabels().mid(min, count);
+ static_cast<Q3DCategoryAxis *>(m_axisZ)->dptr()->setDataLabels(subList);
+ }
+}
+
+void Bars3DController::handleSelectedBarPosChanged(const QPoint &position)
+{
+ QPoint pos = position;
+ if (pos == QPoint(255, 255))
+ pos = noSelectionPoint();
+ if (pos != m_selectedBarPos) {
+ m_selectedBarPos = pos;
+ emit selectedBarPosChanged(pos);
+ emitNeedRender();
+ }
+}
+
+void Bars3DController::handleAxisAutoAdjustRangeChangedInOrientation(
+ Q3DAbstractAxis::AxisOrientation orientation, bool autoAdjust)
+{
+ Q_UNUSED(orientation)
+ Q_UNUSED(autoAdjust)
+ adjustAxisRanges();
+}
+
+QPoint Bars3DController::noSelectionPoint()
+{
+ static QPoint noSelectionPos(-1, -1);
+ return noSelectionPos;
+}
+
+void Bars3DController::setAxisX(Q3DAbstractAxis *axis)
+{
+ Abstract3DController::setAxisX(axis);
+ handleDataRowLabelsChanged();
+}
+
+void Bars3DController::setAxisZ(Q3DAbstractAxis *axis)
+{
+ Abstract3DController::setAxisZ(axis);
+ handleDataColumnLabelsChanged();
+}
+
+void Bars3DController::handleAxisRangeChangedBySender(QObject *sender)
+{
+ // Data window changed
+ if (sender == m_axisX || sender == m_axisZ) {
+ // Disable zoom mode if we're in it (causes crash if not, as zoom selection is deleted)
+ scene()->setSlicingActive(false);
+
+ // Clear selection unless still valid
+ setSelectedBarPos(m_selectedBarPos);
+
+ if (sender == m_axisX)
+ handleDataRowLabelsChanged();
+ if (sender == m_axisZ)
+ handleDataColumnLabelsChanged();
+ }
+
+ Abstract3DController::handleAxisRangeChangedBySender(sender);
+}
+
+void Bars3DController::setBarSpecs(GLfloat thicknessRatio, const QSizeF &spacing, bool relative)
+{
+ m_barThicknessRatio = thicknessRatio;
+ m_barSpacing = spacing;
+ m_isBarSpecRelative = relative;
+
+ m_changeTracker.barSpecsChanged = true;
+ emitNeedRender();
+}
+
+GLfloat Bars3DController::barThickness()
+{
+ return m_barThicknessRatio;
+}
+
+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::MeshStyleBars)
+ objFile = QStringLiteral(":/defaultMeshes/bar");
+ else if (style == QDataVis::MeshStylePyramids)
+ objFile = QStringLiteral(":/defaultMeshes/pyramid");
+ else if (style == QDataVis::MeshStyleCones)
+ objFile = QStringLiteral(":/defaultMeshes/cone");
+ else if (style == QDataVis::MeshStyleCylinders)
+ objFile = QStringLiteral(":/defaultMeshes/cylinder");
+ else if (style == QDataVis::MeshStyleBevelBars)
+ objFile = QStringLiteral(":/defaultMeshes/bevelbar");
+
+ if (smooth)
+ objFile += QStringLiteral("Smooth");
+
+ Abstract3DController::setMeshFileName(objFile);
+}
+
+void Bars3DController::setSelectionMode(QDataVis::SelectionMode mode)
+{
+ // Disable zoom if selection mode changes
+ scene()->setSlicingActive(false);
+ Abstract3DController::setSelectionMode(mode);
+}
+
+void Bars3DController::setSelectedBarPos(const QPoint &position)
+{
+ // If the selection is outside data window or targets non-existent
+ // bar, clear selection instead.
+ QPoint pos = position;
+
+ if (pos != noSelectionPoint()) {
+ int minRow = int(m_axisX->min());
+ int maxRow = int(m_axisX->max());
+ int minCol = int(m_axisZ->min());
+ int maxCol = int(m_axisZ->max());
+
+ if (pos.x() < minRow || pos.x() > maxRow || pos.y() < minCol || pos.y() > maxCol
+ || pos.x() + minRow >= static_cast<QBarDataProxy *>(m_data)->rowCount()
+ || pos.y() + minCol >= static_cast<QBarDataProxy *>(m_data)->rowAt(pos.x())->size()) {
+ pos = noSelectionPoint();
+ }
+ }
+
+ if (pos != m_selectedBarPos) {
+ m_selectedBarPos = pos;
+ m_changeTracker.selectedBarPosChanged = true;
+ emit selectedBarPosChanged(pos);
+ emitNeedRender();
+ }
+}
+
+QPoint Bars3DController::selectedBarPos() const
+{
+ return m_selectedBarPos;
+}
+
+void Bars3DController::adjustAxisRanges()
+{
+ const QBarDataProxy *proxy = static_cast<QBarDataProxy *>(m_data);
+ const QBarDataArray *array = proxy->array();
+
+ Q3DCategoryAxis *categoryAxisX = static_cast<Q3DCategoryAxis *>(m_axisX);
+ if (categoryAxisX && categoryAxisX->isAutoAdjustRange() && proxy) {
+ int rowCount = proxy->rowCount();
+ if (rowCount)
+ rowCount--;
+ categoryAxisX->dptr()->setRange(0.0, qreal(rowCount));
+ }
+
+ Q3DCategoryAxis *categoryAxisZ = static_cast<Q3DCategoryAxis *>(m_axisZ);
+ if (categoryAxisZ && categoryAxisZ->isAutoAdjustRange() && proxy) {
+ int columnCount = 0;
+ for (int i = 0; i < array->size(); i++) {
+ if (columnCount < array->at(i)->size())
+ columnCount = array->at(i)->size();
+ }
+ if (columnCount)
+ columnCount--;
+ categoryAxisZ->dptr()->setRange(0.0, qreal(columnCount));
+ }
+
+ Q3DValueAxis *valueAxis = static_cast<Q3DValueAxis *>(m_axisY);
+ if (valueAxis && categoryAxisX && categoryAxisZ && valueAxis->isAutoAdjustRange() && proxy) {
+ QPair<GLfloat, GLfloat> limits = proxy->dptrc()->limitValues(categoryAxisX->min(),
+ categoryAxisX->max(),
+ categoryAxisZ->min(),
+ categoryAxisZ->max());
+ if (limits.first < 0) {
+ // TODO: Currently we only support symmetric y-axis for bar graph 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);
+ }
+ }
+}
+
+Q3DAbstractAxis *Bars3DController::createDefaultAxis(Q3DAbstractAxis::AxisOrientation orientation)
+{
+ Q3DAbstractAxis *defaultAxis = 0;
+
+ if (orientation == Q3DAbstractAxis::AxisOrientationY)
+ defaultAxis = createDefaultValueAxis();
+ else
+ defaultAxis = createDefaultCategoryAxis();
+
+ return defaultAxis;
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavis3d/engine/bars3dcontroller_p.h b/src/datavisualization/engine/bars3dcontroller_p.h
index 9811eb0d..8398dd81 100644
--- a/src/datavis3d/engine/bars3dcontroller_p.h
+++ b/src/datavisualization/engine/bars3dcontroller_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -29,106 +29,83 @@
#ifndef Q3DBARSCONTROLLER_p_H
#define Q3DBARSCONTROLLER_p_H
-#include "datavis3dglobal_p.h"
+#include "datavisualizationglobal_p.h"
#include "abstract3dcontroller_p.h"
//#define DISPLAY_RENDER_SPEED
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
-class Bars3dRenderer;
+class Bars3DRenderer;
class QBarDataProxy;
struct Bars3DChangeBitField {
bool slicingActiveChanged : 1;
- bool sampleSpaceChanged : 1;
bool barSpecsChanged : 1;
+ bool selectedBarPosChanged : 1;
Bars3DChangeBitField() :
slicingActiveChanged(true),
- sampleSpaceChanged(true),
- barSpecsChanged(true)
+ barSpecsChanged(true),
+ selectedBarPosChanged(true)
{
}
};
-class QT_DATAVIS3D_EXPORT Bars3dController : public Abstract3DController
+class QT_DATAVISUALIZATION_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;
+ QPoint m_selectedBarPos; // Points to row & column in data window.
// Look'n'feel
bool m_isBarSpecRelative;
- QSizeF m_barThickness;
+ GLfloat m_barThicknessRatio;
QSizeF m_barSpacing;
// Rendering
- Bars3dRenderer *m_renderer;
- QBarDataProxy *m_data;
+ Bars3DRenderer *m_renderer;
public:
- explicit Bars3dController(QRect rect);
- ~Bars3dController();
+ 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),
+ void setBarSpecs(GLfloat thicknessRatio = 1.0f,
+ const QSizeF &spacing = QSizeF(1.0, 1.0),
bool relative = true);
- QSizeF barThickness();
+ GLfloat 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);
+ void setSelectedBarPos(const QPoint &position);
+ QPoint selectedBarPos() const;
+
+ virtual void setActiveDataProxy(QAbstractDataProxy *proxy);
+
+ virtual void handleAxisAutoAdjustRangeChangedInOrientation(Q3DAbstractAxis::AxisOrientation orientation, bool autoAdjust);
- // 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);
+ static QPoint noSelectionPoint();
+
+ virtual void setAxisX(Q3DAbstractAxis *axis);
+ virtual void setAxisZ(Q3DAbstractAxis *axis);
+
+ virtual void handleAxisRangeChangedBySender(QObject *sender);
public slots:
void handleArrayReset();
@@ -137,21 +114,25 @@ public slots:
void handleRowsRemoved(int startIndex, int count);
void handleRowsInserted(int startIndex, int count);
void handleItemChanged(int rowIndex, int columnIndex);
+ void handleDataRowLabelsChanged();
+ void handleDataColumnLabelsChanged();
+ void handleSelectedBarPosChanged(const QPoint &position);
signals:
- void slicingActiveChanged(bool isSlicing);
- void sampleSpaceChanged(int samplesRow, int samplesColumn);
- void barSpecsChanged(QSizeF thickness, QSizeF spacing, bool relative);
+ void selectedBarPosChanged(QPoint position);
+
+protected:
+ virtual Q3DAbstractAxis *createDefaultAxis(Q3DAbstractAxis::AxisOrientation orientation);
private:
- void adjustValueAxisRange();
+ void adjustAxisRanges();
- Q_DISABLE_COPY(Bars3dController)
+ Q_DISABLE_COPY(Bars3DController)
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif
diff --git a/src/datavis3d/engine/bars3drenderer.cpp b/src/datavisualization/engine/bars3drenderer.cpp
index 81bad91f..74c1a99b 100644
--- a/src/datavis3d/engine/bars3drenderer.cpp
+++ b/src/datavisualization/engine/bars3drenderer.cpp
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -18,7 +18,7 @@
#include "bars3drenderer_p.h"
#include "bars3dcontroller_p.h"
-#include "camerahelper_p.h"
+#include "q3dcamera_p.h"
#include "shaderhelper_p.h"
#include "objecthelper_p.h"
#include "texturehelper_p.h"
@@ -26,6 +26,7 @@
#include "utils_p.h"
#include "drawer_p.h"
#include "qbardataitem.h"
+#include "q3dlight.h"
#include <QMatrix4x4>
#include <QMouseEvent>
@@ -33,30 +34,23 @@
#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
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+const GLfloat labelMargin = 0.05f;
const GLfloat gridLineWidth = 0.005f;
static QVector3D selectionSkipColor = QVector3D(255, 255, 255); // Selection texture's background color
-Bars3dRenderer::Bars3dRenderer(Bars3dController *controller)
+Bars3DRenderer::Bars3DRenderer(Bars3DController *controller)
: Abstract3DRenderer(controller),
m_controller(controller),
+ m_cachedIsSlicingActivated(false),
+ m_cachedRowCount(0),
+ m_cachedColumnCount(0),
m_selectedBar(0),
- m_previouslySelectedBar(0),
m_sliceSelection(0),
m_sliceCache(0),
m_sliceTitleItem(0),
@@ -79,7 +73,8 @@ Bars3dRenderer::Bars3dRenderer(Bars3dController *controller)
m_depthFrameBuffer(0),
m_selectionFrameBuffer(0),
m_selectionDepthBuffer(0),
- m_shadowQualityToShader(33.3f),
+ m_shadowQualityToShader(100.0f),
+ m_shadowQualityMultiplier(3),
m_heightNormalizer(1.0f),
m_yAdjustment(0.0f),
m_rowWidth(0),
@@ -90,18 +85,14 @@ Bars3dRenderer::Bars3dRenderer(Bars3dController *controller)
m_scaleFactor(0),
m_maxSceneSize(40.0),
m_selection(selectionSkipColor),
+ m_previousSelection(selectionSkipColor),
m_hasHeightAdjustmentChanged(true)
- #ifdef DISPLAY_RENDER_SPEED
- ,m_isFirstFrame(true),
- m_numFrames(0)
- #endif
{
- m_dummyBarRenderItem.setRenderer(this);
initializeOpenGLFunctions();
initializeOpenGL();
}
-Bars3dRenderer::~Bars3dRenderer()
+Bars3DRenderer::~Bars3DRenderer()
{
m_textureHelper->glDeleteFramebuffers(1, &m_selectionFrameBuffer);
m_textureHelper->glDeleteRenderbuffers(1, &m_selectionDepthBuffer);
@@ -119,17 +110,17 @@ Bars3dRenderer::~Bars3dRenderer()
delete m_barObj;
delete m_backgroundObj;
delete m_gridLineObj;
- delete m_textureHelper;
- delete m_drawer;
+ delete m_labelObj;
+ delete m_labelShader;
}
-void Bars3dRenderer::initializeOpenGL()
+void Bars3DRenderer::initializeOpenGL()
{
- m_textureHelper = new TextureHelper();
- m_drawer->initializeOpenGL();
+ Abstract3DRenderer::initializeOpenGL();
// Initialize shaders
handleShadowQualityChange();
+
initLabelShaders(QStringLiteral(":/shaders/vertexLabel"),
QStringLiteral(":/shaders/fragmentLabel"));
@@ -147,42 +138,59 @@ void Bars3dRenderer::initializeOpenGL()
// 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)
+void Bars3DRenderer::updateDataModel(QBarDataProxy *dataProxy)
{
+ int minRow = m_axisCacheX.min();
+ int maxRow = m_axisCacheX.max();
+ int minCol = m_axisCacheZ.min();
+ int maxCol = m_axisCacheZ.max();
+ int newRows = maxRow - minRow + 1;
+ int newColumns = maxCol - minCol + 1;
+ if (newRows != m_renderItemArray.size() || newColumns != m_renderItemArray.at(0).size()) {
+ // Destroy old render items and reallocate new array
+ m_renderItemArray.clear();
+ m_renderItemArray.resize(newRows);
+ for (int i = 0; i < newRows; i++)
+ m_renderItemArray[i].resize(newColumns);
+
+ // Force update for selection related items
+ m_sliceCache = 0;
+ m_sliceTitleItem = 0;
+ if (m_sliceSelection)
+ m_sliceSelection->clear();
+
+ m_cachedColumnCount = newColumns;
+ m_cachedRowCount = newRows;
+ // TODO: Invent foolproof 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(newColumns * newRows);
+ // Calculate here and at setting bar specs
+ calculateSceneScalingFactors();
+ }
+
// Update cached data window
int dataRowCount = dataProxy->rowCount();
- for (int i = 0; i < m_renderItemArray.size(); i++) {
+ int dataRowIndex = minRow;
+ for (int i = 0; i < newRows; i++) {
int j = 0;
- if (i < dataRowCount) {
- const QBarDataRow *dataRow = dataProxy->rowAt(i);
- int updateSize = qMin(dataRow->size(), m_renderItemArray[i].size());
+ if (dataRowIndex < dataRowCount) {
+ const QBarDataRow *dataRow = dataProxy->rowAt(dataRowIndex);
+ int updateSize = qMin((dataRow->size() - minCol), m_renderItemArray[i].size());
if (dataRow) {
+ int dataColIndex = minCol;
for (; j < updateSize ; j++) {
- qreal value = dataRow->at(j).value();
+ qreal value = dataRow->at(dataColIndex).value();
m_renderItemArray[i][j].setValue(value);
- m_renderItemArray[i][j].setHeight(value / m_heightNormalizer);
+ m_renderItemArray[i][j].setHeight(GLfloat(value) / m_heightNormalizer);
+ dataColIndex++;
}
}
}
@@ -190,59 +198,63 @@ void Bars3dRenderer::updateDataModel(QBarDataProxy *dataProxy)
m_renderItemArray[i][j].setValue(0.0);
m_renderItemArray[i][j].setHeight(0.0f);
}
+ dataRowIndex++;
}
Abstract3DRenderer::updateDataModel(dataProxy);
}
-void Bars3dRenderer::render(CameraHelper *camera, const GLuint defaultFboHandle)
+void Bars3DRenderer::updateScene(Q3DScene *scene)
{
-#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);
- }
+ // TODO: Move these to more suitable place e.g. controller should be controlling the viewports.
+ scene->setSecondarySubViewport(m_sliceViewPort);
+ scene->setPrimarySubViewport(m_mainViewPort);
- 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: See QTRD-2374
+ if (m_hasNegativeValues)
+ scene->activeCamera()->setMinYRotation(-90.0);
+ else
+ scene->activeCamera()->setMinYRotation(0.0);
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));
+ scene->activeCamera()->setBaseOrientation(QVector3D(0.0f, 0.0f, cameraDistance + zComp),
+ QVector3D(0.0f, -m_yAdjustment, zComp),
+ QVector3D(0.0f, 1.0f, 0.0f));
m_hasHeightAdjustmentChanged = false;
}
+ scene->activeCamera()->d_ptr->updateViewMatrix(m_autoScaleAdjustment);
+ // Set light position (rotate light with camera, a bit above it (as set in defaultLightPos))
+ scene->setLightPositionRelativeToCamera(defaultLightPos);
+
+ Abstract3DRenderer::updateScene(scene);
+
+ updateSlicingActive(scene->isSlicingActive());
+}
+
+void Bars3DRenderer::render(GLuint defaultFboHandle)
+{
+ bool slicingChanged = m_cachedIsSlicingActivated != m_cachedScene->isSlicingActive();
+
+ // Handle GL state setup for FBO buffers and clearing of the render surface
+ Abstract3DRenderer::render(defaultFboHandle);
+
// If slice selection is on, draw the sliced scene
if (m_cachedIsSlicingActivated)
- drawSlicedScene(camera, m_axisCacheX.titleItem(), m_axisCacheY.titleItem(), m_axisCacheZ.titleItem());
+ drawSlicedScene(m_axisCacheX.titleItem(), m_axisCacheY.titleItem(), m_axisCacheZ.titleItem());
// Draw bars scene
- drawScene(camera, defaultFboHandle);
+ drawScene(defaultFboHandle);
+
+ // If slicing has been activated by this render pass, we need another render
+ // Also trigger another render always when slicing changes in general to ensure
+ // final draw is correct.
+ if (m_cachedIsSlicingActivated != m_cachedScene->isSlicingActive() || slicingChanged)
+ emit needRender();
}
-void Bars3dRenderer::drawSlicedScene(CameraHelper *camera,
- const LabelItem &xLabel,
+void Bars3DRenderer::drawSlicedScene(const LabelItem &xLabel,
const LabelItem &yLabel,
const LabelItem &zLabel)
{
@@ -251,6 +263,11 @@ void Bars3dRenderer::drawSlicedScene(CameraHelper *camera,
GLint stopBar = m_sliceSelection->size();
GLint stepBar = 1;
QVector3D lightPos;
+ GLfloat negativesComp = 1.0f;
+
+ // Compensate bar scaling a bit to avoid drawing on axis titles when we have negative values
+ if (m_hasNegativeValues)
+ negativesComp = 0.67f;
// Specify viewport
glViewport(m_sliceViewPort.x(), m_sliceViewPort.y(),
@@ -261,39 +278,18 @@ void Bars3dRenderer::drawSlicedScene(CameraHelper *camera,
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;
+ GLfloat camZPosSliced = 5.0f / m_autoScaleAdjustment + zComp;
- viewMatrix.lookAt(QVector3D(0.0f, 0.0f, camPosZoomed),
+ viewMatrix.lookAt(QVector3D(0.0f, 0.0f, camZPosSliced),
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
+ // Set light position
+ lightPos = QVector3D(0.0f, -m_yAdjustment, zComp);
// Bind bar shader
m_barShader->bind();
@@ -314,23 +310,37 @@ void Bars3dRenderer::drawSlicedScene(CameraHelper *camera,
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)
+ GLfloat barPosY = negativesComp * item->translation().y() - m_yAdjustment / 2.0f + 0.2f; // we need some room for labels underneath; add +0.2f
+ if (QDataVis::SelectionModeSliceRow == 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));
+ modelMatrix.scale(QVector3D(m_scaleX, negativesComp * item->height(), m_scaleZ));
+ itModelMatrix.scale(QVector3D(m_scaleX, negativesComp * 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();
+#if 0
+ QVector3D baseColor;
+ if (m_selection.x() == item->position().x() && m_selection.y() == item->position().y())
+ baseColor = Utils::vectorFromColor(m_cachedTheme.m_highlightBarColor);
+ else if (QDataVis::SelectionModeSliceRow == m_cachedSelectionMode)
+ baseColor = Utils::vectorFromColor(m_cachedTheme.m_highlightRowColor);
+ else
+ baseColor = Utils::vectorFromColor(m_cachedTheme.m_highlightColumnColor);
+ QVector3D heightColor = Utils::vectorFromColor(m_cachedTheme.m_heightColor) * item->height();
QVector3D barColor = baseColor + heightColor;
-
- GLfloat lightStrength = m_cachedTheme.m_lightStrength;
+#else
+ QVector3D barColor;
+ if (m_selection.x() == item->position().x() && m_selection.y() == item->position().y())
+ barColor = Utils::vectorFromColor(m_cachedTheme.m_highlightBarColor);
+ else if (QDataVis::SelectionModeSliceRow == m_cachedSelectionMode)
+ barColor = Utils::vectorFromColor(m_cachedTheme.m_highlightRowColor);
+ else
+ barColor = Utils::vectorFromColor(m_cachedTheme.m_highlightColumnColor);
+#endif
if (item->height() != 0) {
// Set shader bindings
@@ -341,11 +351,16 @@ void Bars3dRenderer::drawSlicedScene(CameraHelper *camera,
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);
-
+ m_barShader->setUniformValue(m_barShader->lightS(), 0.5f);
+ m_barShader->setUniformValue(m_barShader->ambientS(),
+ m_cachedTheme.m_ambientStrength * 2.0f);
// Draw the object
+#if defined (Q_OS_MAC)
+ // Mac slice issue hack fix. TODO: Fix correctly
+ m_drawer->drawObject(m_barShader, m_barObj, 0, -1);
+#else
m_drawer->drawObject(m_barShader, m_barObj);
+#endif
}
}
@@ -357,86 +372,88 @@ void Bars3dRenderer::drawSlicedScene(CameraHelper *camera,
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);
- }
+ 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 (QDataVis::SelectionModeSliceRow == m_cachedSelectionMode) {
if (m_sliceTitleItem) {
m_drawer->drawLabel(*dummyItem, sliceSelectionLabel, viewMatrix, projectionMatrix,
- QVector3D(0.0f, m_yAdjustment, zComp),
+ QVector3D(0.0f, m_autoScaleAdjustment, zComp),
QVector3D(0.0f, 0.0f, 0.0f), 0,
m_cachedSelectionMode, m_labelShader,
- m_labelObj, camera, false, false, Drawer::LabelTop);
+ m_labelObj, m_cachedScene->activeCamera(), false, false, Drawer::LabelTop);
}
m_drawer->drawLabel(*dummyItem, zLabel, viewMatrix, projectionMatrix,
- QVector3D(0.0f, m_yAdjustment, zComp),
+ QVector3D(0.0f, m_autoScaleAdjustment, zComp),
QVector3D(0.0f, 0.0f, 0.0f), 0,
m_cachedSelectionMode, m_labelShader,
- m_labelObj, camera, false, false, Drawer::LabelBottom);
+ m_labelObj, m_cachedScene->activeCamera(), false, false, Drawer::LabelBottom);
} else {
m_drawer->drawLabel(*dummyItem, xLabel, viewMatrix, projectionMatrix,
- QVector3D(0.0f, m_yAdjustment, zComp),
+ QVector3D(0.0f, m_autoScaleAdjustment, zComp),
QVector3D(0.0f, 0.0f, 0.0f), 0,
m_cachedSelectionMode, m_labelShader,
- m_labelObj, camera, false, false, Drawer::LabelBottom);
+ m_labelObj, m_cachedScene->activeCamera(), false, false, Drawer::LabelBottom);
if (m_sliceTitleItem) {
m_drawer->drawLabel(*dummyItem, sliceSelectionLabel, viewMatrix, projectionMatrix,
- QVector3D(0.0f, m_yAdjustment, zComp),
+ QVector3D(0.0f, m_autoScaleAdjustment, zComp),
QVector3D(0.0f, 0.0f, 0.0f), 0,
m_cachedSelectionMode, m_labelShader,
- m_labelObj, camera, false, false, Drawer::LabelTop);
+ m_labelObj, m_cachedScene->activeCamera(), false, false, Drawer::LabelTop);
}
}
m_drawer->drawLabel(*dummyItem, yLabel, viewMatrix, projectionMatrix,
- QVector3D(0.0f, m_yAdjustment, zComp),
+ QVector3D(0.0f, m_autoScaleAdjustment, zComp),
QVector3D(0.0f, 0.0f, 90.0f), 0,
m_cachedSelectionMode, m_labelShader,
- m_labelObj, camera, false, false, Drawer::LabelLeft);
+ m_labelObj, m_cachedScene->activeCamera(), 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);
+ if (negativesComp == 1.0f) {
+ m_drawer->drawLabel(*item, item->sliceLabelItem(), viewMatrix, projectionMatrix,
+ QVector3D(0.0f, m_yAdjustment, zComp),
+ QVector3D(0.0f, 0.0f, 90.0f),
+ item->height(),
+ m_cachedSelectionMode, m_labelShader,
+ m_labelObj, m_cachedScene->activeCamera(), false, false,
+ Drawer::LabelOver, Qt::AlignTop);
+ } else {
+ m_drawer->drawLabel(*item, item->sliceLabelItem(), viewMatrix, projectionMatrix,
+ QVector3D(0.0f, m_yAdjustment, zComp),
+ QVector3D(0.0f, 0.0f, 0.0f),
+ negativesComp * negativesComp * item->height(),
+ m_cachedSelectionMode, m_labelShader,
+ m_labelObj, m_cachedScene->activeCamera());
+ }
// 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);
- }
+ labelItem = m_sliceCache->labelItems().at(col);
m_drawer->drawLabel(*item, *labelItem, viewMatrix, projectionMatrix,
- QVector3D(0.0f, m_yAdjustment, zComp),
+ QVector3D(0.0f, m_autoScaleAdjustment, zComp),
QVector3D(0.0f, 0.0f, -45.0f), item->height(),
m_cachedSelectionMode, m_labelShader,
- m_labelObj, camera, false, false, Drawer::LabelBelow);
+ m_labelObj, m_cachedScene->activeCamera(), false, false,
+ Drawer::LabelBelow);
}
}
glDisable(GL_TEXTURE_2D);
- if (m_cachedLabelTransparency > QDataVis::TransparencyNone)
- glDisable(GL_BLEND);
+ glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
// Release label shader
m_labelShader->release();
}
-void Bars3dRenderer::drawScene(CameraHelper *camera,
- const GLuint defaultFboHandle)
+void Bars3DRenderer::drawScene(GLuint defaultFboHandle)
{
GLint startBar = 0;
GLint stopBar = 0;
@@ -448,11 +465,9 @@ void Bars3dRenderer::drawScene(CameraHelper *camera,
GLfloat backgroundRotation = 0;
- GLfloat barPos = 0;
+ GLfloat colPos = 0;
GLfloat rowPos = 0;
- //m_selection = selectionSkipColor;
-
// Specify viewport
glViewport(m_mainViewPort.x(), m_mainViewPort.y(),
m_mainViewPort.width(), m_mainViewPort.height());
@@ -462,12 +477,8 @@ void Bars3dRenderer::drawScene(CameraHelper *camera,
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);
+ // Get the view matrix
+ QMatrix4x4 viewMatrix = m_cachedScene->activeCamera()->viewMatrix();
// 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)
@@ -510,17 +521,16 @@ void Bars3dRenderer::drawScene(CameraHelper *camera,
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);
+ // Get light position from the scene
+ QVector3D lightPos = m_cachedScene->activeLight()->position();
// 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*/) {
+ if (m_cachedShadowQuality > QDataVis::ShadowQualityNone && !m_cachedIsSlicingActivated) {
// Render scene into a depth texture for using with shadow mapping
// Enable drawing to depth framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, m_depthFrameBuffer);
@@ -531,30 +541,24 @@ void Bars3dRenderer::drawScene(CameraHelper *camera,
// 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);
+ m_mainViewPort.width() * m_shadowQualityMultiplier,
+ m_mainViewPort.height() * m_shadowQualityMultiplier);
// 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 depthLightPos = m_cachedScene->activeCamera()->calculatePositionRelativeToCamera(
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);
+
+ // 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()
+ depthProjectionMatrix.perspective(10.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) {
@@ -562,23 +566,33 @@ void Bars3dRenderer::drawScene(CameraHelper *camera,
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)
+ GLfloat shadowOffset = 0.0f;
+
+ // Set front face culling for negative valued bars and back face culling for
+ // positive valued bars to remove peter-panning issues
+ if (item.height() > 0) {
glCullFace(GL_BACK);
- else
+ if (m_yFlipped)
+ shadowOffset = 0.015f;
+ } else {
glCullFace(GL_FRONT);
+ if (!m_yFlipped)
+ shadowOffset = -0.015f;
+ }
QMatrix4x4 modelMatrix;
QMatrix4x4 MVPMatrix;
- barPos = (bar + 1) * (m_cachedBarSpacing.width());
- rowPos = (row + 1) * (m_cachedBarSpacing.height());
+ colPos = (bar + 0.5f) * (m_cachedBarSpacing.width());
+ rowPos = (row + 0.5f) * (m_cachedBarSpacing.height());
- modelMatrix.translate((m_rowWidth - barPos) / m_scaleFactor,
- item.height() - m_yAdjustment,
+ // Draw shadows for bars "on the other side" a bit off ground to avoid seeing
+ // shadows through the ground
+ modelMatrix.translate((colPos - m_rowWidth) / m_scaleFactor,
+ item.height() - m_yAdjustment + shadowOffset,
(m_columnDepth - rowPos) / m_scaleFactor + zComp);
- modelMatrix.scale(QVector3D(m_scaleX, item.height(), m_scaleZ));
+ // Scale the bars down in X and Z to reduce self-shadowing issues
+ modelMatrix.scale(QVector3D(m_scaleX * 0.9f, item.height(), m_scaleZ * 0.9f));
MVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
@@ -639,7 +653,7 @@ void Bars3dRenderer::drawScene(CameraHelper *camera,
#endif
// Skip selection mode drawing if we're slicing or have no selection mode
- if (!m_cachedIsSlicingActivated && m_cachedSelectionMode > QDataVis::ModeNone) {
+ if (!m_cachedIsSlicingActivated && m_cachedSelectionMode > QDataVis::SelectionModeNone) {
// Bind selection shader
m_selectionShader->bind();
@@ -664,10 +678,10 @@ void Bars3dRenderer::drawScene(CameraHelper *camera,
QMatrix4x4 modelMatrix;
QMatrix4x4 MVPMatrix;
- barPos = (bar + 1) * (m_cachedBarSpacing.width());
- rowPos = (row + 1) * (m_cachedBarSpacing.height());
+ colPos = (bar + 0.5f) * (m_cachedBarSpacing.width());
+ rowPos = (row + 0.5f) * (m_cachedBarSpacing.height());
- modelMatrix.translate((m_rowWidth - barPos) / m_scaleFactor,
+ modelMatrix.translate((colPos - m_rowWidth) / m_scaleFactor,
item.height() - m_yAdjustment,
(m_columnDepth - rowPos) / m_scaleFactor + zComp);
modelMatrix.scale(QVector3D(m_scaleX, item.height(), m_scaleZ));
@@ -711,16 +725,10 @@ void Bars3dRenderer::drawScene(CameraHelper *camera,
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);
+ if (QDataVis::InputStateOnScene == m_controller->inputState()) {
+ m_selection = Utils::getSelection(m_controller->inputPosition(),
+ m_cachedBoundingRect.height());
}
- locker.unlock();
glBindFramebuffer(GL_FRAMEBUFFER, defaultFboHandle);
@@ -752,13 +760,27 @@ void Bars3dRenderer::drawScene(CameraHelper *camera,
// 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 selectionDirty = (m_selection != m_previousSelection
+ || (m_selection != selectionSkipColor
+ && QDataVis::InputStateOnScene == m_controller->inputState()
+ && !m_cachedIsSlicingActivated));
+ if (selectionDirty) {
+ m_previousSelection = m_selection;
+ if (m_sliceSelection) {
+ if (!m_cachedIsSlicingActivated) {
+ m_sliceCache = 0;
+ m_sliceTitleItem = 0;
+ }
+ if (m_sliceSelection->size()) {
+ // Slice doesn't own its items, no need to delete them - just clear
+ m_sliceSelection->clear();
+ }
+ }
}
+
+ // Draw bars
bool barSelectionFound = false;
+ BarRenderItem *selectedBar(0);
for (int row = startRow; row != stopRow; row += stepRow) {
for (int bar = startBar; bar != stopBar; bar += stepBar) {
BarRenderItem &item = m_renderItemArray[row][bar];
@@ -773,9 +795,10 @@ void Bars3dRenderer::drawScene(CameraHelper *camera,
QMatrix4x4 MVPMatrix;
QMatrix4x4 depthMVPMatrix;
- barPos = (bar + 1) * (m_cachedBarSpacing.width());
- rowPos = (row + 1) * (m_cachedBarSpacing.height());
- modelMatrix.translate((m_rowWidth - barPos) / m_scaleFactor,
+ colPos = (bar + 0.5f) * (m_cachedBarSpacing.width());
+ rowPos = (row + 0.5f) * (m_cachedBarSpacing.height());
+
+ modelMatrix.translate((colPos - m_rowWidth) / m_scaleFactor,
item.height() - m_yAdjustment,
(m_columnDepth - rowPos) / m_scaleFactor + zComp);
modelMatrix.scale(QVector3D(m_scaleX, item.height(), m_scaleZ));
@@ -787,69 +810,81 @@ void Bars3dRenderer::drawScene(CameraHelper *camera,
#endif
depthMVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
+#if 0
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));
+ * (float(row) / GLfloat(m_cachedRowCount));
QVector3D barColor = baseColor + heightColor + depthColor;
+#else
+ QVector3D barColor = Utils::vectorFromColor(m_cachedTheme.m_baseColor);
+#endif
GLfloat lightStrength = m_cachedTheme.m_lightStrength;
- if (m_cachedSelectionMode > QDataVis::ModeNone) {
- Bars3dController::SelectionType selectionType = isSelected(row, bar);
+ if (m_cachedSelectionMode > QDataVis::SelectionModeNone) {
+ Bars3DController::SelectionType selectionType = isSelected(row, bar);
switch (selectionType) {
- case Bars3dController::SelectionItem: {
+ 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
+ // Insert position data into render item. We have no ownership, don't delete the previous one
if (!m_cachedIsSlicingActivated) {
- m_selectedBar = &item;
- m_selectedBar->setPosition(QPoint(row, bar));
+ selectedBar = &item;
+ 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);
+ }
+ if (selectionDirty && m_cachedSelectionMode >= QDataVis::SelectionModeSliceRow) {
+ item.setTranslation(modelMatrix.column(3).toVector3D());
+ item.setPosition(QPoint(row, bar));
+ m_sliceSelection->append(&item);
+ barSelectionFound = true;
+ if (m_cachedSelectionMode == QDataVis::SelectionModeSliceRow) {
+ if (m_axisCacheX.labelItems().size() > row)
+ m_sliceTitleItem = m_axisCacheX.labelItems().at(row);
+ if (!m_sliceCache) {
+ // m_sliceCache is the axis for labels, while title comes from different axis.
+ m_sliceCache = &m_axisCacheZ;
+ }
+ } else if (m_cachedSelectionMode == QDataVis::SelectionModeSliceColumn) {
+ if (m_axisCacheZ.labelItems().size() > bar)
+ m_sliceTitleItem = m_axisCacheZ.labelItems().at(bar);
+ if (!m_sliceCache) {
+ // m_sliceCache is the axis for labels, while title comes from different axis.
+ m_sliceCache = &m_axisCacheX;
+ }
}
}
break;
}
- case Bars3dController::SelectionRow: {
+ 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) {
+ if (QDataVis::SelectionModeSliceRow == 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);
- }
+ item.setPosition(QPoint(row, bar));
+ if (selectionDirty)
+ m_sliceSelection->append(&item);
}
break;
}
- case Bars3dController::SelectionColumn: {
+ 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) {
+ if (QDataVis::SelectionModeSliceColumn == 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);
- }
+ item.setPosition(QPoint(row, bar));
+ if (selectionDirty)
+ m_sliceSelection->append(&item);
}
break;
}
- case Bars3dController::SelectionNone: {
+ case Bars3DController::SelectionNone: {
// Current bar is not selected, nor on a row or column
// do nothing
break;
@@ -870,7 +905,8 @@ void Bars3dRenderer::drawScene(CameraHelper *camera,
m_barShader->setUniformValue(m_barShader->ambientS(), m_cachedTheme.m_ambientStrength);
#if !defined(QT_OPENGL_ES_2)
- if (m_cachedShadowQuality > QDataVis::ShadowNone) {
+ if (m_cachedShadowQuality > QDataVis::ShadowQualityNone
+ && !m_cachedIsSlicingActivated) {
// Set shadow shader bindings
m_barShader->setUniformValue(m_barShader->shadowQ(), m_shadowQualityToShader);
m_barShader->setUniformValue(m_barShader->depth(), depthMVPMatrix);
@@ -885,12 +921,20 @@ void Bars3dRenderer::drawScene(CameraHelper *camera,
m_barShader->setUniformValue(m_barShader->lightS(), lightStrength);
// Draw the object
+#if defined (Q_OS_MAC)
+ // Mac slice issue hack fix. TODO: Fix correctly
+ m_drawer->drawObject(m_barShader, m_barObj, 0, -1);
+#else
m_drawer->drawObject(m_barShader, m_barObj);
+#endif
}
}
}
}
+ if (selectionDirty)
+ emit selectedBarPosChanged(QPoint(int(m_selection.x()), int(m_selection.y())));
+
// Release bar shader
m_barShader->release();
@@ -939,7 +983,7 @@ void Bars3dRenderer::drawScene(CameraHelper *camera,
m_cachedTheme.m_ambientStrength * 2.0f);
#if !defined(QT_OPENGL_ES_2)
- if (m_cachedShadowQuality > QDataVis::ShadowNone) {
+ if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) {
// Set shadow shader bindings
m_backgroundShader->setUniformValue(m_backgroundShader->shadowQ(),
m_shadowQualityToShader);
@@ -975,15 +1019,16 @@ void Bars3dRenderer::drawScene(CameraHelper *camera,
// Draw grid lines
if (m_cachedIsGridEnabled && m_heightNormalizer) {
+ ShaderHelper *lineShader = m_backgroundShader;
// Bind bar shader
- m_barShader->bind();
+ lineShader->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);
+ lineShader->setUniformValue(lineShader->lightP(), lightPos);
+ lineShader->setUniformValue(lineShader->view(), viewMatrix);
+ lineShader->setUniformValue(lineShader->color(), barColor);
+ lineShader->setUniformValue(lineShader->ambientS(), m_cachedTheme.m_ambientStrength);
// Floor lines: rows
for (GLfloat row = 0.0f; row <= m_cachedRowCount; row++) {
@@ -992,7 +1037,7 @@ void Bars3dRenderer::drawScene(CameraHelper *camera,
QMatrix4x4 depthMVPMatrix;
QMatrix4x4 itModelMatrix;
- rowPos = (row + 0.5f) * (m_cachedBarSpacing.height());
+ rowPos = row * m_cachedBarSpacing.height();
modelMatrix.translate(0.0f, -m_yAdjustment,
(m_columnDepth - rowPos) / m_scaleFactor + zComp);
modelMatrix.scale(QVector3D(m_rowWidth / m_scaleFactor, gridLineWidth,
@@ -1007,29 +1052,29 @@ void Bars3dRenderer::drawScene(CameraHelper *camera,
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);
+ lineShader->setUniformValue(lineShader->model(), modelMatrix);
+ lineShader->setUniformValue(lineShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ lineShader->setUniformValue(lineShader->MVP(), MVPMatrix);
#if !defined(QT_OPENGL_ES_2)
- if (m_cachedShadowQuality > QDataVis::ShadowNone) {
+ if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) {
// 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);
+ lineShader->setUniformValue(lineShader->shadowQ(), m_shadowQualityToShader);
+ lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix);
+ lineShader->setUniformValue(lineShader->lightS(),
+ m_cachedTheme.m_lightStrength / 10.0f);
// Draw the object
- m_drawer->drawObject(m_barShader, m_gridLineObj, 0, m_depthTexture);
+ m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture);
} else
#endif
{
// Set shadowless shader bindings
- m_barShader->setUniformValue(m_barShader->lightS(), m_cachedTheme.m_lightStrength);
+ lineShader->setUniformValue(lineShader->lightS(), m_cachedTheme.m_lightStrength);
// Draw the object
- m_drawer->drawObject(m_barShader, m_gridLineObj);
+ m_drawer->drawObject(lineShader, m_gridLineObj);
}
}
@@ -1040,8 +1085,8 @@ void Bars3dRenderer::drawScene(CameraHelper *camera,
QMatrix4x4 depthMVPMatrix;
QMatrix4x4 itModelMatrix;
- barPos = (bar + 0.5f) * (m_cachedBarSpacing.width());
- modelMatrix.translate((m_rowWidth - barPos) / m_scaleFactor,
+ colPos = bar * m_cachedBarSpacing.width();
+ modelMatrix.translate((m_rowWidth - colPos) / m_scaleFactor,
-m_yAdjustment, zComp);
modelMatrix.scale(QVector3D(gridLineWidth, gridLineWidth,
m_columnDepth / m_scaleFactor));
@@ -1056,29 +1101,29 @@ void Bars3dRenderer::drawScene(CameraHelper *camera,
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);
+ lineShader->setUniformValue(lineShader->model(), modelMatrix);
+ lineShader->setUniformValue(lineShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ lineShader->setUniformValue(lineShader->MVP(), MVPMatrix);
#if !defined(QT_OPENGL_ES_2)
- if (m_cachedShadowQuality > QDataVis::ShadowNone) {
+ if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) {
// 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);
+ lineShader->setUniformValue(lineShader->shadowQ(), m_shadowQualityToShader);
+ lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix);
+ lineShader->setUniformValue(lineShader->lightS(),
+ m_cachedTheme.m_lightStrength / 10.0f);
// Draw the object
- m_drawer->drawObject(m_barShader, m_gridLineObj, 0, m_depthTexture);
+ m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture);
} else
#endif
{
// Set shadowless shader bindings
- m_barShader->setUniformValue(m_barShader->lightS(), m_cachedTheme.m_lightStrength);
+ lineShader->setUniformValue(lineShader->lightS(), m_cachedTheme.m_lightStrength);
// Draw the object
- m_drawer->drawObject(m_barShader, m_gridLineObj);
+ m_drawer->drawObject(lineShader, m_gridLineObj);
}
}
@@ -1115,29 +1160,29 @@ void Bars3dRenderer::drawScene(CameraHelper *camera,
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);
+ lineShader->setUniformValue(lineShader->model(), modelMatrix);
+ lineShader->setUniformValue(lineShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ lineShader->setUniformValue(lineShader->MVP(), MVPMatrix);
#if !defined(QT_OPENGL_ES_2)
- if (m_cachedShadowQuality > QDataVis::ShadowNone) {
+ if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) {
// 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);
+ lineShader->setUniformValue(lineShader->shadowQ(), m_shadowQualityToShader);
+ lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix);
+ lineShader->setUniformValue(lineShader->lightS(),
+ m_cachedTheme.m_lightStrength / 10.0f);
// Draw the object
- m_drawer->drawObject(m_barShader, m_gridLineObj, 0, m_depthTexture);
+ m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture);
} else
#endif
{
// Set shadowless shader bindings
- m_barShader->setUniformValue(m_barShader->lightS(), m_cachedTheme.m_lightStrength);
+ lineShader->setUniformValue(lineShader->lightS(), m_cachedTheme.m_lightStrength);
// Draw the object
- m_drawer->drawObject(m_barShader, m_gridLineObj);
+ m_drawer->drawObject(lineShader, m_gridLineObj);
}
}
@@ -1167,118 +1212,34 @@ void Bars3dRenderer::drawScene(CameraHelper *camera,
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);
+ lineShader->setUniformValue(lineShader->model(), modelMatrix);
+ lineShader->setUniformValue(lineShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ lineShader->setUniformValue(lineShader->MVP(), MVPMatrix);
#if !defined(QT_OPENGL_ES_2)
- if (m_cachedShadowQuality > QDataVis::ShadowNone) {
+ if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) {
// 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);
+ lineShader->setUniformValue(lineShader->shadowQ(), m_shadowQualityToShader);
+ lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix);
+ lineShader->setUniformValue(lineShader->lightS(),
+ m_cachedTheme.m_lightStrength / 10.0f);
// Draw the object
- m_drawer->drawObject(m_barShader, m_gridLineObj, 0, m_depthTexture);
+ m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture);
} else
#endif
{
// Set shadowless shader bindings
- m_barShader->setUniformValue(m_barShader->lightS(), m_cachedTheme.m_lightStrength);
+ lineShader->setUniformValue(lineShader->lightS(), m_cachedTheme.m_lightStrength);
// Draw the object
- m_drawer->drawObject(m_barShader, m_gridLineObj);
+ m_drawer->drawObject(lineShader, 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;
+ lineShader->release();
}
// TODO: Calculations done temporarily here. When optimizing, move to after data set addition? Keep drawing of the labels here.
@@ -1286,18 +1247,16 @@ void Bars3dRenderer::drawScene(CameraHelper *camera,
m_labelShader->bind();
glEnable(GL_TEXTURE_2D);
- if (m_cachedLabelTransparency > QDataVis::TransparencyNone) {
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- }
+ 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;
+ rowPos = (row + 0.5f) * m_cachedBarSpacing.height();
+ colPos = (m_rowWidth / m_scaleFactor) + labelMargin;
GLfloat rotLabelX = -90.0f;
GLfloat rotLabelY = 0.0f;
GLfloat rotLabelZ = 0.0f;
@@ -1305,7 +1264,7 @@ void Bars3dRenderer::drawScene(CameraHelper *camera,
if (m_zFlipped)
rotLabelY = 180.0f;
if (m_xFlipped) {
- barPos = -m_rowWidth;
+ colPos = -(m_rowWidth / m_scaleFactor) - labelMargin;
alignment = Qt::AlignLeft;
}
if (m_yFlipped) {
@@ -1315,7 +1274,7 @@ void Bars3dRenderer::drawScene(CameraHelper *camera,
rotLabelY = 180.0f;
rotLabelZ = 180.0f;
}
- QVector3D labelPos = QVector3D(barPos / m_scaleFactor,
+ QVector3D labelPos = QVector3D(colPos,
-m_yAdjustment + 0.005f, // raise a bit over background to avoid depth "glimmering"
(m_columnDepth - rowPos) / m_scaleFactor + zComp);
@@ -1327,17 +1286,16 @@ void Bars3dRenderer::drawScene(CameraHelper *camera,
QVector3D(0.0f, m_yAdjustment, zComp),
QVector3D(rotLabelX, rotLabelY, rotLabelZ),
0, m_cachedSelectionMode,
- m_labelShader, m_labelObj, camera, true, true, Drawer::LabelMid,
+ m_labelShader, m_labelObj, m_cachedScene->activeCamera(), true, true, Drawer::LabelMid,
alignment);
}
-
}
- for (int bar = 0; bar != m_cachedColumnCount; bar += 1) {
- if (m_axisCacheZ.labelItems().size() > bar) {
+ for (int column = 0; column != m_cachedColumnCount; column += 1) {
+ if (m_axisCacheZ.labelItems().size() > column) {
// 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;
+ colPos = (column + 0.5f) * m_cachedBarSpacing.width();
+ rowPos = (m_columnDepth / m_scaleFactor) + labelMargin;
GLfloat rotLabelX = -90.0f;
GLfloat rotLabelY = 90.0f;
GLfloat rotLabelZ = 0.0f;
@@ -1345,7 +1303,7 @@ void Bars3dRenderer::drawScene(CameraHelper *camera,
if (m_xFlipped)
rotLabelY = -90.0f;
if (m_zFlipped) {
- rowPos = -m_columnDepth;
+ rowPos = -(m_columnDepth / m_scaleFactor) - labelMargin;
alignment = Qt::AlignRight;
}
if (m_yFlipped) {
@@ -1355,21 +1313,18 @@ void Bars3dRenderer::drawScene(CameraHelper *camera,
rotLabelY = 90.0f;
rotLabelZ = 180.0f;
}
- QVector3D labelPos = QVector3D((m_rowWidth - barPos) / m_scaleFactor,
+ QVector3D labelPos = QVector3D((colPos - m_rowWidth) / 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
+ rowPos + zComp);
m_dummyBarRenderItem.setTranslation(labelPos);
- const LabelItem &axisLabelItem = *m_axisCacheZ.labelItems().at(bar);
- //qDebug() << "labelPos, col" << bar + 1 << ":" << labelPos << m_axisCacheZ.labels().at(bar);
+ const LabelItem &axisLabelItem = *m_axisCacheZ.labelItems().at(column);
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,
+ m_labelShader, m_labelObj, m_cachedScene->activeCamera(), true, true, Drawer::LabelMid,
alignment);
}
}
@@ -1385,6 +1340,8 @@ void Bars3dRenderer::drawScene(CameraHelper *camera,
for (int i = 0; i < labelCount; i++) {
if (m_axisCacheY.labelItems().size() > labelNbr) {
+ GLfloat labelMarginXTrans = labelMargin;
+ GLfloat labelMarginZTrans = labelMargin;
GLfloat labelXTrans = m_rowWidth / m_scaleFactor;
GLfloat labelZTrans = m_columnDepth / m_scaleFactor;
GLfloat labelYTrans = 2.0f * labelPos / m_heightNormalizer - m_yAdjustment;
@@ -1394,17 +1351,20 @@ void Bars3dRenderer::drawScene(CameraHelper *camera,
Qt::AlignmentFlag alignment = Qt::AlignLeft;
if (!m_xFlipped) {
labelXTrans = -labelXTrans;
+ labelMarginXTrans = -labelMargin;
rotLabelY = 90.0f;
}
if (m_zFlipped) {
labelZTrans = -labelZTrans;
+ labelMarginZTrans = -labelMargin;
alignment = Qt::AlignRight;
}
const LabelItem &axisLabelItem = *m_axisCacheY.labelItems().at(labelNbr);
// Back wall
- QVector3D labelTrans = QVector3D(labelXTrans, labelYTrans, labelZTrans + zComp);
+ QVector3D labelTrans = QVector3D(labelXTrans, labelYTrans,
+ labelZTrans + labelMarginZTrans + zComp);
//qDebug() << "labelPos, value:" << labelTrans;
@@ -1413,7 +1373,7 @@ void Bars3dRenderer::drawScene(CameraHelper *camera,
QVector3D(0.0f, m_yAdjustment, zComp),
QVector3D(rotLabelX, rotLabelY, rotLabelZ),
0, m_cachedSelectionMode,
- m_labelShader, m_labelObj, camera, true, true, Drawer::LabelMid,
+ m_labelShader, m_labelObj, m_cachedScene->activeCamera(), true, true, Drawer::LabelMid,
alignment);
// Side wall
@@ -1426,37 +1386,111 @@ void Bars3dRenderer::drawScene(CameraHelper *camera,
else
rotLabelY = 0.0f;
- labelTrans = QVector3D(-labelXTrans, labelYTrans, -labelZTrans + zComp);
+ labelTrans = QVector3D(-labelXTrans - labelMarginXTrans, 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,
+ m_labelShader, m_labelObj, m_cachedScene->activeCamera(), true, true, Drawer::LabelMid,
alignment);
}
labelNbr++;
labelPos += heightStep;
}
+ // Handle slice activation and selection label drawing
+ if (!barSelectionFound) {
+ // We have no ownership, don't delete. Just NULL the pointer.
+ m_selectedBar = NULL;
+ if (m_cachedIsSlicingActivated
+ && (m_selection == selectionSkipColor
+ || QDataVis::InputStateOnOverview == m_controller->inputState())) {
+ m_cachedScene->setSlicingActive(false);
+ }
+ } else if (m_cachedSelectionMode >= QDataVis::SelectionModeSliceRow && selectionDirty) {
+ // Activate slice mode
+ m_cachedScene->setSlicingActive(true);
+
+ // Create label textures
+ for (int col = 0; col < m_sliceSelection->size(); col++) {
+ BarRenderItem *item = m_sliceSelection->at(col);
+ if (item->sliceLabel().isNull())
+ item->setSliceLabel(generateValueLabel(m_axisCacheY.labelFormat(), item->value()));
+ m_drawer->generateLabelItem(item->sliceLabelItem(), item->sliceLabel());
+ }
+ } else {
+ // Print value of selected bar
+ glDisable(GL_DEPTH_TEST);
+ // Draw the selection label
+ LabelItem &labelItem = selectedBar->selectionLabelItem();
+ if (m_selectedBar != selectedBar || m_updateLabels || !labelItem.textureId()) {
+ QString labelText = selectedBar->selectionLabel();
+ if (labelText.isNull()) {
+ static const QString rowIndexTag(QStringLiteral("@rowIdx"));
+ static const QString rowLabelTag(QStringLiteral("@rowLabel"));
+ static const QString rowTitleTag(QStringLiteral("@rowTitle"));
+ static const QString colIndexTag(QStringLiteral("@colIdx"));
+ static const QString colLabelTag(QStringLiteral("@colLabel"));
+ static const QString colTitleTag(QStringLiteral("@colTitle"));
+ static const QString valueTitleTag(QStringLiteral("@valueTitle"));
+ static const QString valueLabelTag(QStringLiteral("@valueLabel"));
+
+ // Custom format expects printf format specifier. There is no tag for it.
+ labelText = generateValueLabel(itemLabelFormat(), selectedBar->value());
+
+ int selBarPosX = selectedBar->position().x();
+ int selBarPosY = selectedBar->position().y();
+ labelText.replace(rowIndexTag, QString::number(selBarPosX));
+ if (m_axisCacheX.labels().size() > selBarPosX)
+ labelText.replace(rowLabelTag, m_axisCacheX.labels().at(selBarPosX));
+ else
+ labelText.replace(rowLabelTag, QString());
+ labelText.replace(rowTitleTag, m_axisCacheX.title());
+ labelText.replace(colIndexTag, QString::number(selBarPosY));
+ if (m_axisCacheZ.labels().size() > selBarPosY)
+ labelText.replace(colLabelTag, m_axisCacheZ.labels().at(selBarPosY));
+ else
+ labelText.replace(colLabelTag, QString());
+ labelText.replace(colTitleTag, m_axisCacheZ.title());
+ labelText.replace(valueTitleTag, m_axisCacheY.title());
+
+ if (labelText.contains(valueLabelTag)) {
+ QString labelFormat = m_axisCacheY.labelFormat();
+ if (labelFormat.isEmpty())
+ labelFormat = Utils::defaultLabelFormat();
+ QString valueLabelText = generateValueLabel(labelFormat, selectedBar->value());
+ labelText.replace(valueLabelTag, valueLabelText);
+ }
+
+ selectedBar->setSelectionLabel(labelText);
+ }
+ m_drawer->generateLabelItem(labelItem, labelText);
+ m_selectedBar = selectedBar;
+ }
+
+ m_drawer->drawLabel(*selectedBar, labelItem, viewMatrix, projectionMatrix,
+ QVector3D(0.0f, m_yAdjustment, zComp),
+ QVector3D(0.0f, 0.0f, 0.0f), selectedBar->height(),
+ m_cachedSelectionMode, m_labelShader,
+ m_labelObj, m_cachedScene->activeCamera(), true, false);
+
+ // Reset label update flag; they should have been updated when we get here
+ m_updateLabels = false;
+
+ glEnable(GL_DEPTH_TEST);
+ }
+
glDisable(GL_TEXTURE_2D);
- if (m_cachedLabelTransparency > QDataVis::TransparencyNone)
- glDisable(GL_BLEND);
+ 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()
+void Bars3DRenderer::handleResize()
{
if (m_cachedBoundingRect.width() == 0 || m_cachedBoundingRect.height() == 0)
return;
@@ -1467,121 +1501,121 @@ void Bars3dRenderer::handleResize()
m_cachedBoundingRect.height() - m_cachedBoundingRect.height() / 5,
m_cachedBoundingRect.width() / 5,
m_cachedBoundingRect.height() / 5);
+ m_sliceViewPort = QRect(0, 0, m_cachedBoundingRect.width(), m_cachedBoundingRect.height());
} else {
m_mainViewPort = QRect(0, 0, m_cachedBoundingRect.width(), m_cachedBoundingRect.height());
+ m_sliceViewPort = QRect(0, 0, 0, 0);
}
- m_sliceViewPort = QRect(0, 0, m_cachedBoundingRect.width(), m_cachedBoundingRect.height());
Abstract3DRenderer::handleResize();
}
-void Bars3dRenderer::updateBarSpecs(QSizeF thickness, QSizeF spacing, bool relative)
+void Bars3DRenderer::updateBarSpecs(GLfloat thicknessRatio, const QSizeF &spacing, bool relative)
{
- m_cachedBarThickness = thickness;
+ // Convert ratio to QSizeF, as we need it in that format for autoscaling calculations
+ m_cachedBarThickness.setWidth(1.0f);
+ m_cachedBarThickness.setHeight(1.0f / thicknessRatio);
+
if (relative) {
- m_cachedBarSpacing.setWidth((thickness.width() * 2) * (spacing.width() + 1.0f));
- m_cachedBarSpacing.setHeight((thickness.height() * 2) * (spacing.height() + 1.0f));
+ m_cachedBarSpacing.setWidth((m_cachedBarThickness.width() * 2) * (spacing.width() + 1.0f));
+ m_cachedBarSpacing.setHeight((m_cachedBarThickness.height() * 2) * (spacing.height() + 1.0f));
} else {
- m_cachedBarSpacing = thickness * 2 + spacing * 2;
+ m_cachedBarSpacing = m_cachedBarThickness * 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)
+void Bars3DRenderer::updateAxisRange(Q3DAbstractAxis::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.";
-}
+ if (orientation == Q3DAbstractAxis::AxisOrientationY) {
+ calculateHeightAdjustment();
+ // Check if we have negative values
+ if (min < 0 && !m_hasNegativeValues) {
+ m_hasNegativeValues = true;
+ // Reload background
+ loadBackgroundMesh();
+ emit needRender();
+ } else if (min >= 0 && m_hasNegativeValues) {
+ m_hasNegativeValues = false;
+ // Reload background
+ loadBackgroundMesh();
+ emit needRender();
+ }
-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);
+ // TODO Currently bargraph only supports zero centered or zero minimum ranges
+ if (min > 0.0 || (min != 0.0 && (qFabs(min) != qFabs(max)))) {
+ qWarning() << __FUNCTION__ << "Bar graph currently properly supports only "
+ "zero-centered and zero minimum ranges for Y-axis.";
+ }
}
-
- // 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)
+void Bars3DRenderer::updateSelectionMode(QDataVis::SelectionMode mode)
{
Abstract3DRenderer::updateSelectionMode(mode);
// Create zoom selection if there isn't one
- if (mode >= QDataVis::ModeZoomRow && !m_sliceSelection) {
+ if (mode >= QDataVis::SelectionModeSliceRow && !m_sliceSelection) {
m_sliceSelection = new QList<BarRenderItem *>;
- if (mode == QDataVis::ModeZoomRow)
+ if (mode == QDataVis::SelectionModeSliceRow)
m_sliceSelection->reserve(m_cachedRowCount);
else
m_sliceSelection->reserve(m_cachedColumnCount);
}
}
-void Bars3dRenderer::updateBackgroundEnabled(bool enable)
+void Bars3DRenderer::updateBackgroundEnabled(bool enable)
{
if (enable != m_cachedIsBackgroundEnabled) {
Abstract3DRenderer::updateBackgroundEnabled(enable);
- loadBarMesh(); // Load changed bar type
+ loadMeshFile(); // Load changed bar type
}
}
-void Bars3dRenderer::updateShadowQuality(QDataVis::ShadowQuality quality)
+void Bars3DRenderer::updateSelectedBarPos(const QPoint &position)
+{
+ if (position == Bars3DController::noSelectionPoint())
+ m_selection = selectionSkipColor;
+ else
+ m_selection = QVector3D(position.x(), position.y(), 0);
+ emit needRender();
+}
+
+void Bars3DRenderer::updateShadowQuality(QDataVis::ShadowQuality quality)
{
- qDebug() << __FUNCTION__ << quality;
m_cachedShadowQuality = quality;
switch (quality) {
- case QDataVis::ShadowLow:
+ case QDataVis::ShadowQualityLow:
m_shadowQualityToShader = 33.3f;
+ m_shadowQualityMultiplier = 1;
break;
- case QDataVis::ShadowMedium:
+ case QDataVis::ShadowQualityMedium:
m_shadowQualityToShader = 100.0f;
+ m_shadowQualityMultiplier = 3;
break;
- case QDataVis::ShadowHigh:
+ case QDataVis::ShadowQualityHigh:
m_shadowQualityToShader = 200.0f;
+ m_shadowQualityMultiplier = 5;
+ break;
+ case QDataVis::ShadowQualitySoftLow:
+ m_shadowQualityToShader = 7.5f;
+ m_shadowQualityMultiplier = 1;
+ break;
+ case QDataVis::ShadowQualitySoftMedium:
+ m_shadowQualityToShader = 10.0f;
+ m_shadowQualityMultiplier = 3;
+ break;
+ case QDataVis::ShadowQualitySoftHigh:
+ m_shadowQualityToShader = 15.0f;
+ m_shadowQualityMultiplier = 4;
break;
default:
m_shadowQualityToShader = 0.0f;
+ m_shadowQualityMultiplier = 1;
break;
}
@@ -1593,7 +1627,7 @@ void Bars3dRenderer::updateShadowQuality(QDataVis::ShadowQuality quality)
#endif
}
-void Bars3dRenderer::loadBarMesh()
+void Bars3DRenderer::loadMeshFile()
{
QString objectFileName = m_cachedObjFile;
if (m_barObj)
@@ -1605,7 +1639,7 @@ void Bars3dRenderer::loadBarMesh()
m_barObj->load();
}
-void Bars3dRenderer::loadBackgroundMesh()
+void Bars3DRenderer::loadBackgroundMesh()
{
if (m_backgroundObj)
delete m_backgroundObj;
@@ -1616,7 +1650,7 @@ void Bars3dRenderer::loadBackgroundMesh()
m_backgroundObj->load();
}
-void Bars3dRenderer::loadGridLineMesh()
+void Bars3DRenderer::loadGridLineMesh()
{
if (m_gridLineObj)
delete m_gridLineObj;
@@ -1624,7 +1658,7 @@ void Bars3dRenderer::loadGridLineMesh()
m_gridLineObj->load();
}
-void Bars3dRenderer::loadLabelMesh()
+void Bars3DRenderer::loadLabelMesh()
{
if (m_labelObj)
delete m_labelObj;
@@ -1632,17 +1666,17 @@ void Bars3dRenderer::loadLabelMesh()
m_labelObj->load();
}
-void Bars3dRenderer::updateTextures()
+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()
+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_rowWidth = (m_cachedColumnCount * m_cachedBarSpacing.width()) / 2.0f;
+ m_columnDepth = (m_cachedRowCount * 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)));
@@ -1653,7 +1687,7 @@ void Bars3dRenderer::calculateSceneScalingFactors()
//qDebug() << "m_rowWidth:" << m_rowWidth << "m_columnDepth:" << m_columnDepth << "m_maxDimension:" << m_maxDimension;
}
-void Bars3dRenderer::calculateHeightAdjustment()
+void Bars3DRenderer::calculateHeightAdjustment()
{
m_heightNormalizer = (GLfloat)qMax(qFabs(m_axisCacheY.min()), qFabs(m_axisCacheY.max()));
@@ -1666,10 +1700,10 @@ void Bars3dRenderer::calculateHeightAdjustment()
//qDebug() << m_yAdjustment;
}
-Bars3dController::SelectionType Bars3dRenderer::isSelected(GLint row, GLint bar)
+Bars3DController::SelectionType Bars3DRenderer::isSelected(GLint row, GLint bar)
{
//static QVector3D prevSel = m_selection; // TODO: For debugging
- Bars3dController::SelectionType isSelectedType = Bars3dController::SelectionNone;
+ Bars3DController::SelectionType isSelectedType = Bars3DController::SelectionNone;
if (m_selection == selectionSkipColor)
return isSelectedType; // skip window
@@ -1686,39 +1720,52 @@ Bars3dController::SelectionType Bars3dRenderer::isSelected(GLint row, GLint bar)
// prevSel = selection;
//}
if (current == m_selection) {
- isSelectedType = Bars3dController::SelectionItem;
+ 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.y() == m_selection.y() && (m_cachedSelectionMode == QDataVis::SelectionModeItemAndColumn
+ || m_cachedSelectionMode == QDataVis::SelectionModeItemRowAndColumn
+ || m_cachedSelectionMode == QDataVis::SelectionModeSliceColumn)) {
+ 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;
+ else if (current.x() == m_selection.x() && (m_cachedSelectionMode == QDataVis::SelectionModeItemAndRow
+ || m_cachedSelectionMode == QDataVis::SelectionModeItemRowAndColumn
+ || m_cachedSelectionMode == QDataVis::SelectionModeSliceRow)) {
+ isSelectedType = Bars3DController::SelectionRow;
}
return isSelectedType;
}
-void Bars3dRenderer::updateSlicingActive(bool isSlicing)
+void Bars3DRenderer::updateSlicingActive(bool isSlicing)
{
+ if (isSlicing == m_cachedIsSlicingActivated)
+ return;
+
m_cachedIsSlicingActivated = isSlicing;
if (isSlicing) {
m_mainViewPort = QRect(0, m_cachedBoundingRect.height() - m_cachedBoundingRect.height() / 5,
m_cachedBoundingRect.width() / 5, m_cachedBoundingRect.height() / 5);
+ m_sliceViewPort = QRect(0, 0, m_cachedBoundingRect.width(), m_cachedBoundingRect.height());
+ if (m_depthTexture) {
+ m_textureHelper->deleteTexture(&m_depthTexture);
+ m_depthTexture = 0;
+ }
} else {
m_mainViewPort = QRect(0, 0, this->m_cachedBoundingRect.width(),
this->m_cachedBoundingRect.height());
+ m_sliceViewPort = QRect(0, 0, 0, 0);
+ initSelectionBuffer(); // We need to re-init selection buffer in case there has been a resize
+#if !defined(QT_OPENGL_ES_2)
+ updateDepthBuffer(); // Re-init depth buffer as well
+#endif
}
}
-QRect Bars3dRenderer::mainViewPort()
+QRect Bars3DRenderer::mainViewPort()
{
return m_mainViewPort;
}
-void Bars3dRenderer::initShaders(const QString &vertexShader, const QString &fragmentShader)
+void Bars3DRenderer::initShaders(const QString &vertexShader, const QString &fragmentShader)
{
if (m_barShader)
delete m_barShader;
@@ -1726,7 +1773,7 @@ void Bars3dRenderer::initShaders(const QString &vertexShader, const QString &fra
m_barShader->initialize();
}
-void Bars3dRenderer::initSelectionShader()
+void Bars3DRenderer::initSelectionShader()
{
if (m_selectionShader)
delete m_selectionShader;
@@ -1735,8 +1782,11 @@ void Bars3dRenderer::initSelectionShader()
m_selectionShader->initialize();
}
-void Bars3dRenderer::initSelectionBuffer()
+void Bars3DRenderer::initSelectionBuffer()
{
+ if (m_cachedIsSlicingActivated)
+ return;
+
if (m_selectionTexture)
m_textureHelper->deleteTexture(&m_selectionTexture);
@@ -1746,7 +1796,7 @@ void Bars3dRenderer::initSelectionBuffer()
}
#if !defined(QT_OPENGL_ES_2)
-void Bars3dRenderer::initDepthShader()
+void Bars3DRenderer::initDepthShader()
{
if (m_depthShader)
delete m_depthShader;
@@ -1755,30 +1805,51 @@ void Bars3dRenderer::initDepthShader()
m_depthShader->initialize();
}
-void Bars3dRenderer::updateDepthBuffer()
+void Bars3DRenderer::updateDepthBuffer()
{
+ if (m_cachedIsSlicingActivated)
+ return;
+
if (m_depthTexture) {
m_textureHelper->deleteTexture(&m_depthTexture);
m_depthTexture = 0;
}
- if (m_cachedShadowQuality > QDataVis::ShadowNone) {
+ if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) {
m_depthTexture = m_textureHelper->createDepthTexture(m_mainViewPort.size(),
m_depthFrameBuffer,
- m_cachedShadowQuality);
+ m_shadowQualityMultiplier);
if (!m_depthTexture) {
switch (m_cachedShadowQuality) {
- case QDataVis::ShadowHigh:
+ case QDataVis::ShadowQualityHigh:
qWarning("Creating high quality shadows failed. Changing to medium quality.");
- (void)m_controller->setShadowQuality(QDataVis::ShadowMedium);
+ (void)m_controller->setShadowQuality(QDataVis::ShadowQualityMedium);
+ updateShadowQuality(QDataVis::ShadowQualityMedium);
break;
- case QDataVis::ShadowMedium:
+ case QDataVis::ShadowQualityMedium:
qWarning("Creating medium quality shadows failed. Changing to low quality.");
- (void)m_controller->setShadowQuality(QDataVis::ShadowLow);
+ (void)m_controller->setShadowQuality(QDataVis::ShadowQualityLow);
+ updateShadowQuality(QDataVis::ShadowQualityLow);
break;
- case QDataVis::ShadowLow:
+ case QDataVis::ShadowQualityLow:
qWarning("Creating low quality shadows failed. Switching shadows off.");
- (void)m_controller->setShadowQuality(QDataVis::ShadowNone);
+ (void)m_controller->setShadowQuality(QDataVis::ShadowQualityNone);
+ updateShadowQuality(QDataVis::ShadowQualityNone);
+ break;
+ case QDataVis::ShadowQualitySoftHigh:
+ qWarning("Creating soft high quality shadows failed. Changing to soft medium quality.");
+ (void)m_controller->setShadowQuality(QDataVis::ShadowQualitySoftMedium);
+ updateShadowQuality(QDataVis::ShadowQualitySoftMedium);
+ break;
+ case QDataVis::ShadowQualitySoftMedium:
+ qWarning("Creating soft medium quality shadows failed. Changing to soft low quality.");
+ (void)m_controller->setShadowQuality(QDataVis::ShadowQualitySoftLow);
+ updateShadowQuality(QDataVis::ShadowQualitySoftLow);
+ break;
+ case QDataVis::ShadowQualitySoftLow:
+ qWarning("Creating soft low quality shadows failed. Switching shadows off.");
+ (void)m_controller->setShadowQuality(QDataVis::ShadowQualityNone);
+ updateShadowQuality(QDataVis::ShadowQualityNone);
break;
default:
// You'll never get here
@@ -1789,7 +1860,7 @@ void Bars3dRenderer::updateDepthBuffer()
}
#endif
-void Bars3dRenderer::initBackgroundShaders(const QString &vertexShader,
+void Bars3DRenderer::initBackgroundShaders(const QString &vertexShader,
const QString &fragmentShader)
{
if (m_backgroundShader)
@@ -1798,7 +1869,7 @@ void Bars3dRenderer::initBackgroundShaders(const QString &vertexShader,
m_backgroundShader->initialize();
}
-void Bars3dRenderer::initLabelShaders(const QString &vertexShader, const QString &fragmentShader)
+void Bars3DRenderer::initLabelShaders(const QString &vertexShader, const QString &fragmentShader)
{
if (m_labelShader)
delete m_labelShader;
@@ -1806,4 +1877,4 @@ void Bars3dRenderer::initLabelShaders(const QString &vertexShader, const QString
m_labelShader->initialize();
}
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavis3d/engine/bars3drenderer_p.h b/src/datavisualization/engine/bars3drenderer_p.h
index 93d47cf1..9b612474 100644
--- a/src/datavis3d/engine/bars3drenderer_p.h
+++ b/src/datavisualization/engine/bars3drenderer_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -29,47 +29,30 @@
#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 "datavisualizationglobal_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
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
class ShaderHelper;
class ObjectHelper;
-class TextureHelper;
-class Theme;
-class Drawer;
class LabelItem;
-class CameraHelper;
+class Q3DScene;
-class QT_DATAVIS3D_EXPORT Bars3dRenderer : public Abstract3DRenderer
+class QT_DATAVISUALIZATION_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;
+ Bars3DController *m_controller;
// Cached state based on emitted signals from the controller
QSizeF m_cachedBarThickness;
@@ -80,7 +63,6 @@ private:
// 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
@@ -99,7 +81,6 @@ private:
ObjectHelper *m_backgroundObj;
ObjectHelper *m_gridLineObj;
ObjectHelper *m_labelObj;
- TextureHelper *m_textureHelper;
GLuint m_bgrTexture;
GLuint m_depthTexture;
GLuint m_selectionTexture;
@@ -107,6 +88,7 @@ private:
GLuint m_selectionFrameBuffer;
GLuint m_selectionDepthBuffer;
GLfloat m_shadowQualityToShader;
+ GLint m_shadowQualityMultiplier;
GLfloat m_heightNormalizer;
GLfloat m_yAdjustment;
GLfloat m_rowWidth;
@@ -117,63 +99,51 @@ private:
GLfloat m_scaleFactor;
GLfloat m_maxSceneSize;
QVector3D m_selection;
-
- QPoint m_selectionPointRequest;
- bool m_isSelectionPointRequestActive;
+ QVector3D m_previousSelection;
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();
+ explicit Bars3DRenderer(Bars3DController *controller);
+ ~Bars3DRenderer();
void updateDataModel(QBarDataProxy *dataProxy);
- void render(CameraHelper *camera, const GLuint defaultFboHandle = 0);
+ void updateScene(Q3DScene *scene);
+ void render(GLuint defaultFboHandle = 0);
QRect mainViewPort();
+protected:
+ virtual void initializeOpenGL();
+ virtual void loadMeshFile();
+
public slots:
- void updateBarSpecs(QSizeF thickness = QSizeF(1.0f, 1.0f),
- QSizeF spacing = QSizeF(1.0f, 1.0f),
+ void updateBarSpecs(GLfloat thicknessRatio = 1.0f,
+ const QSizeF &spacing = QSizeF(1.0, 1.0),
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);
+ void updateSelectedBarPos(const QPoint &position);
// 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);
+ virtual void updateAxisRange(Q3DAbstractAxis::AxisOrientation orientation, qreal min, qreal max);
signals:
- void selectionUpdated(QVector3D selection);
+ void selectedBarPosChanged(QPoint position);
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 drawSlicedScene(const LabelItem &xLabel, const LabelItem &yLabel, const LabelItem &zLabel);
+ void drawScene(GLuint defaultFboHandle);
void handleResize();
- void loadBarMesh();
void loadBackgroundMesh();
void loadGridLineMesh();
void loadLabelMesh();
@@ -189,12 +159,12 @@ private:
void calculateHeightAdjustment();
Abstract3DController::SelectionType isSelected(GLint row, GLint bar);
- Q_DISABLE_COPY(Bars3dRenderer)
+ Q_DISABLE_COPY(Bars3DRenderer)
friend class BarRenderItem;
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif
diff --git a/src/datavis3d/engine/drawer.cpp b/src/datavisualization/engine/drawer.cpp
index 5d524963..9d50186d 100644
--- a/src/datavis3d/engine/drawer.cpp
+++ b/src/datavisualization/engine/drawer.cpp
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -16,13 +16,13 @@
**
****************************************************************************/
-#include "qdatavis3denums.h"
+#include "qdatavisualizationenums.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 "q3dcamera.h"
#include "utils_p.h"
#include "texturehelper_p.h"
#include <QMatrix4x4>
@@ -39,18 +39,19 @@ public:
};
StaticLibInitializer staticLibInitializer;
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
-Drawer::Drawer(const Theme &theme, const QFont &font, QDataVis::LabelTransparency transparency)
+Drawer::Drawer(const Theme &theme, const QFont &font, QDataVis::LabelStyle style)
: m_theme(theme),
m_font(font),
- m_transparency(transparency),
+ m_style(style),
m_textureHelper(0)
{
}
Drawer::~Drawer()
{
+ delete m_textureHelper;
}
void Drawer::initializeOpenGL()
@@ -67,15 +68,25 @@ void Drawer::setTheme(const Theme &theme)
emit drawerChanged();
}
+Theme Drawer::theme() const
+{
+ return m_theme;
+}
+
void Drawer::setFont(const QFont &font)
{
m_font = font;
emit drawerChanged();
}
-void Drawer::setTransparency(QDataVis::LabelTransparency transparency)
+QFont Drawer::font() const
+{
+ return m_font;
+}
+
+void Drawer::setStyle(QDataVis::LabelStyle style)
{
- m_transparency = transparency;
+ m_style = style;
emit drawerChanged();
}
@@ -175,7 +186,7 @@ void Drawer::drawLabel(const AbstractRenderItem &item, const LabelItem &labelIte
const QVector3D &positionComp, const QVector3D &rotation,
GLfloat itemHeight, QDataVis::SelectionMode mode,
ShaderHelper *shader, ObjectHelper *object,
- CameraHelper *camera,
+ const Q3DCamera *camera,
bool useDepth, bool rotateAlong,
LabelPosition position, Qt::AlignmentFlag alignment)
{
@@ -186,13 +197,13 @@ void Drawer::drawLabel(const AbstractRenderItem &item, const LabelItem &labelIte
QSize textureSize = labelItem.size();
QMatrix4x4 modelMatrix;
QMatrix4x4 MVPMatrix;
- GLfloat xPosition;
- GLfloat yPosition;
+ GLfloat xPosition = 0.0f;
+ GLfloat yPosition = 0.0f;
GLfloat zPosition = positionComp.z();
switch (position) {
case LabelBelow: {
- yPosition = -1.6f; // minus maximum negative height (+ some extra for label)
+ yPosition = -2.6f + positionComp.y(); // minus maximum negative height (+ some extra for axis title label)
break;
}
case LabelLow: {
@@ -210,31 +221,30 @@ void Drawer::drawLabel(const AbstractRenderItem &item, const LabelItem &labelIte
break;
}
case LabelOver: {
- float mod = 0.1f;
+ float mod = 0.3f;
if (itemHeight < 0)
- mod = -0.1f;
- yPosition = item.translation().y() - (positionComp.y() / 2.0f - 0.2f)
- + itemHeight + mod;
+ mod = 0.15f;
+ yPosition = item.translation().y() - (positionComp.y() / 2.0f) + itemHeight + mod;
break;
}
case LabelBottom: {
- yPosition = -1.95f; // TODO: Calculate from scene
+ yPosition = -2.95f + positionComp.y();
xPosition = 0.0f;
break;
}
case LabelTop: {
- yPosition = 1.95f; // TODO: Calculate from scene
+ yPosition = 2.95f - positionComp.y();
xPosition = 0.0f;
break;
}
case LabelLeft: {
yPosition = 0.0f;
- xPosition = -2.5f; // TODO: Calculate from scene
+ xPosition = -2.95f;
break;
}
case LabelRight: {
yPosition = 0.0f;
- xPosition = 2.5f; // TODO: Calculate from scene
+ xPosition = 2.95f;
break;
}
}
@@ -245,6 +255,7 @@ void Drawer::drawLabel(const AbstractRenderItem &item, const LabelItem &labelIte
// Apply alignment
GLfloat xAlignment = 0.0f;
+ GLfloat yAlignment = 0.0f;
GLfloat zAlignment = 0.0f;
switch (alignment) {
case Qt::AlignLeft: {
@@ -261,6 +272,20 @@ void Drawer::drawLabel(const AbstractRenderItem &item, const LabelItem &labelIte
* qFabs(qSin(qDegreesToRadians(rotation.y())));
break;
}
+ case Qt::AlignTop: {
+ yAlignment = ((GLfloat)textureSize.width() * scaleFactor)
+ * qFabs(qCos(qDegreesToRadians(rotation.y())));
+ if (itemHeight < 0)
+ yAlignment = -yAlignment;
+ break;
+ }
+ case Qt::AlignBottom: {
+ yAlignment = (-(GLfloat)textureSize.width() * scaleFactor)
+ * qFabs(qCos(qDegreesToRadians(rotation.y())));
+ if (itemHeight < 0)
+ yAlignment = -yAlignment;
+ break;
+ }
default: {
break;
}
@@ -270,12 +295,12 @@ void Drawer::drawLabel(const AbstractRenderItem &item, const LabelItem &labelIte
xPosition = item.translation().x();
if (useDepth)
zPosition = item.translation().z();
- else if (QDataVis::ModeZoomColumn == mode)
+ else if (QDataVis::SelectionModeSliceColumn == mode)
xPosition = -(item.translation().z()) + positionComp.z(); // flip first to left
}
// Position label
- modelMatrix.translate(xPosition + xAlignment, yPosition, zPosition + zAlignment);
+ modelMatrix.translate(xPosition + xAlignment, yPosition + yAlignment, zPosition + zAlignment);
// Rotate
// TODO: We should convert rotations to use quaternions to avoid rotation order problems
@@ -289,10 +314,12 @@ void Drawer::drawLabel(const AbstractRenderItem &item, const LabelItem &labelIte
modelMatrix.rotate(rotation.x(), 1.0f, 0.0f, 0.0f);
if (useDepth && !rotateAlong) {
+ qreal yComp = qreal(qRadiansToDegrees(qTan(positionComp.y() / cameraDistance)));
// Apply negative camera rotations to keep labels facing camera
- QPointF camRotations = camera->getCameraRotations();
- modelMatrix.rotate(-camRotations.x(), 0.0f, 1.0f, 0.0f);
- modelMatrix.rotate(-camRotations.y(), 1.0f, 0.0f, 0.0f);
+ qreal camRotationX = camera->xRotation();
+ qreal camRotationY = camera->yRotation();
+ modelMatrix.rotate(-camRotationX, 0.0f, 1.0f, 0.0f);
+ modelMatrix.rotate(-camRotationY - yComp, 1.0f, 0.0f, 0.0f);
}
// Scale label based on text size
@@ -309,30 +336,34 @@ void Drawer::drawLabel(const AbstractRenderItem &item, const LabelItem &labelIte
drawObject(shader, object, labelItem.textureId());
}
-void Drawer::generateLabelTexture(AbstractRenderItem *item)
+void Drawer::generateSelectionLabelTexture(AbstractRenderItem *item)
{
- LabelItem &labelItem = item->labelItem();
- generateLabelItem(labelItem, item->label());
+ LabelItem &labelItem = item->selectionLabelItem();
+ generateLabelItem(labelItem, item->selectionLabel());
}
-void Drawer::generateLabelItem(LabelItem &item, const QString &text)
+void Drawer::generateLabelItem(LabelItem &item, const QString &text, int widestLabel)
{
initializeOpenGL();
item.clear();
- // Create labels
- // Print label into a QImage using QPainter
- QImage label = Utils::printTextToImage(m_font,
- text,
- m_theme.m_textBackgroundColor,
- m_theme.m_textColor,
- m_transparency);
-
- // Set label size
- item.setSize(label.size());
- // Insert text texture into label (also deletes the old texture)
- item.setTextureId(m_textureHelper->create2DTexture(label, true, true));
+ if (!text.isEmpty()) {
+ // Create labels
+ // Print label into a QImage using QPainter
+ QImage label = Utils::printTextToImage(m_font,
+ text,
+ m_theme.m_textBackgroundColor,
+ m_theme.m_textColor,
+ m_style,
+ m_theme.m_labelBorders,
+ widestLabel);
+
+ // Set label size
+ item.setSize(label.size());
+ // Insert text texture into label (also deletes the old texture)
+ item.setTextureId(m_textureHelper->create2DTexture(label, true, true));
+ }
}
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavis3d/engine/drawer_p.h b/src/datavisualization/engine/drawer_p.h
index 3139fbe0..89a4ce8c 100644
--- a/src/datavis3d/engine/drawer_p.h
+++ b/src/datavisualization/engine/drawer_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -29,21 +29,21 @@
#ifndef DRAWER_P_H
#define DRAWER_P_H
-#include "datavis3dglobal_p.h"
+#include "datavisualizationglobal_p.h"
#include "q3dbars.h"
#include "theme_p.h"
#include "labelitem_p.h"
#include "abstractrenderitem_p.h"
#include <QFont>
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
class ShaderHelper;
class ObjectHelper;
class AbstractObjectHelper;
class SurfaceObject;
class TextureHelper;
-class CameraHelper;
+class Q3DCamera;
class Drawer : public QObject, public QOpenGLFunctions
{
@@ -63,14 +63,16 @@ public:
};
public:
- explicit Drawer(const Theme &theme, const QFont &font, QDataVis::LabelTransparency transparency);
+ explicit Drawer(const Theme &theme, const QFont &font, QDataVis::LabelStyle style);
~Drawer();
void initializeOpenGL();
void setTheme(const Theme &theme);
+ Theme theme() const;
void setFont(const QFont &font);
- void setTransparency(QDataVis::LabelTransparency transparency);
+ QFont font() const;
+ void setStyle(QDataVis::LabelStyle style);
void drawObject(ShaderHelper *shader, AbstractObjectHelper *object, GLuint textureId = 0,
GLuint depthTextureId = 0);
@@ -79,13 +81,13 @@ public:
const QMatrix4x4 &viewmatrix, const QMatrix4x4 &projectionmatrix,
const QVector3D &positionComp, const QVector3D &rotation, GLfloat itemHeight,
QDataVis::SelectionMode mode, ShaderHelper *shader, ObjectHelper *object,
- CameraHelper *camera,
+ const Q3DCamera *camera,
bool useDepth = false, bool rotateAlong = false,
LabelPosition position = LabelOver,
Qt::AlignmentFlag alignment = Qt::AlignCenter);
- void generateLabelTexture(AbstractRenderItem *item);
- void generateLabelItem(LabelItem &item, const QString &text);
+ void generateSelectionLabelTexture(AbstractRenderItem *item);
+ void generateLabelItem(LabelItem &item, const QString &text, int widestLabel = 0);
Q_SIGNALS:
void drawerChanged();
@@ -93,10 +95,10 @@ Q_SIGNALS:
private:
Theme m_theme;
QFont m_font;
- QDataVis::LabelTransparency m_transparency;
+ QDataVis::LabelStyle m_style;
TextureHelper *m_textureHelper;
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif
diff --git a/src/datavis3d/engine/engine.pri b/src/datavisualization/engine/engine.pri
index 5dc415e1..4c905fe9 100644
--- a/src/datavis3d/engine/engine.pri
+++ b/src/datavisualization/engine/engine.pri
@@ -2,14 +2,10 @@ HEADERS += $$PWD/q3dwindow_p.h \
$$PWD/q3dwindow.h \
$$PWD/q3dbars.h \
$$PWD/q3dbars_p.h \
- $$PWD/q3dmaps.h \
- $$PWD/q3dmaps_p.h \
$$PWD/theme_p.h \
$$PWD/drawer_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 \
@@ -20,17 +16,24 @@ HEADERS += $$PWD/q3dwindow_p.h \
$$PWD/scatter3dcontroller_p.h \
$$PWD/scatter3drenderer_p.h \
$$PWD/axisrendercache_p.h \
- $$PWD/abstract3drenderer_p.h
+ $$PWD/abstract3drenderer_p.h \
+ $$PWD/selectionpointer_p.h \
+ $$PWD/q3dcamera.h \
+ $$PWD/q3dcamera_p.h \
+ $$PWD/q3dscene.h \
+ $$PWD/q3dlight.h \
+ $$PWD/q3dlight_p.h \
+ $$PWD/q3dbox.h \
+ $$PWD/q3dobject.h \
+ $$PWD/q3dobject_p.h \
+ $$PWD/q3dscene_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 \
@@ -39,6 +42,12 @@ SOURCES += $$PWD/q3dwindow.cpp \
$$PWD/scatter3dcontroller.cpp \
$$PWD/scatter3drenderer.cpp \
$$PWD/axisrendercache.cpp \
- $$PWD/abstract3drenderer.cpp
+ $$PWD/abstract3drenderer.cpp \
+ $$PWD/selectionpointer.cpp \
+ $$PWD/q3dcamera.cpp \
+ $$PWD/q3dlight.cpp \
+ $$PWD/q3dbox.cpp \
+ $$PWD/q3dobject.cpp \
+ $$PWD/q3dscene.cpp
RESOURCES += engine/engine.qrc
diff --git a/src/datavis3d/engine/engine.qrc b/src/datavisualization/engine/engine.qrc
index af6e899d..7420ae51 100644
--- a/src/datavis3d/engine/engine.qrc
+++ b/src/datavisualization/engine/engine.qrc
@@ -56,6 +56,7 @@
<file alias="vertexSurfaceGrid">shaders/surfaceGrid.vert</file>
<file alias="vertexSurfaceFlat">shaders/surfaceFlat.vert</file>
<file alias="fragmentSurfaceFlat">shaders/surfaceFlat.frag</file>
+ <file alias="fragmentSurfaceES2">shaders/surface_ES2.frag</file>
</qresource>
<qresource prefix="/textures"/>
</RCC>
diff --git a/src/datavis3d/engine/meshes/backgroudFlat.obj b/src/datavisualization/engine/meshes/backgroudFlat.obj
index cf4d10a5..cf4d10a5 100644
--- a/src/datavis3d/engine/meshes/backgroudFlat.obj
+++ b/src/datavisualization/engine/meshes/backgroudFlat.obj
diff --git a/src/datavis3d/engine/meshes/backgroudNegatives.obj b/src/datavisualization/engine/meshes/backgroudNegatives.obj
index dd4d3f05..dd4d3f05 100644
--- a/src/datavis3d/engine/meshes/backgroudNegatives.obj
+++ b/src/datavisualization/engine/meshes/backgroudNegatives.obj
diff --git a/src/datavis3d/engine/meshes/backgroudSmooth.obj b/src/datavisualization/engine/meshes/backgroudSmooth.obj
index ad16d904..ad16d904 100644
--- a/src/datavis3d/engine/meshes/backgroudSmooth.obj
+++ b/src/datavisualization/engine/meshes/backgroudSmooth.obj
diff --git a/src/datavis3d/engine/meshes/barFilledFlat.obj b/src/datavisualization/engine/meshes/barFilledFlat.obj
index 5f627091..5f627091 100644
--- a/src/datavis3d/engine/meshes/barFilledFlat.obj
+++ b/src/datavisualization/engine/meshes/barFilledFlat.obj
diff --git a/src/datavis3d/engine/meshes/barFilledSmooth.obj b/src/datavisualization/engine/meshes/barFilledSmooth.obj
index efc4317a..efc4317a 100644
--- a/src/datavis3d/engine/meshes/barFilledSmooth.obj
+++ b/src/datavisualization/engine/meshes/barFilledSmooth.obj
diff --git a/src/datavis3d/engine/meshes/barFlat.obj b/src/datavisualization/engine/meshes/barFlat.obj
index b802feab..b802feab 100644
--- a/src/datavis3d/engine/meshes/barFlat.obj
+++ b/src/datavisualization/engine/meshes/barFlat.obj
diff --git a/src/datavis3d/engine/meshes/barSmooth.obj b/src/datavisualization/engine/meshes/barSmooth.obj
index aa4fdd92..aa4fdd92 100644
--- a/src/datavis3d/engine/meshes/barSmooth.obj
+++ b/src/datavisualization/engine/meshes/barSmooth.obj
diff --git a/src/datavis3d/engine/meshes/coneFilledFlat.obj b/src/datavisualization/engine/meshes/coneFilledFlat.obj
index cbbffaff..cbbffaff 100644
--- a/src/datavis3d/engine/meshes/coneFilledFlat.obj
+++ b/src/datavisualization/engine/meshes/coneFilledFlat.obj
diff --git a/src/datavis3d/engine/meshes/coneFilledSmooth.obj b/src/datavisualization/engine/meshes/coneFilledSmooth.obj
index ea3a8702..ea3a8702 100644
--- a/src/datavis3d/engine/meshes/coneFilledSmooth.obj
+++ b/src/datavisualization/engine/meshes/coneFilledSmooth.obj
diff --git a/src/datavis3d/engine/meshes/coneFlat.obj b/src/datavisualization/engine/meshes/coneFlat.obj
index 51c3821e..51c3821e 100644
--- a/src/datavis3d/engine/meshes/coneFlat.obj
+++ b/src/datavisualization/engine/meshes/coneFlat.obj
diff --git a/src/datavis3d/engine/meshes/coneSmooth.obj b/src/datavisualization/engine/meshes/coneSmooth.obj
index 48c48ba8..48c48ba8 100644
--- a/src/datavis3d/engine/meshes/coneSmooth.obj
+++ b/src/datavisualization/engine/meshes/coneSmooth.obj
diff --git a/src/datavis3d/engine/meshes/cubeFilledFlat.obj b/src/datavisualization/engine/meshes/cubeFilledFlat.obj
index 108cf7ac..108cf7ac 100644
--- a/src/datavis3d/engine/meshes/cubeFilledFlat.obj
+++ b/src/datavisualization/engine/meshes/cubeFilledFlat.obj
diff --git a/src/datavis3d/engine/meshes/cubeFilledSmooth.obj b/src/datavisualization/engine/meshes/cubeFilledSmooth.obj
index 07350f03..07350f03 100644
--- a/src/datavis3d/engine/meshes/cubeFilledSmooth.obj
+++ b/src/datavisualization/engine/meshes/cubeFilledSmooth.obj
diff --git a/src/datavis3d/engine/meshes/cubeFlat.obj b/src/datavisualization/engine/meshes/cubeFlat.obj
index 3c8d6d0a..3c8d6d0a 100644
--- a/src/datavis3d/engine/meshes/cubeFlat.obj
+++ b/src/datavisualization/engine/meshes/cubeFlat.obj
diff --git a/src/datavis3d/engine/meshes/cubeSmooth.obj b/src/datavisualization/engine/meshes/cubeSmooth.obj
index 9d147bfd..9d147bfd 100644
--- a/src/datavis3d/engine/meshes/cubeSmooth.obj
+++ b/src/datavisualization/engine/meshes/cubeSmooth.obj
diff --git a/src/datavis3d/engine/meshes/cylinderFilledFlat.obj b/src/datavisualization/engine/meshes/cylinderFilledFlat.obj
index 16c2ef36..16c2ef36 100644
--- a/src/datavis3d/engine/meshes/cylinderFilledFlat.obj
+++ b/src/datavisualization/engine/meshes/cylinderFilledFlat.obj
diff --git a/src/datavis3d/engine/meshes/cylinderFilledSmooth.obj b/src/datavisualization/engine/meshes/cylinderFilledSmooth.obj
index 90db7d63..90db7d63 100644
--- a/src/datavis3d/engine/meshes/cylinderFilledSmooth.obj
+++ b/src/datavisualization/engine/meshes/cylinderFilledSmooth.obj
diff --git a/src/datavis3d/engine/meshes/cylinderFlat.obj b/src/datavisualization/engine/meshes/cylinderFlat.obj
index 2b7e3e5e..2b7e3e5e 100644
--- a/src/datavis3d/engine/meshes/cylinderFlat.obj
+++ b/src/datavisualization/engine/meshes/cylinderFlat.obj
diff --git a/src/datavis3d/engine/meshes/cylinderSmooth.obj b/src/datavisualization/engine/meshes/cylinderSmooth.obj
index 6ccbb286..6ccbb286 100644
--- a/src/datavis3d/engine/meshes/cylinderSmooth.obj
+++ b/src/datavisualization/engine/meshes/cylinderSmooth.obj
diff --git a/src/datavis3d/engine/meshes/plane.obj b/src/datavisualization/engine/meshes/plane.obj
index 96ac0dd7..96ac0dd7 100644
--- a/src/datavis3d/engine/meshes/plane.obj
+++ b/src/datavisualization/engine/meshes/plane.obj
diff --git a/src/datavis3d/engine/meshes/pyramidFilledFlat.obj b/src/datavisualization/engine/meshes/pyramidFilledFlat.obj
index 0cf73bbe..0cf73bbe 100644
--- a/src/datavis3d/engine/meshes/pyramidFilledFlat.obj
+++ b/src/datavisualization/engine/meshes/pyramidFilledFlat.obj
diff --git a/src/datavis3d/engine/meshes/pyramidFilledSmooth.obj b/src/datavisualization/engine/meshes/pyramidFilledSmooth.obj
index 306bda58..306bda58 100644
--- a/src/datavis3d/engine/meshes/pyramidFilledSmooth.obj
+++ b/src/datavisualization/engine/meshes/pyramidFilledSmooth.obj
diff --git a/src/datavis3d/engine/meshes/pyramidFlat.obj b/src/datavisualization/engine/meshes/pyramidFlat.obj
index 35edb477..35edb477 100644
--- a/src/datavis3d/engine/meshes/pyramidFlat.obj
+++ b/src/datavisualization/engine/meshes/pyramidFlat.obj
diff --git a/src/datavis3d/engine/meshes/pyramidSmooth.obj b/src/datavisualization/engine/meshes/pyramidSmooth.obj
index b11c8750..b11c8750 100644
--- a/src/datavis3d/engine/meshes/pyramidSmooth.obj
+++ b/src/datavisualization/engine/meshes/pyramidSmooth.obj
diff --git a/src/datavis3d/engine/meshes/scatterdot.obj b/src/datavisualization/engine/meshes/scatterdot.obj
index d994a80f..d994a80f 100644
--- a/src/datavis3d/engine/meshes/scatterdot.obj
+++ b/src/datavisualization/engine/meshes/scatterdot.obj
diff --git a/src/datavis3d/engine/meshes/scatterdotFlat.obj b/src/datavisualization/engine/meshes/scatterdotFlat.obj
index 4052738d..4052738d 100644
--- a/src/datavis3d/engine/meshes/scatterdotFlat.obj
+++ b/src/datavisualization/engine/meshes/scatterdotFlat.obj
diff --git a/src/datavis3d/engine/meshes/sphere.obj b/src/datavisualization/engine/meshes/sphere.obj
index 671a7bcc..671a7bcc 100644
--- a/src/datavis3d/engine/meshes/sphere.obj
+++ b/src/datavisualization/engine/meshes/sphere.obj
diff --git a/src/datavis3d/engine/meshes/sphereSmooth.obj b/src/datavisualization/engine/meshes/sphereSmooth.obj
index 3c5b1299..3c5b1299 100644
--- a/src/datavis3d/engine/meshes/sphereSmooth.obj
+++ b/src/datavisualization/engine/meshes/sphereSmooth.obj
diff --git a/src/datavisualization/engine/q3dbars.cpp b/src/datavisualization/engine/q3dbars.cpp
new file mode 100644
index 00000000..0a543d54
--- /dev/null
+++ b/src/datavisualization/engine/q3dbars.cpp
@@ -0,0 +1,620 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 "q3dbars.h"
+#include "q3dbars_p.h"
+#include "bars3dcontroller_p.h"
+#include "q3dvalueaxis.h"
+#include "q3dcategoryaxis.h"
+#include "qbardataproxy.h"
+#include "q3dcamera.h"
+
+#include <QMouseEvent>
+
+#include <QDebug>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+/*!
+ * \class Q3DBars
+ * \inmodule QtDataVisualization
+ * \brief The Q3DBars class provides methods for rendering 3D bar 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.
+ *
+ * If no axes are explicitly set to Q3DBars, temporary default axes with no labels are created.
+ * These default axes can be modified via axis accessors, but as soon any axis is explicitly
+ * set for the orientation, the default axis for that orientation is destroyed.
+ *
+ * Data proxies work similarly: If no data proxy is explicitly set, Q3DBars creates a default
+ * proxy. If any other proxy is set as active data proxy later, the default proxy and all data
+ * added to it is destroyed.
+ *
+ * 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 Q3DBars graph
+ *
+ * First, construct an instance of Q3DBars:
+ *
+ * \snippet doc_src_q3dbars_construction.cpp 4
+ *
+ * After constructing Q3DBars, you can set the data window by changing the range on the row and
+ * column axes. It is not mandatory, as data window will default to showing all of the data in
+ * the data proxy. If the amount of data is large, it is usually preferable to show just a
+ * portion of it. For the example, let's set the data window to show first five rows and columns:
+ *
+ * \snippet doc_src_q3dbars_construction.cpp 0
+ *
+ * Now Q3DBars is ready to receive data to be rendered. Add one row of 5 qreals into the data
+ * set:
+ *
+ * \snippet doc_src_q3dbars_construction.cpp 1
+ *
+ * \note We set the data window 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_q3dbars_construction.cpp 2
+ *
+ * The complete code needed to create and display this graph is:
+ *
+ * \snippet doc_src_q3dbars_construction.cpp 3
+ *
+ * And this is what those few lines of code produce:
+ *
+ * \image q3dbars-minimal.png
+ *
+ * The scene can be rotated, zoomed into, and a bar can be selected to view it's value,
+ * 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{Bars Example} or
+ * the \l{Custom Proxy Example}.
+ *
+ * \sa Q3DScatter, Q3DSurface, {Qt Data Visualization C++ Classes}
+ */
+
+/*!
+ * Constructs a new 3D bar window.
+ */
+Q3DBars::Q3DBars()
+ : d_ptr(new Q3DBarsPrivate(this, geometry()))
+{
+ setVisualController(d_ptr->m_shared);
+ d_ptr->m_shared->initializeOpenGL();
+ QObject::connect(d_ptr->m_shared, &Bars3DController::selectedBarPosChanged, this,
+ &Q3DBars::selectedBarPosChanged);
+ QObject::connect(d_ptr->m_shared, &Abstract3DController::needRender, this,
+ &Q3DWindow::renderLater);
+}
+
+/*!
+ * Destroys the 3D bar window.
+ */
+Q3DBars::~Q3DBars()
+{
+}
+
+/*!
+ * \internal
+ */
+void Q3DBars::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ d_ptr->m_shared->mouseDoubleClickEvent(event);
+}
+
+/*!
+ * \internal
+ */
+void Q3DBars::touchEvent(QTouchEvent *event)
+{
+ d_ptr->m_shared->touchEvent(event);
+}
+
+/*!
+ * \internal
+ */
+void Q3DBars::mousePressEvent(QMouseEvent *event)
+{
+ d_ptr->m_shared->mousePressEvent(event, event->pos());
+}
+
+/*!
+ * \internal
+ */
+void Q3DBars::mouseReleaseEvent(QMouseEvent *event)
+{
+ d_ptr->m_shared->mouseReleaseEvent(event, event->pos());
+}
+
+/*!
+ * \internal
+ */
+void Q3DBars::mouseMoveEvent(QMouseEvent *event)
+{
+ d_ptr->m_shared->mouseMoveEvent(event, event->pos());
+}
+
+/*!
+ * \internal
+ */
+void Q3DBars::wheelEvent(QWheelEvent *event)
+{
+ d_ptr->m_shared->wheelEvent(event);
+}
+
+/*!
+ * \internal
+ */
+void Q3DBars::resizeEvent(QResizeEvent *event)
+{
+ Q_UNUSED(event);
+ d_ptr->m_shared->setSize(width(), height());
+}
+
+/*!
+ * Sets window \a width.
+ */
+void Q3DBars::setWidth(const int width)
+{
+ d_ptr->m_shared->setWidth(width);
+ QWindow::setWidth(width);
+}
+
+/*!
+ * Sets window \a height.
+ */
+void Q3DBars::setHeight(const int height)
+{
+ d_ptr->m_shared->setHeight(height);
+ QWindow::setHeight(height);
+}
+
+/*!
+ * \property Q3DBars::barThickness
+ *
+ * Bar thickness ratio between X and Z dimensions. 1.0 means bars are as wide as they are deep, 0.5
+ * makes them twice as deep as they are wide. It is preset to \c 1.0 by default.
+ */
+void Q3DBars::setBarThickness(qreal thicknessRatio)
+{
+ d_ptr->m_shared->setBarSpecs(GLfloat(thicknessRatio), barSpacing(), isBarSpacingRelative());
+}
+
+qreal Q3DBars::barThickness()
+{
+ return d_ptr->m_shared->barThickness();
+}
+
+/*!
+ * \property Q3DBars::barSpacing
+ *
+ * Bar spacing, ie. the empty space between bars, in X and Z dimensions. It is preset to
+ * \c {(1.0, 1.0)} by default. Spacing is affected by barSpacingRelative -property.
+ *
+ * \sa barSpacingRelative
+ */
+void Q3DBars::setBarSpacing(QSizeF spacing)
+{
+ d_ptr->m_shared->setBarSpecs(GLfloat(barThickness()), spacing, isBarSpacingRelative());
+}
+
+QSizeF Q3DBars::barSpacing()
+{
+ return d_ptr->m_shared->barSpacing();
+}
+
+/*!
+ * \property Q3DBars::barSpacingRelative
+ *
+ * This is used to indicate if spacing is meant to be absolute or relative to bar thickness.
+ * If it is true, value of 0.0 means the bars are side-to-side and for example 1.0 means
+ * there is one thickness in between the bars. It is preset to \c true.
+ */
+void Q3DBars::setBarSpacingRelative(bool relative)
+{
+ d_ptr->m_shared->setBarSpecs(GLfloat(barThickness()), barSpacing(), relative);
+}
+
+bool Q3DBars::isBarSpacingRelative()
+{
+ return d_ptr->m_shared->isBarSpecRelative();
+}
+
+/*!
+ * Sets the bar \a style to one of the values in \c QDataVis::MeshStyle. It is preset to
+ * \c QDataVis::MeshStyleBars by default. A \a smooth flag can be used to set shading to smooth.
+ * It is \c false by default.
+ *
+ * \sa setMeshFileName()
+ */
+void Q3DBars::setBarType(QDataVis::MeshStyle style, bool smooth)
+{
+ d_ptr->m_shared->setBarType(style, smooth);
+}
+
+/*!
+ * Sets a predefined \a theme from \c QDataVis::Theme. It is preset to \c QDataVis::ThemeQt by
+ * default. Theme affects bar colors, label colors, text color, background color, window color and
+ * grid color. Lighting is also adjusted by themes.
+ *
+ * \sa setBarColor()
+ *
+ * \warning This method is subject to change.
+ */
+void Q3DBars::setTheme(QDataVis::Theme theme)
+{
+ d_ptr->m_shared->setTheme(theme);
+}
+
+/*!
+ * Set bar color using your own color. \a baseColor sets the base color of a bar. The \a uniform
+ * -flag is used to define if color needs to be uniform throughout bar's length, or will the colors
+ * be applied by height, starting with dark at the bottom. It is \c true by default.
+ *
+ * Calling this method overrides colors from theme.
+ *
+ * \sa setTheme()
+ *
+ * \warning This method is subject to change.
+ */
+void Q3DBars::setBarColor(const QColor &baseColor, bool uniform)
+{
+ d_ptr->m_shared->setObjectColor(baseColor, uniform);
+}
+
+/*!
+ * \return bar color in use.
+ */
+QColor Q3DBars::barColor() const
+{
+ return d_ptr->m_shared->objectColor();
+}
+
+/*!
+ * \property Q3DBars::selectionMode
+ *
+ * Sets bar selection \a mode to one of \c QDataVis::SelectionMode. It is preset to
+ * \c QDataVis::SelectionModeItem by default.
+ */
+void Q3DBars::setSelectionMode(QDataVis::SelectionMode mode)
+{
+ d_ptr->m_shared->setSelectionMode(mode);
+}
+
+QDataVis::SelectionMode Q3DBars::selectionMode() const
+{
+ return d_ptr->m_shared->selectionMode();
+}
+
+/*!
+ * \property Q3DBars::meshFileName
+ *
+ * Override bar type with a mesh object located in \a objFileName.
+ * \note Object needs to be in Wavefront obj format and include vertices, normals and UVs.
+ * It also needs to be in triangles.
+ *
+ * \sa setBarType()
+ */
+void Q3DBars::setMeshFileName(const QString &objFileName)
+{
+ d_ptr->m_shared->setMeshFileName(objFileName);
+}
+
+QString Q3DBars::meshFileName() const
+{
+ return d_ptr->m_shared->meshFileName();
+}
+
+/*!
+ * \property Q3DBars::font
+ *
+ * Sets the \a font for labels. It is preset to \c Arial by default.
+ */
+void Q3DBars::setFont(const QFont &font)
+{
+ d_ptr->m_shared->setFont(font);
+}
+
+QFont Q3DBars::font() const
+{
+ return d_ptr->m_shared->font();
+}
+
+/*!
+ * \property Q3DBars::scene
+ *
+ * This property contains the read only Q3DScene that can be used to access e.g. camera object.
+ */
+Q3DScene *Q3DBars::scene() const
+{
+ return d_ptr->m_shared->scene();
+}
+
+/*!
+ * \property Q3DBars::labelStyle
+ *
+ * Sets label \a style to one of \c QDataVis::LabelStyle. It is preset to
+ * \c QDataVis::LabelStyleFromTheme by default.
+ */
+void Q3DBars::setLabelStyle(QDataVis::LabelStyle style)
+{
+ d_ptr->m_shared->setLabelStyle(style);
+}
+
+QDataVis::LabelStyle Q3DBars::labelStyle() const
+{
+ return d_ptr->m_shared->labelStyle();
+}
+
+/*!
+ * \property Q3DBars::gridVisible
+ *
+ * Sets grid visibility to \a visible. It is preset to \c true by default.
+ */
+void Q3DBars::setGridVisible(bool visible)
+{
+ d_ptr->m_shared->setGridEnabled(visible);
+}
+
+bool Q3DBars::isGridVisible() const
+{
+ return d_ptr->m_shared->gridEnabled();
+}
+
+/*!
+ * \property Q3DBars::backgroundVisible
+ *
+ * Sets background visibility to \a visible. It is preset to \c true by default.
+ */
+void Q3DBars::setBackgroundVisible(bool visible)
+{
+ d_ptr->m_shared->setBackgroundEnabled(visible);
+}
+
+bool Q3DBars::isBackgroundVisible() const
+{
+ return d_ptr->m_shared->backgroundEnabled();
+}
+
+/*!
+ * \property Q3DBars::selectedBarPos
+ *
+ * Selects a bar in a \a position. The position is the position in data window.
+ * Only one bar can be selected at a time.
+ * To clear selection, specify an illegal \a position, e.g. (-1, -1).
+ */
+void Q3DBars::setSelectedBarPos(const QPoint &position)
+{
+ d_ptr->m_shared->setSelectedBarPos(position);
+}
+
+QPoint Q3DBars::selectedBarPos() const
+{
+ return d_ptr->m_shared->selectedBarPos();
+}
+
+/*!
+ * \property Q3DBars::shadowQuality
+ *
+ * Sets shadow \a quality to one of \c QDataVis::ShadowQuality. It is preset to
+ * \c QDataVis::ShadowQualityMedium by default.
+ *
+ * \note 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(QDataVis::ShadowQuality quality)
+{
+ d_ptr->m_shared->setShadowQuality(quality);
+}
+
+QDataVis::ShadowQuality Q3DBars::shadowQuality() const
+{
+ return d_ptr->m_shared->shadowQuality();
+}
+
+/*!
+ * Sets a user-defined row \a axis. Implicitly calls addAxis() to transfer ownership of
+ * the \a axis to this graph.
+ *
+ * If the \a axis is null, a temporary default axis with no labels is created.
+ * This temporary axis is destroyed if another \a axis is explicitly set to same orientation.
+ *
+ * \sa addAxis(), releaseAxis()
+ */
+void Q3DBars::setRowAxis(Q3DCategoryAxis *axis)
+{
+ d_ptr->m_shared->setAxisX(axis);
+}
+
+/*!
+ * \return category axis for rows.
+ */
+Q3DCategoryAxis *Q3DBars::rowAxis() const
+{
+ return static_cast<Q3DCategoryAxis *>(d_ptr->m_shared->axisX());
+}
+
+/*!
+ * Sets a user-defined column \a axis. Implicitly calls addAxis() to transfer ownership of
+ * the \a axis to this graph.
+ *
+ * If the \a axis is null, a temporary default axis with no labels is created.
+ * This temporary axis is destroyed if another \a axis is explicitly set to same orientation.
+ *
+ * \sa addAxis(), releaseAxis()
+ */
+void Q3DBars::setColumnAxis(Q3DCategoryAxis *axis)
+{
+ d_ptr->m_shared->setAxisZ(axis);
+}
+
+/*!
+ * \return category axis for columns.
+ */
+Q3DCategoryAxis *Q3DBars::columnAxis() const
+{
+ return static_cast<Q3DCategoryAxis *>(d_ptr->m_shared->axisZ());
+}
+
+/*!
+ * Sets a user-defined value \a axis (the Y-axis). Implicitly calls addAxis() to transfer ownership
+ * of the \a axis to this graph.
+ *
+ * If the \a axis is null, a temporary default axis with no labels and automatically adjusting
+ * range is created.
+ * This temporary axis is destroyed if another \a axis is explicitly set to same orientation.
+ *
+ * \sa addAxis(), releaseAxis()
+ */
+void Q3DBars::setValueAxis(Q3DValueAxis *axis)
+{
+ d_ptr->m_shared->setAxisY(axis);
+}
+
+/*!
+ * \return used value axis (Y-axis).
+ */
+Q3DValueAxis *Q3DBars::valueAxis() const
+{
+ return static_cast<Q3DValueAxis *>(d_ptr->m_shared->axisY());
+}
+
+/*!
+ * Adds \a axis to the graph. The axes added via addAxis are not yet taken to use,
+ * addAxis is simply used to give the ownership of the \a axis to the graph.
+ * The \a axis must not be null or added to another graph.
+ *
+ * \sa releaseAxis(), setValueAxis(), setRowAxis(), setColumnAxis()
+ */
+void Q3DBars::addAxis(Q3DAbstractAxis *axis)
+{
+ d_ptr->m_shared->addAxis(axis);
+}
+
+/*!
+ * Releases the ownership of the \a axis back to the caller, if it is added to this graph.
+ * If the released \a axis is in use, a new default axis will be created and set active.
+ *
+ * If the default axis is released and added back later, it behaves as any other axis would.
+ *
+ * \sa addAxis(), setValueAxis(), setRowAxis(), setColumnAxis()
+ */
+void Q3DBars::releaseAxis(Q3DAbstractAxis *axis)
+{
+ d_ptr->m_shared->releaseAxis(axis);
+}
+
+/*!
+ * \return list of all added axes.
+ *
+ * \sa addAxis()
+ */
+QList<Q3DAbstractAxis *> Q3DBars::axes() const
+{
+ return d_ptr->m_shared->axes();
+}
+
+/*!
+ * Sets the active data \a proxy. Implicitly calls addDataProxy() to transfer ownership of
+ * the \a proxy to this graph.
+ *
+ * If the \a proxy is null, a temporary default proxy is created and activated.
+ * This temporary proxy is destroyed if another \a proxy is explicitly set active via this method.
+ *
+ * \sa addDataProxy(), releaseDataProxy()
+ */
+void Q3DBars::setActiveDataProxy(QBarDataProxy *proxy)
+{
+ d_ptr->m_shared->setActiveDataProxy(proxy);
+}
+
+/*!
+ * \return active data proxy.
+ */
+QBarDataProxy *Q3DBars::activeDataProxy() const
+{
+ return static_cast<QBarDataProxy *>(d_ptr->m_shared->activeDataProxy());
+}
+
+/*!
+ * Adds data \a proxy to the graph. The proxies added via addDataProxy are not yet taken to use,
+ * addDataProxy is simply used to give the ownership of the data \a proxy to the graph.
+ * The \a proxy must not be null or added to another graph.
+ *
+ * \sa releaseDataProxy(), setActiveDataProxy()
+ */
+void Q3DBars::addDataProxy(QBarDataProxy *proxy)
+{
+ d_ptr->m_shared->addDataProxy(proxy);
+}
+
+/*!
+ * Releases the ownership of the data \a proxy back to the caller, if it is added to this graph.
+ * If the released \a proxy is in use, a new empty default proxy is created and taken to use.
+ *
+ * If the default \a proxy is released and added back later, it behaves as any other proxy would.
+ *
+ * \sa addDataProxy(), setActiveDataProxy()
+ */
+void Q3DBars::releaseDataProxy(QBarDataProxy *proxy)
+{
+ d_ptr->m_shared->releaseDataProxy(proxy);
+}
+
+/*!
+ * \return list of all added data proxies.
+ *
+ * \sa addDataProxy()
+ */
+QList<QBarDataProxy *> Q3DBars::dataProxies() const
+{
+ QList<QBarDataProxy *> retList;
+ QList<QAbstractDataProxy *> abstractList = d_ptr->m_shared->dataProxies();
+ foreach (QAbstractDataProxy *proxy, abstractList)
+ retList.append(static_cast<QBarDataProxy *>(proxy));
+
+ return retList;
+}
+
+Q3DBarsPrivate::Q3DBarsPrivate(Q3DBars *q, QRect rect)
+ : q_ptr(q),
+ m_shared(new Bars3DController(rect))
+{
+ QObject::connect(m_shared, &Abstract3DController::shadowQualityChanged, this,
+ &Q3DBarsPrivate::handleShadowQualityUpdate);
+}
+
+Q3DBarsPrivate::~Q3DBarsPrivate()
+{
+ qDebug() << "Destroying Q3DBarsPrivate";
+ delete m_shared;
+}
+
+void Q3DBarsPrivate::handleShadowQualityUpdate(QDataVis::ShadowQuality quality)
+{
+ emit q_ptr->shadowQualityChanged(quality);
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualization/engine/q3dbars.h b/src/datavisualization/engine/q3dbars.h
new file mode 100644
index 00000000..d0ddf3fb
--- /dev/null
+++ b/src/datavisualization/engine/q3dbars.h
@@ -0,0 +1,142 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 Q3DBARS_H
+#define Q3DBARS_H
+
+#include <QtDataVisualization/qdatavisualizationenums.h>
+#include <QtDataVisualization/q3dwindow.h>
+#include <QFont>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class Q3DBarsPrivate;
+class Q3DAbstractAxis;
+class Q3DCategoryAxis;
+class Q3DValueAxis;
+class QBarDataProxy;
+class Q3DScene;
+
+class QT_DATAVISUALIZATION_EXPORT Q3DBars : public Q3DWindow
+{
+ Q_OBJECT
+ Q_PROPERTY(QtDataVisualization::QDataVis::SelectionMode selectionMode READ selectionMode WRITE setSelectionMode)
+ Q_PROPERTY(QtDataVisualization::QDataVis::LabelStyle labelStyle READ labelStyle WRITE setLabelStyle)
+ Q_PROPERTY(QtDataVisualization::QDataVis::ShadowQuality shadowQuality READ shadowQuality WRITE setShadowQuality NOTIFY shadowQualityChanged)
+ Q_PROPERTY(qreal barThickness READ barThickness WRITE setBarThickness)
+ Q_PROPERTY(QSizeF barSpacing READ barSpacing WRITE setBarSpacing)
+ Q_PROPERTY(bool barSpacingRelative READ isBarSpacingRelative WRITE setBarSpacingRelative)
+ Q_PROPERTY(QString meshFileName READ meshFileName WRITE setMeshFileName)
+ Q_PROPERTY(QFont font READ font WRITE setFont)
+ Q_PROPERTY(bool gridVisible READ isGridVisible WRITE setGridVisible)
+ Q_PROPERTY(bool backgroundVisible READ isBackgroundVisible WRITE setBackgroundVisible)
+ Q_PROPERTY(QPoint selectedBarPos READ selectedBarPos WRITE setSelectedBarPos NOTIFY selectedBarPosChanged)
+ Q_PROPERTY(Q3DScene* scene READ scene)
+
+ Q_ENUMS(QtDataVisualization::QDataVis::SelectionMode)
+ Q_ENUMS(QtDataVisualization::QDataVis::ShadowQuality)
+ Q_ENUMS(QtDataVisualization::QDataVis::LabelStyle)
+ Q_ENUMS(QtDataVisualization::QDataVis::CameraPreset)
+
+public:
+ explicit Q3DBars();
+ ~Q3DBars();
+
+ void setBarType(QDataVis::MeshStyle style, bool smooth = false);
+
+ void setTheme(QDataVis::Theme theme);
+
+ void setBarThickness(qreal thicknessRatio);
+ qreal barThickness();
+
+ void setBarSpacing(QSizeF spacing);
+ QSizeF barSpacing();
+
+ void setBarSpacingRelative(bool relative);
+ bool isBarSpacingRelative();
+
+ void setBarColor(const QColor &baseColor, bool uniform = true);
+ QColor barColor() const;
+
+ void setMeshFileName(const QString &objFileName);
+ QString meshFileName() const;
+
+ void setSelectionMode(QDataVis::SelectionMode mode);
+ QDataVis::SelectionMode selectionMode() const;
+
+ void setFont(const QFont &font);
+ QFont font() const;
+
+ Q3DScene *scene() const;
+
+ void setLabelStyle(QDataVis::LabelStyle style);
+ QDataVis::LabelStyle labelStyle() const;
+
+ void setGridVisible(bool visible);
+ bool isGridVisible() const;
+
+ void setWidth(const int width);
+ void setHeight(const int height);
+
+ void setBackgroundVisible(bool visible);
+ bool isBackgroundVisible() const;
+
+ void setSelectedBarPos(const QPoint &position);
+ QPoint selectedBarPos() const;
+
+ void setShadowQuality(QDataVis::ShadowQuality quality);
+ QDataVis::ShadowQuality shadowQuality() const;
+
+ void setRowAxis(Q3DCategoryAxis *axis);
+ Q3DCategoryAxis *rowAxis() const;
+ void setColumnAxis(Q3DCategoryAxis *axis);
+ Q3DCategoryAxis *columnAxis() const;
+ void setValueAxis(Q3DValueAxis *axis);
+ Q3DValueAxis *valueAxis() const;
+ void addAxis(Q3DAbstractAxis *axis);
+ void releaseAxis(Q3DAbstractAxis *axis);
+ QList<Q3DAbstractAxis *> axes() const;
+
+ void setActiveDataProxy(QBarDataProxy *proxy);
+ QBarDataProxy *activeDataProxy() const;
+ void addDataProxy(QBarDataProxy *proxy);
+ void releaseDataProxy(QBarDataProxy *proxy);
+ QList<QBarDataProxy *> dataProxies() const;
+
+signals:
+ void shadowQualityChanged(QDataVis::ShadowQuality quality);
+ void selectedBarPosChanged(QPoint position);
+
+protected:
+
+ void mouseDoubleClickEvent(QMouseEvent *event);
+ void touchEvent(QTouchEvent *event);
+ void mousePressEvent(QMouseEvent *event);
+ void mouseReleaseEvent(QMouseEvent *event);
+ void mouseMoveEvent(QMouseEvent *event);
+ void wheelEvent(QWheelEvent *event);
+ void resizeEvent(QResizeEvent *event);
+
+private:
+ QScopedPointer<Q3DBarsPrivate> d_ptr;
+ Q_DISABLE_COPY(Q3DBars)
+};
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/engine/q3dbars_p.h b/src/datavisualization/engine/q3dbars_p.h
index 9eed8162..653db606 100644
--- a/src/datavis3d/engine/q3dbars_p.h
+++ b/src/datavisualization/engine/q3dbars_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -30,9 +30,9 @@
#define Q3DBARS_p_H
#include "bars3dcontroller_p.h"
-#include "qdatavis3denums.h"
+#include "qdatavisualizationenums.h"
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
class Q3DBars;
@@ -42,10 +42,13 @@ public:
Q3DBarsPrivate(Q3DBars *q, QRect rect);
~Q3DBarsPrivate();
+ // Used to detect when shadow quality changes autonomously due to e.g. resizing.
+ void handleShadowQualityUpdate(QDataVis::ShadowQuality quality);
+
Q3DBars *q_ptr;
- Bars3dController *m_shared;
+ Bars3DController *m_shared;
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif
diff --git a/src/datavisualization/engine/q3dbox.cpp b/src/datavisualization/engine/q3dbox.cpp
new file mode 100644
index 00000000..43f3e90e
--- /dev/null
+++ b/src/datavisualization/engine/q3dbox.cpp
@@ -0,0 +1,481 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 "datavisualizationglobal_p.h"
+#include "q3dbox.h"
+#include <QtCore/QList>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+/*!
+ \class Q3DBox
+ \inmodule QtDataVisualization
+ \brief The Q3DBox class represents an axis-aligned box in 3D space.
+ \since 1.0.0
+
+ Q3DBox can be used to represent the bounding box of objects in a 3D
+ scene so that they can be easily culled if they are out of view.
+
+ The sides of the box are always aligned with the x, y, and z axes of
+ the world co-ordinate system. Transforming a box with transformed()
+ will result in the smallest axis-aligned bounding box that contains
+ the transformed box.
+
+ Boxes may be null, finite, or infinite. A null box does not occupy
+ any space and does not intersect with any other box. A finite
+ box consists of a minimum() and maximum() extent in 3D space.
+ An infinite box encompasses all points in 3D space.
+
+ The extents of a finite box are also included within the box.
+ A box with minimum() and maximum() set to the same value
+ contains a single point.
+*/
+
+/*!
+ \fn Q3DBox::Q3DBox()
+
+ Constructs a null box in 3D space.
+
+ \sa isNull()
+*/
+
+/*!
+ \fn Q3DBox::Q3DBox(const QVector3D& corner1, const QVector3D& corner2)
+
+ Constructs a finite box in 3D space from \a corner1 to \a corner2.
+ The minimum() and maximum() co-ordinates of the new box are set
+ to the minimum and maximum x, y, and z values from \a corner1 and
+ \a corner2. The \a corner1 and \a corner2 values can be any two
+ opposite corners that define the box.
+
+ \sa isFinite(), minimum(), maximum()
+*/
+
+/*!
+ \fn bool Q3DBox::isNull() const
+
+ Returns true if this box is null; false otherwise.
+
+ \sa isFinite(), isInfinite(), setToNull()
+*/
+
+/*!
+ \fn bool Q3DBox::isFinite() const
+
+ Returns true if this box is finite in size; false otherwise.
+
+ \sa isNull(), isInfinite(), setExtents()
+*/
+
+/*!
+ \fn bool Q3DBox::isInfinite() const
+
+ Returns true if this box is infinite in size; false otherwise.
+
+ \sa isNull(), isFinite(), setToInfinite()
+*/
+
+/*!
+ \fn QVector3D Q3DBox::minimum() const
+
+ Returns the minimum corner of this box.
+
+ \sa maximum(), setExtents()
+*/
+
+/*!
+ \fn QVector3D Q3DBox::maximum() const
+
+ Returns the maximum corner of this box.
+
+ \sa minimum(), setExtents()
+*/
+
+/*!
+ \fn void Q3DBox::setExtents(const QVector3D& corner1, const QVector3D& corner2)
+
+ Sets the extents of this box to a finite region from \a corner1 to
+ \a corner2. The minimum() and maximum() co-ordinates of the box are
+ set to the minimum and maximum x, y, and z values from \a corner1 and
+ \a corner2. The \a corner1 and \a corner2 values can be any two
+ opposite corners that define the box.
+
+ \sa minimum(), maximum()
+*/
+
+/*!
+ \fn void Q3DBox::setToNull()
+
+ Sets this box to null.
+
+ \sa isNull()
+*/
+
+/*!
+ \fn void Q3DBox::setToInfinite()
+
+ Sets this box to be infinite in size.
+
+ \sa isInfinite()
+*/
+
+/*!
+ \fn QVector3D Q3DBox::size() const
+
+ Returns the finite size of this box. If this box is null or
+ infinite, the returned value will be zero.
+
+ \sa center(), isNull(), isInfinite()
+*/
+
+/*!
+ \fn QVector3D Q3DBox::center() const
+
+ Returns the finite center of this box. If this box is null
+ or infinite, the returned value will be zero.
+
+ \sa size(), isNull(), isInfinite()
+*/
+
+/*!
+ \fn bool Q3DBox::contains(const QVector3D& point) const
+
+ Returns true if this box contains \a point; false otherwise.
+ Null boxes do not contain any points and infinite boxes contain
+ all points.
+
+ Containment is not a strict test: the point is contained if it
+ lies on one of the faces of the box.
+
+ \sa intersects()
+*/
+
+/*!
+ \fn bool Q3DBox::contains(const Q3DBox& box) const
+
+ Returns true if this box completely contains \a box. If this box
+ is null, then it will not contain \a box. If this box is infinite,
+ and \a box is not null, then \a box will be contained within this box.
+ If \a box is infinite, then this box must also be infinite to contain it.
+
+ \sa intersects()
+*/
+
+/*!
+ Returns true if \a box intersects this box; false otherwise.
+
+ \sa intersect(), intersected(), contains()
+*/
+bool Q3DBox::intersects(const Q3DBox& box) const
+{
+ if (boxtype == Null)
+ return false;
+ else if (boxtype == Infinite)
+ return box.boxtype != Null;
+ else if (box.boxtype == Null)
+ return false;
+ else if (box.boxtype == Infinite)
+ return true;
+
+ if (maxcorner.x() < box.mincorner.x())
+ return false;
+ if (mincorner.x() > box.maxcorner.x())
+ return false;
+
+ if (maxcorner.y() < box.mincorner.y())
+ return false;
+ if (mincorner.y() > box.maxcorner.y())
+ return false;
+
+ if (maxcorner.z() < box.mincorner.z())
+ return false;
+ if (mincorner.z() > box.maxcorner.z())
+ return false;
+
+ return true;
+}
+
+/*!
+ Intersects this box with \a box.
+
+ \sa intersected(), intersects(), unite()
+*/
+void Q3DBox::intersect(const Q3DBox& box)
+{
+ // Handle the simple cases first.
+ if (boxtype == Null) {
+ // Null intersected with anything is null.
+ return;
+ } else if (boxtype == Infinite) {
+ // Infinity intersected with a box is that box.
+ *this = box;
+ return;
+ } else if (box.boxtype == Null) {
+ // Anything intersected with null is null.
+ setToNull();
+ return;
+ } else if (box.boxtype == Infinite) {
+ // Box intersected with infinity is the box.
+ return;
+ }
+
+ // Intersect two finite boxes.
+ QVector3D min1 = mincorner;
+ QVector3D max1 = maxcorner;
+ QVector3D min2 = box.mincorner;
+ QVector3D max2 = box.maxcorner;
+ if (min2.x() > min1.x())
+ min1.setX(min2.x());
+ if (min2.y() > min1.y())
+ min1.setY(min2.y());
+ if (min2.z() > min1.z())
+ min1.setZ(min2.z());
+ if (max2.x() < max1.x())
+ max1.setX(max2.x());
+ if (max2.y() < max1.y())
+ max1.setY(max2.y());
+ if (max2.z() < max1.z())
+ max1.setZ(max2.z());
+ if (min1.x() > max1.x() || min1.y() > max1.y() || min1.z() > max1.z()) {
+ setToNull();
+ } else {
+ mincorner = min1;
+ maxcorner = max1;
+ }
+}
+
+/*!
+ Returns a new box which is the intersection of this box with \a box.
+
+ \sa intersect(), intersects(), united()
+*/
+Q3DBox Q3DBox::intersected(const Q3DBox& box) const
+{
+ Q3DBox result(*this);
+ result.intersect(box);
+ return result;
+}
+
+/*!
+ Unites this box with \a point by expanding it to encompass \a point.
+ If \a point is already contained within this box, then this box
+ will be unchanged.
+
+ \sa united(), intersect()
+*/
+void Q3DBox::unite(const QVector3D& point)
+{
+ if (boxtype == Finite) {
+ if (point.x() < mincorner.x())
+ mincorner.setX(point.x());
+ else if (point.x() > maxcorner.x())
+ maxcorner.setX(point.x());
+ if (point.y() < mincorner.y())
+ mincorner.setY(point.y());
+ else if (point.y() > maxcorner.y())
+ maxcorner.setY(point.y());
+ if (point.z() < mincorner.z())
+ mincorner.setZ(point.z());
+ else if (point.z() > maxcorner.z())
+ maxcorner.setZ(point.z());
+ } else if (boxtype == Null) {
+ boxtype = Finite;
+ mincorner = point;
+ maxcorner = point;
+ }
+}
+
+/*!
+ Unites this box with \a box by expanding this box to encompass the
+ region defined by \a box. If \a box is already contained within
+ this box, then this box will be unchanged.
+
+ \sa united(), intersect()
+*/
+void Q3DBox::unite(const Q3DBox& box)
+{
+ if (box.boxtype == Finite) {
+ unite(box.minimum());
+ unite(box.maximum());
+ } else if (box.boxtype == Infinite) {
+ setToInfinite();
+ }
+}
+
+/*!
+ Returns a new box which unites this box with \a point. The returned
+ value will be the smallest box that contains both this box and \a point.
+
+ \sa unite(), intersected()
+*/
+Q3DBox Q3DBox::united(const QVector3D& point) const
+{
+ if (boxtype == Finite) {
+ Q3DBox result(*this);
+ result.unite(point);
+ return result;
+ } else if (boxtype == Null) {
+ return Q3DBox(point, point);
+ } else {
+ return *this;
+ }
+}
+
+/*!
+ Returns a new box which unites this box with \a box. The returned value
+ will be the smallest box that contains both this box and \a box.
+
+ \sa unite(), intersected()
+*/
+Q3DBox Q3DBox::united(const Q3DBox& box) const
+{
+ if (boxtype == Finite) {
+ Q3DBox result(*this);
+ result.unite(box);
+ return result;
+ } else if (boxtype == Null) {
+ return box;
+ } else {
+ return *this;
+ }
+}
+
+/*!
+ Transforms this box according to \a matrix. Each of the 8 box
+ corners are transformed and then a new box that encompasses all
+ of the transformed corner values is created.
+
+ \sa transformed()
+*/
+void Q3DBox::transform(const QMatrix4x4& matrix)
+{
+ *this = transformed(matrix);
+}
+
+/*!
+ Returns this box transformed by \a matrix. Each of the 8 box
+ corners are transformed and then a new box that encompasses all
+ of the transformed corner values is returned.
+
+ \sa transform()
+*/
+Q3DBox Q3DBox::transformed(const QMatrix4x4& matrix) const
+{
+ if (boxtype != Finite)
+ return *this;
+ Q3DBox result;
+ result.unite(matrix * mincorner);
+ result.unite(matrix * QVector3D(mincorner.x(), mincorner.y(), maxcorner.z()));
+ result.unite(matrix * QVector3D(mincorner.x(), maxcorner.y(), maxcorner.z()));
+ result.unite(matrix * QVector3D(mincorner.x(), maxcorner.y(), mincorner.z()));
+ result.unite(matrix * QVector3D(maxcorner.x(), mincorner.y(), mincorner.z()));
+ result.unite(matrix * QVector3D(maxcorner.x(), maxcorner.y(), mincorner.z()));
+ result.unite(matrix * QVector3D(maxcorner.x(), mincorner.y(), maxcorner.z()));
+ result.unite(matrix * maxcorner);
+ return result;
+}
+
+/*!
+ \fn bool Q3DBox::operator==(const Q3DBox& box) const
+
+ Returns true if this box is identical to \a box.
+*/
+
+/*!
+ \fn bool Q3DBox::operator!=(const Q3DBox& box) const
+
+ Returns true if this box is not identical to \a box.
+*/
+
+/*!
+ \fn bool qFuzzyCompare(const Q3DBox& box1, const Q3DBox& box2)
+ \relates Q3DBox
+
+ Returns true if \a box1 and \a box2 are almost equal; false otherwise.
+*/
+
+#ifndef QT_NO_DEBUG_STREAM
+
+QDebug operator<<(QDebug dbg, const Q3DBox &box)
+{
+ if (box.isFinite()) {
+ dbg.nospace() << "Q3DBox(("
+ << box.minimum().x() << ", " << box.minimum().y() << ", "
+ << box.minimum().z() << ") - ("
+ << box.maximum().x() << ", " << box.maximum().y() << ", "
+ << box.maximum().z() << "))";
+ return dbg.space();
+ } else if (box.isNull()) {
+ dbg << "Q3DBox(null)";
+ return dbg;
+ } else {
+ dbg << "Q3DBox(infinite)";
+ return dbg;
+ }
+}
+
+#endif
+
+#ifndef QT_NO_DATASTREAM
+
+/*!
+ \relates Q3DBox
+
+ Writes the given \a box to the given \a stream and returns a
+ reference to the stream.
+*/
+QDataStream &operator<<(QDataStream &stream, const Q3DBox &box)
+{
+ if (box.isNull()) {
+ stream << int(0);
+ } else if (box.isInfinite()) {
+ stream << int(2);
+ } else {
+ stream << int(1);
+ stream << box.minimum();
+ stream << box.maximum();
+ }
+ return stream;
+}
+
+/*!
+ \relates Q3DBox
+
+ Reads a 3D box from the given \a stream into the given \a box
+ and returns a reference to the stream.
+*/
+QDataStream &operator>>(QDataStream &stream, Q3DBox &box)
+{
+ int type;
+ stream >> type;
+ if (type == 1) {
+ QVector3D minimum, maximum;
+ stream >> minimum;
+ stream >> maximum;
+ box = Q3DBox(minimum, maximum);
+ } else if (type == 2) {
+ box.setToInfinite();
+ } else {
+ box.setToNull();
+ }
+ return stream;
+}
+
+#endif // QT_NO_DATASTREAM
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualization/engine/q3dbox.h b/src/datavisualization/engine/q3dbox.h
new file mode 100644
index 00000000..aa63ec39
--- /dev/null
+++ b/src/datavisualization/engine/q3dbox.h
@@ -0,0 +1,184 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 Q3DBOX_H
+#define Q3DBOX_H
+
+#include <QtDataVisualization/qdatavisualizationenums.h>
+#include <QtGui/QMatrix4x4>
+#include <QtGui/QVector3D>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class Q3DBox; // Needed to circumvent an issue with qdoc. If this line is removed, make docs will not work for this.
+
+class QT_DATAVISUALIZATION_EXPORT Q3DBox
+{
+public:
+ Q3DBox();
+ Q3DBox(const QVector3D& corner1, const QVector3D& corner2);
+
+ bool isNull() const;
+ bool isFinite() const;
+ bool isInfinite() const;
+
+ QVector3D minimum() const;
+ QVector3D maximum() const;
+ void setExtents(const QVector3D& corner1, const QVector3D& corner2);
+
+ void setToNull();
+ void setToInfinite();
+
+ QVector3D size() const;
+ QVector3D center() const;
+
+ bool contains(const QVector3D& point) const;
+ bool contains(const Q3DBox& box) const;
+
+ bool intersects(const Q3DBox& box) const;
+ void intersect(const Q3DBox& box);
+ Q3DBox intersected(const Q3DBox& box) const;
+
+ void unite(const QVector3D& point);
+ void unite(const Q3DBox& box);
+
+ Q3DBox united(const QVector3D& point) const;
+ Q3DBox united(const Q3DBox& box) const;
+
+ void transform(const QMatrix4x4& matrix);
+ Q3DBox transformed(const QMatrix4x4& matrix) const;
+
+ bool operator==(const Q3DBox& box) const;
+ bool operator!=(const Q3DBox& box) const;
+
+ friend bool qFuzzyCompare(const Q3DBox& box1, const Q3DBox& box2);
+
+private:
+ enum Type
+ {
+ Null,
+ Finite,
+ Infinite
+ };
+
+ Q3DBox::Type boxtype;
+ QVector3D mincorner, maxcorner;
+};
+
+inline Q3DBox::Q3DBox() : boxtype(Null), mincorner(0, 0, 0), maxcorner(0, 0, 0) {}
+
+inline Q3DBox::Q3DBox(const QVector3D& corner1, const QVector3D& corner2)
+ : boxtype(Finite),
+ mincorner(qMin(corner1.x(), corner2.x()),
+ qMin(corner1.y(), corner2.y()),
+ qMin(corner1.z(), corner2.z())),
+ maxcorner(qMax(corner1.x(), corner2.x()),
+ qMax(corner1.y(), corner2.y()),
+ qMax(corner1.z(), corner2.z())) {}
+
+inline bool Q3DBox::isNull() const { return (boxtype == Null); }
+inline bool Q3DBox::isFinite() const { return (boxtype == Finite); }
+inline bool Q3DBox::isInfinite() const { return (boxtype == Infinite); }
+
+inline QVector3D Q3DBox::minimum() const { return mincorner; }
+inline QVector3D Q3DBox::maximum() const { return maxcorner; }
+
+inline void Q3DBox::setExtents(const QVector3D& corner1, const QVector3D& corner2)
+{
+ boxtype = Finite;
+ mincorner = QVector3D(qMin(corner1.x(), corner2.x()),
+ qMin(corner1.y(), corner2.y()),
+ qMin(corner1.z(), corner2.z()));
+ maxcorner = QVector3D(qMax(corner1.x(), corner2.x()),
+ qMax(corner1.y(), corner2.y()),
+ qMax(corner1.z(), corner2.z()));
+}
+
+inline void Q3DBox::setToNull()
+{
+ boxtype = Null;
+ mincorner = QVector3D(0, 0, 0);
+ maxcorner = QVector3D(0, 0, 0);
+}
+
+inline void Q3DBox::setToInfinite()
+{
+ boxtype = Infinite;
+ mincorner = QVector3D(0, 0, 0);
+ maxcorner = QVector3D(0, 0, 0);
+}
+
+inline QVector3D Q3DBox::size() const { return maxcorner - mincorner; }
+inline QVector3D Q3DBox::center() const { return (mincorner + maxcorner) * 0.5f; }
+
+inline bool Q3DBox::contains(const QVector3D& point) const
+{
+ if (boxtype == Finite) {
+ return (point.x() >= mincorner.x() && point.x() <= maxcorner.x() &&
+ point.y() >= mincorner.y() && point.y() <= maxcorner.y() &&
+ point.z() >= mincorner.z() && point.z() <= maxcorner.z());
+ } else if (boxtype == Infinite) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+inline bool Q3DBox::contains(const Q3DBox& box) const
+{
+ if (box.boxtype == Finite)
+ return contains(box.mincorner) && contains(box.maxcorner);
+ else if (box.boxtype == Infinite)
+ return (boxtype == Infinite);
+ else
+ return false;
+}
+
+inline bool Q3DBox::operator==(const Q3DBox& box) const
+{
+ return (boxtype == box.boxtype &&
+ mincorner == box.mincorner &&
+ maxcorner == box.maxcorner);
+}
+
+inline bool Q3DBox::operator!=(const Q3DBox& box) const
+{
+ return (boxtype != box.boxtype ||
+ mincorner != box.mincorner ||
+ maxcorner != box.maxcorner);
+}
+
+inline bool qFuzzyCompare(const Q3DBox& box1, const Q3DBox& box2)
+{
+ return box1.boxtype == box2.boxtype &&
+ qFuzzyCompare(box1.mincorner, box2.mincorner) &&
+ qFuzzyCompare(box1.maxcorner, box2.maxcorner);
+}
+
+#ifndef QT_NO_DEBUG_STREAM
+QT_DATAVISUALIZATION_EXPORT QDebug operator<<(QDebug dbg, const Q3DBox &box);
+#endif
+
+#ifndef QT_NO_DATASTREAM
+QT_DATAVISUALIZATION_EXPORT QDataStream &operator<<(QDataStream &stream, const Q3DBox &box);
+QT_DATAVISUALIZATION_EXPORT QDataStream &operator>>(QDataStream &stream, Q3DBox &box);
+#endif
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
+#endif
diff --git a/src/datavisualization/engine/q3dcamera.cpp b/src/datavisualization/engine/q3dcamera.cpp
new file mode 100644
index 00000000..571af1d7
--- /dev/null
+++ b/src/datavisualization/engine/q3dcamera.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 QtDataVisualization 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 "q3dcamera.h"
+#include "q3dcamera_p.h"
+#include "q3dscene.h"
+#include "q3dbox.h"
+#include "q3dobject.h"
+#include "utils_p.h"
+
+#include <qmath.h>
+#include <QVector3D>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+/*!
+ \class Q3DCamera
+ \inmodule QtDataVisualization
+ \brief Representation of a camera in 3D space.
+ \since 1.0.0
+
+ Q3DCamera represents a basic orbit around centerpoint 3D camera that is used when rendering the data visualization.
+ The class offers simple methods for setting the orbit point in rotations, but allows also setting the 4x4 viewmatrix
+ directly in case a more customized camera behavior is needed.
+*/
+
+/*!
+ * Constructs a new 3D camera with position set to origo, up direction facing towards the Y-axis and looking at origo by default. An
+ * optional \a parent parameter can be given and is then passed to QObject constructor.
+ */
+Q3DCamera::Q3DCamera(QObject *parent) :
+ Q3DObject(parent),
+ d_ptr(new Q3DCameraPrivate(this))
+{
+}
+
+/*!
+ * Destroys the camera object.
+ */
+Q3DCamera::~Q3DCamera()
+{
+}
+
+/*!
+ * Copies the 3D camera's properties from the given source camera.
+ * Values are copied from the \a source to this object.
+ */
+void Q3DCamera::copyValuesFrom(const Q3DCamera &source)
+{
+ Q3DObject::copyValuesFrom(source);
+
+ d_ptr->m_target.setX(source.d_ptr->m_target.x());
+ d_ptr->m_target.setY(source.d_ptr->m_target.y());
+ d_ptr->m_target.setZ(source.d_ptr->m_target.z());
+
+ d_ptr->m_up.setX(source.d_ptr->m_up.x());
+ d_ptr->m_up.setY(source.d_ptr->m_up.y());
+ d_ptr->m_up.setZ(source.d_ptr->m_up.z());
+
+ float *values = new float[16];
+ source.d_ptr->m_viewMatrix.copyDataTo(values);
+ d_ptr->m_viewMatrix = QMatrix4x4(values);
+ delete[] values;
+
+ d_ptr->m_xRotation = source.d_ptr->m_xRotation;
+ d_ptr->m_yRotation = source.d_ptr->m_yRotation;
+
+ d_ptr->m_minXRotation = source.d_ptr->m_minXRotation;
+ d_ptr->m_minYRotation = source.d_ptr->m_minYRotation;
+ d_ptr->m_maxXRotation = source.d_ptr->m_maxXRotation;
+ d_ptr->m_maxYRotation = source.d_ptr->m_maxYRotation;
+
+ d_ptr->m_wrapXRotation = source.d_ptr->m_wrapXRotation;
+ d_ptr->m_wrapYRotation = source.d_ptr->m_wrapYRotation;
+
+ d_ptr->m_zoomLevel = source.d_ptr->m_zoomLevel;
+ d_ptr->m_activePreset = source.d_ptr->m_activePreset;
+}
+
+/*!
+ * \property Q3DCamera::xRotation
+ *
+ * This property contains the X-rotation angle of the camera around the target point in degrees starting from
+ * the current base position set by the setBaseOrientation() methods.
+ */
+qreal Q3DCamera::xRotation() const {
+ return d_ptr->m_xRotation;
+}
+
+void Q3DCamera::setXRotation(qreal rotation)
+{
+ if (d_ptr->m_wrapXRotation)
+ rotation = Utils::wrapValue(rotation, d_ptr->m_minXRotation, d_ptr->m_maxXRotation);
+ else
+ rotation = qBound(qreal(d_ptr->m_minXRotation), qreal(rotation), qreal(d_ptr->m_maxXRotation));
+
+ if (d_ptr->m_xRotation != rotation) {
+ d_ptr->setXRotation(rotation);
+ if (d_ptr->m_activePreset != QDataVis::CameraPresetNone) {
+ d_ptr->m_activePreset = QDataVis::CameraPresetNone;
+ setDirty(true);
+ }
+
+ emit xRotationChanged(d_ptr->m_xRotation);
+ }
+}
+
+/*!
+ * \property Q3DCamera::yRotation
+ *
+ * This property contains the Y-rotation angle of the camera around the target point in degrees starting from
+ * the current base position set by the setBaseOrientation() methods.
+ */
+qreal Q3DCamera::yRotation() const {
+ return d_ptr->m_yRotation;
+}
+
+void Q3DCamera::setYRotation(qreal rotation)
+{
+ if (d_ptr->m_wrapYRotation)
+ rotation = Utils::wrapValue(rotation, d_ptr->m_minYRotation, d_ptr->m_maxYRotation);
+ else
+ rotation = qBound(qreal(d_ptr->m_minYRotation), qreal(rotation), qreal(d_ptr->m_maxYRotation));
+
+ if (d_ptr->m_yRotation != rotation) {
+ d_ptr->setYRotation(rotation);
+ if (d_ptr->m_activePreset != QDataVis::CameraPresetNone) {
+ d_ptr->m_activePreset = QDataVis::CameraPresetNone;
+ setDirty(true);
+ }
+
+ emit yRotationChanged(d_ptr->m_yRotation);
+ }
+}
+
+/*!
+ * \property Q3DCamera::minXRotation
+ *
+ * This property contains the current minimum X-rotation for the camera.
+ * The full circle range is [-180,180] and the minimum value is limited to -180.
+ * Also the value can't be higher than maximum, and is adjusted if necessary.
+ *
+ * \sa wrapXRotation, maxXRotation
+ */
+qreal Q3DCamera::minXRotation() const
+{
+ return d_ptr->m_minXRotation;
+}
+
+/*!
+ * \internal
+ */
+void Q3DCamera::setMinXRotation(qreal minRotation)
+{
+ minRotation = qBound(-180.0, minRotation, 180.0);
+ if (minRotation > d_ptr->m_maxXRotation)
+ minRotation = d_ptr->m_maxXRotation;
+
+ if (d_ptr->m_minXRotation != minRotation) {
+ d_ptr->m_minXRotation = minRotation;
+ emit minXRotationChanged(minRotation);
+
+ if (d_ptr->m_xRotation < d_ptr->m_minXRotation)
+ setXRotation(d_ptr->m_xRotation);
+ }
+}
+
+/*!
+ * \property Q3DCamera::minYRotation
+ *
+ * This property contains the current minimum Y-rotation for the camera.
+ * The full Y angle range is [-90,90] and the minimum value is limited to -90.
+ * Also the value can't be higher than maximum, and is adjusted if necessary.
+ *
+ * \sa wrapYRotation, maxYRotation
+ */
+qreal Q3DCamera::minYRotation() const
+{
+ return d_ptr->m_minYRotation;
+}
+
+/*!
+ * \internal
+ */
+void Q3DCamera::setMinYRotation(qreal minRotation)
+{
+ minRotation = qBound(-90.0, minRotation, 90.0);
+ if (minRotation > d_ptr->m_maxYRotation)
+ minRotation = d_ptr->m_maxYRotation;
+
+ if (d_ptr->m_minYRotation != minRotation) {
+ d_ptr->m_minYRotation = minRotation;
+ emit minYRotationChanged(minRotation);
+
+ if (d_ptr->m_yRotation < d_ptr->m_minYRotation)
+ setYRotation(d_ptr->m_yRotation);
+ }
+}
+
+/*!
+ * \property Q3DCamera::maxXRotation
+ *
+ * This property contains the current maximum X-rotation for the camera.
+ * The full circle range is [-180,180] and the maximum value is limited to 180.
+ * Also the value can't be lower than minimum, and is adjusted if necessary.
+ *
+ * \sa wrapXRotation, minXRotation
+ */
+qreal Q3DCamera::maxXRotation() const
+{
+ return d_ptr->m_maxXRotation;
+}
+
+/*!
+ * \internal
+ */
+void Q3DCamera::setMaxXRotation(qreal maxRotation)
+{
+ maxRotation = qBound(-180.0, maxRotation, 180.0);
+
+ if (maxRotation < d_ptr->m_minXRotation)
+ maxRotation = d_ptr->m_minXRotation;
+
+ if (d_ptr->m_maxXRotation != maxRotation) {
+ d_ptr->m_maxXRotation = maxRotation;
+ emit maxXRotationChanged(maxRotation);
+
+ if (d_ptr->m_xRotation > d_ptr->m_maxXRotation)
+ setXRotation(d_ptr->m_xRotation);
+ }
+}
+
+/*!
+ * \property Q3DCamera::maxYRotation
+ *
+ * This property contains the current maximum Y-rotation for the camera.
+ * The full Y angle range is [-90,90] and the maximum value is limited to 90.
+ * Also the value can't be lower than minimum, and is adjusted if necessary.
+ *
+ * \sa wrapYRotation, minYRotation
+ */
+qreal Q3DCamera::maxYRotation() const
+{
+ return d_ptr->m_maxYRotation;
+}
+
+/*!
+ * \internal
+ */
+void Q3DCamera::setMaxYRotation(qreal maxRotation)
+{
+ maxRotation = qBound(-90.0, maxRotation, 90.0);
+
+ if (maxRotation < d_ptr->m_minYRotation)
+ maxRotation = d_ptr->m_minYRotation;
+
+ if (d_ptr->m_maxYRotation != maxRotation) {
+ d_ptr->m_maxYRotation = maxRotation;
+ emit maxYRotationChanged(maxRotation);
+
+ if (d_ptr->m_yRotation > d_ptr->m_maxYRotation)
+ setYRotation(d_ptr->m_yRotation);
+ }
+}
+
+/*!
+ * Sets the base values for the camera that are used when calculating the camera position using the rotation values.
+ * The base position of the camera is defined by \a basePosition, expectation is that the x and y values are 0.
+ * Look at target point is defined by \a target and the camera rotates around it. Up direction for the camera is
+ * defined by \a baseUp, normally this is a vector with only y values set to 1.
+ */
+void Q3DCamera::setBaseOrientation(const QVector3D &basePosition,
+ const QVector3D &target,
+ const QVector3D &baseUp)
+{
+ if (position() != basePosition
+ || d_ptr->m_target != target
+ || d_ptr->m_up != baseUp) {
+ setPosition(basePosition);
+ d_ptr->m_target = target;
+ d_ptr->m_up = baseUp;
+ setDirty(true);
+ }
+}
+
+/*!
+ * \property Q3DCamera::viewMatrix
+ *
+ * This property contains the view matrix used in the 3D calculations. When the default orbiting camera behavior is sufficient
+ * there is no need to touch this property. But if the default behavior is insufficient the view matrix can be set directly.
+ * When setting the view matrix directly remember to set Q3DCamera::viewMatrixAutoUpdateEnabled to false.
+ */
+QMatrix4x4 Q3DCamera::viewMatrix() const
+{
+ return d_ptr->m_viewMatrix;
+}
+
+void Q3DCamera::setViewMatrix(const QMatrix4x4 &viewMatrix)
+{
+ if (d_ptr->m_viewMatrix != viewMatrix) {
+ d_ptr->m_viewMatrix = viewMatrix;
+ setDirty(true);
+ emit viewMatrixChanged(d_ptr->m_viewMatrix);
+ }
+}
+
+/*!
+ * \property Q3DCamera::viewMatrixAutoUpdateEnabled
+ *
+ * This property determines if view matrix is automatically updated each render cycle using the current base orientation and
+ * rotations. If set to false, no automatic recalculation is done and the view matrix can be set using the
+ * Q3DMatrix::viewMatrix property.
+ */
+bool Q3DCamera::isViewMatrixAutoUpdateEnabled()
+{
+ return d_ptr->m_isViewMatrixUpdateActive;
+}
+
+void Q3DCamera::setViewMatrixAutoUpdateEnabled(bool isEnabled)
+{
+ d_ptr->m_isViewMatrixUpdateActive = isEnabled;
+ emit viewMatrixAutoUpdateChanged(isEnabled);
+}
+
+/*!
+ * \property Q3DCamera::cameraPreset
+ *
+ * This property contains the currently active camera preset,
+ * if no preset is active the value is QDataVis::CameraPresetNone.
+ * \note The base camera orientation set by setBaseOrientation() will affect
+ * the presets as all calculations are based on those values.
+ */
+QDataVis::CameraPreset Q3DCamera::cameraPreset()
+{
+ return d_ptr->m_activePreset;
+}
+
+void Q3DCamera::setCameraPreset(QDataVis::CameraPreset preset)
+{
+ switch (preset) {
+ case QDataVis::CameraPresetFrontLow: {
+ setXRotation(0.0);
+ setYRotation(0.0);
+ break;
+ }
+ case QDataVis::CameraPresetFront: {
+ setXRotation(0.0);
+ setYRotation(22.5);
+ break;
+ }
+ case QDataVis::CameraPresetFrontHigh: {
+ setXRotation(0.0);
+ setYRotation(45.0);
+ break;
+ }
+ case QDataVis::CameraPresetLeftLow: {
+ setXRotation(90.0);
+ setYRotation(0.0);
+ break;
+ }
+ case QDataVis::CameraPresetLeft: {
+ setXRotation(90.0);
+ setYRotation(22.5);
+ break;
+ }
+ case QDataVis::CameraPresetLeftHigh: {
+ setXRotation(90.0);
+ setYRotation(45.0);
+ break;
+ }
+ case QDataVis::CameraPresetRightLow: {
+ setXRotation(-90.0);
+ setYRotation(0.0);
+ break;
+ }
+ case QDataVis::CameraPresetRight: {
+ setXRotation(-90.0);
+ setYRotation(22.5);
+ break;
+ }
+ case QDataVis::CameraPresetRightHigh: {
+ setXRotation(-90.0);
+ setYRotation(45.0);
+ break;
+ }
+ case QDataVis::CameraPresetBehindLow: {
+ setXRotation(180.0);
+ setYRotation(0.0);
+ break;
+ }
+ case QDataVis::CameraPresetBehind: {
+ setXRotation(180.0);
+ setYRotation(22.5);
+ break;
+ }
+ case QDataVis::CameraPresetBehindHigh: {
+ setXRotation(180.0);
+ setYRotation(45.0);
+ break;
+ }
+ case QDataVis::CameraPresetIsometricLeft: {
+ setXRotation(45.0);
+ setYRotation(22.5);
+ break;
+ }
+ case QDataVis::CameraPresetIsometricLeftHigh: {
+ setXRotation(45.0);
+ setYRotation(45.0);
+ break;
+ }
+ case QDataVis::CameraPresetIsometricRight: {
+ setXRotation(-45.0);
+ setYRotation(22.5);
+ break;
+ }
+ case QDataVis::CameraPresetIsometricRightHigh: {
+ setXRotation(-45.0);
+ setYRotation(45.0);
+ break;
+ }
+ case QDataVis::CameraPresetDirectlyAbove: {
+ setXRotation(0.0);
+ setYRotation(90.0);
+ break;
+ }
+ case QDataVis::CameraPresetDirectlyAboveCW45: {
+ setXRotation(-45.0);
+ setYRotation(90.0);
+ break;
+ }
+ case QDataVis::CameraPresetDirectlyAboveCCW45: {
+ setXRotation(45.0);
+ setYRotation(90.0);
+ break;
+ }
+ case QDataVis::CameraPresetFrontBelow: {
+ setXRotation(0.0);
+ setYRotation(-45.0);
+ break;
+ }
+ case QDataVis::CameraPresetLeftBelow: {
+ setXRotation(90.0);
+ setYRotation(-45.0);
+ break;
+ }
+ case QDataVis::CameraPresetRightBelow: {
+ setXRotation(-90.0);
+ setYRotation(-45.0);
+ break;
+ }
+ case QDataVis::CameraPresetBehindBelow: {
+ setXRotation(180.0);
+ setYRotation(-45.0);
+ break;
+ }
+ case QDataVis::CameraPresetDirectlyBelow: {
+ setXRotation(0.0);
+ setYRotation(-90.0);
+ break;
+ }
+ default:
+ preset = QDataVis::CameraPresetNone;
+ break;
+ }
+
+ if (d_ptr->m_activePreset != preset) {
+ d_ptr->m_activePreset = preset;
+ setDirty(true);
+ emit cameraPresetChanged(preset);
+ }
+}
+
+/*!
+ * \property Q3DCamera::zoomLevel
+ *
+ * This property contains the the camera zoom level in percentages.
+ * 100% means there is no zoom in or out set in the camera.
+ */
+int Q3DCamera::zoomLevel()
+{
+ return d_ptr->m_zoomLevel;
+}
+
+void Q3DCamera::setZoomLevel(int zoomLevel)
+{
+ if (d_ptr->m_zoomLevel != zoomLevel) {
+ d_ptr->m_zoomLevel = zoomLevel;
+ setDirty(true);
+ emit zoomLevelChanged(zoomLevel);
+ }
+}
+
+/*!
+ * Calculates and returns a position relative to the camera using the given parameters
+ * and the current camera viewMatrix property.
+ * \a relativePosition defines the relative 3D offset to the current camera position.
+ * \a fixedRotation is optional, if given fixes rotation of the calculated point around the data visualization area to the given value in degrees.
+ * \a distanceModifier is also optional, if given modifies the distance of the calculated point from the data visualization.
+ * \return Calculated position relative to this camera's position.
+ */
+QVector3D Q3DCamera::calculatePositionRelativeToCamera(const QVector3D &relativePosition,
+ qreal fixedRotation,
+ qreal distanceModifier) const
+{
+ // Move the position with camera
+ GLfloat radiusFactor = relativePosition.z() * (1.5f + distanceModifier);
+ GLfloat xAngle;
+ GLfloat yAngle;
+ if (!fixedRotation) {
+ xAngle = qDegreesToRadians(d_ptr->m_xRotation);
+ yAngle = qDegreesToRadians(d_ptr->m_yRotation);
+ } else {
+ xAngle = qDegreesToRadians(fixedRotation);
+ yAngle = 0;
+ }
+ GLfloat radius = (radiusFactor + relativePosition.y()); // set radius to match the highest height of the position
+ GLfloat zPos = radius * qCos(xAngle) * qCos(yAngle);
+ GLfloat xPos = radius * qSin(xAngle) * qCos(yAngle);
+ GLfloat yPos = (radiusFactor + relativePosition.y()) * qSin(yAngle);
+ // Keep in the set position in relation to camera
+ return QVector3D(-xPos + relativePosition.x(),
+ yPos + relativePosition.y(),
+ zPos + relativePosition.z());
+}
+
+/*!
+ * \property Q3DCamera::wrapXRotation
+ *
+ * This property determines the behavior of the minimum and maximum limits in the X-rotation.
+ * By default the X-rotation wraps from minimum value to maximum and from maximum to minimum.
+ *
+ * If set to true the X-rotation of the camera is wrapped from minimum to maximum and from maximum to minimum.
+ * If set to false the X-rotation of the camera is limited to the sector determined by minimum and maximum values.
+ */
+bool Q3DCamera::wrapXRotation() const
+{
+ return d_ptr->m_wrapXRotation;
+}
+
+void Q3DCamera::setWrapXRotation(bool isEnabled)
+{
+ d_ptr->m_wrapXRotation = isEnabled;
+}
+
+/*!
+ * \property Q3DCamera::wrapYRotation
+ *
+ * This property determines the behavior of the minimum and maximum limits in the Y-rotation.
+ * By default the Y-rotation is limited between the minimum and maximum values without any wrapping.
+ *
+ * If true the Y-rotation of the camera is wrapped from minimum to maximum and from maximum to minimum.
+ * If false the Y-rotation of the camera is limited to the sector determined by minimum and maximum values.
+ */
+bool Q3DCamera::wrapYRotation() const
+{
+ return d_ptr->m_wrapYRotation;
+}
+
+void Q3DCamera::setWrapYRotation(bool isEnabled)
+{
+ d_ptr->m_wrapYRotation = isEnabled;
+}
+
+/*!
+ * Utility function that sets the camera rotations and distance.\a horizontal and \a vertical define the camera rotations to be used.
+ * Optional \a zoom parameter can be given to set the zoom of the camera in range of 10-500%.
+ */
+void Q3DCamera::setCameraPosition(qreal horizontal, qreal vertical, qreal zoom)
+{
+ setZoomLevel(qBound(10.0, zoom, 500.0));
+ setXRotation(horizontal);
+ setYRotation(vertical);
+}
+
+Q3DCameraPrivate::Q3DCameraPrivate(Q3DCamera *q) :
+ q_ptr(q),
+ m_isViewMatrixUpdateActive(true),
+ m_xRotation(0.0),
+ m_yRotation(0.0),
+ m_minXRotation(-180.0),
+ m_minYRotation(0.0),
+ m_maxXRotation(180.0),
+ m_maxYRotation(90.0),
+ m_wrapXRotation(true),
+ m_wrapYRotation(false),
+ m_zoomLevel(100),
+ m_activePreset(QDataVis::CameraPresetNone)
+{
+}
+
+Q3DCameraPrivate::~Q3DCameraPrivate()
+{
+}
+
+// Copies changed values from this camera to the other camera. If the other camera had same changes,
+// those changes are discarded.
+void Q3DCameraPrivate::sync(Q3DCamera &other)
+{
+ if (q_ptr->isDirty()) {
+ other.copyValuesFrom(*q_ptr);
+ q_ptr->setDirty(false);
+ other.setDirty(false);
+ }
+}
+
+void Q3DCameraPrivate::setXRotation(const qreal rotation)
+{
+ if (m_xRotation != rotation) {
+ m_xRotation = rotation;
+ q_ptr->setDirty(true);
+ }
+}
+
+void Q3DCameraPrivate::setYRotation(const qreal rotation)
+{
+ if (m_yRotation != rotation) {
+ m_yRotation = rotation;
+ q_ptr->setDirty(true);
+ }
+}
+
+void Q3DCameraPrivate::setMinXRotation(const qreal rotation)
+{
+ if (m_minXRotation != rotation) {
+ m_minXRotation = rotation;
+ q_ptr->setDirty(true);
+ }
+}
+
+void Q3DCameraPrivate::setMinYRotation(const qreal rotation)
+{
+ if (m_minYRotation != rotation) {
+ m_minYRotation = rotation;
+ q_ptr->setDirty(true);
+ }
+}
+
+void Q3DCameraPrivate::setMaxXRotation(const qreal rotation)
+{
+ if (m_maxXRotation != rotation) {
+ m_maxXRotation = rotation;
+ q_ptr->setDirty(true);
+ }
+}
+
+void Q3DCameraPrivate::setMaxYRotation(const qreal rotation)
+{
+ if (m_maxYRotation != rotation) {
+ m_maxYRotation = rotation;
+ q_ptr->setDirty(true);
+ }
+}
+
+// Recalculates the view matrix based on the currently set base orientation, rotation and zoom level values.
+// zoomAdjustment is adjustment to ensure that the 3D visualization stays inside the view area in the 100% zoom.
+void Q3DCameraPrivate::updateViewMatrix(qreal zoomAdjustment)
+{
+ if (!m_isViewMatrixUpdateActive)
+ return;
+
+ int zoom = m_zoomLevel * zoomAdjustment;
+ QMatrix4x4 viewMatrix;
+
+ // Apply to view matrix
+ viewMatrix.lookAt(q_ptr->position(), m_target, m_up);
+ // Compensate for translation (if d_ptr->m_target is off origin)
+ 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, 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
+ viewMatrix.scale((GLfloat)zoom / 100.0f);
+ // Compensate for translation (if d_ptr->m_target is off origin)
+ viewMatrix.translate(-m_target.x(), -m_target.y(), -m_target.z());
+
+ q_ptr->setViewMatrix(viewMatrix);
+}
+
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualization/engine/q3dcamera.h b/src/datavisualization/engine/q3dcamera.h
new file mode 100644
index 00000000..ee750cec
--- /dev/null
+++ b/src/datavisualization/engine/q3dcamera.h
@@ -0,0 +1,131 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 Q3DCAMERA_H
+#define Q3DCAMERA_H
+
+#include <QtDataVisualization/q3dobject.h>
+#include <QMatrix4x4>
+
+class QVector3D;
+class QPoint;
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class Q3DCameraPrivate;
+
+class QT_DATAVISUALIZATION_EXPORT Q3DCamera : public Q3DObject
+{
+ Q_OBJECT
+ Q_PROPERTY(qreal xRotation READ xRotation WRITE setXRotation NOTIFY xRotationChanged)
+ Q_PROPERTY(qreal yRotation READ yRotation WRITE setYRotation NOTIFY yRotationChanged)
+ Q_PROPERTY(qreal minXRotation READ minXRotation NOTIFY minXRotationChanged)
+ Q_PROPERTY(qreal minYRotation READ minYRotation NOTIFY minYRotationChanged)
+ Q_PROPERTY(qreal maxXRotation READ maxXRotation NOTIFY maxXRotationChanged)
+ Q_PROPERTY(qreal maxYRotation READ maxYRotation NOTIFY maxYRotationChanged)
+ Q_PROPERTY(int zoomLevel READ zoomLevel WRITE setZoomLevel NOTIFY zoomLevelChanged)
+ Q_PROPERTY(QMatrix4x4 viewMatrix READ viewMatrix WRITE setViewMatrix NOTIFY viewMatrixChanged)
+ Q_PROPERTY(QtDataVisualization::QDataVis::CameraPreset cameraPreset READ cameraPreset WRITE setCameraPreset NOTIFY cameraPresetChanged)
+ Q_PROPERTY(bool viewMatrixAutoUpdateEnabled READ isViewMatrixAutoUpdateEnabled WRITE setViewMatrixAutoUpdateEnabled NOTIFY viewMatrixAutoUpdateChanged)
+ Q_PROPERTY(bool wrapXRotation READ wrapXRotation WRITE setWrapXRotation NOTIFY wrapXRotationChanged )
+ Q_PROPERTY(bool wrapYRotation READ wrapYRotation WRITE setWrapYRotation NOTIFY wrapYRotationChanged )
+ Q_ENUMS(QtDataVisualization::QDataVis::CameraPreset)
+
+public:
+ Q3DCamera(QObject *parent = 0);
+ virtual ~Q3DCamera();
+
+ qreal xRotation() const;
+ void setXRotation(qreal rotation);
+ qreal yRotation() const;
+ void setYRotation(qreal rotation);
+
+ qreal minXRotation() const;
+ qreal maxXRotation() const;
+
+ qreal minYRotation() const;
+ qreal maxYRotation() const;
+
+ bool wrapXRotation() const;
+ void setWrapXRotation(bool isEnabled);
+
+ bool wrapYRotation() const;
+ void setWrapYRotation(bool isEnabled);
+
+ void copyValuesFrom(const Q3DCamera &source);
+
+ QMatrix4x4 viewMatrix() const;
+ void setViewMatrix(const QMatrix4x4 &viewMatrix);
+
+ bool isViewMatrixAutoUpdateEnabled();
+ void setViewMatrixAutoUpdateEnabled(bool isEnabled);
+
+ QDataVis::CameraPreset cameraPreset();
+ void setCameraPreset(QDataVis::CameraPreset preset);
+
+ int zoomLevel();
+ void setZoomLevel(int zoomLevel);
+
+ void setBaseOrientation(const QVector3D &defaultPosition,
+ const QVector3D &defaultTarget,
+ const QVector3D &defaultUp);
+
+ QVector3D calculatePositionRelativeToCamera(const QVector3D &relativePosition,
+ qreal fixedRotation,
+ qreal distanceModifier) const;
+ void setCameraPosition(qreal horizontal, qreal vertical, qreal distance = 100.0);
+
+signals:
+ void xRotationChanged(qreal rotation);
+ void yRotationChanged(qreal rotation);
+ void minXRotationChanged(qreal rotation);
+ void minYRotationChanged(qreal rotation);
+ void maxXRotationChanged(qreal rotation);
+ void maxYRotationChanged(qreal rotation);
+ void zoomLevelChanged(int zoomLevel);
+ void viewMatrixChanged(QMatrix4x4 viewMatrix);
+ void cameraPresetChanged(QDataVis::CameraPreset preset);
+ void viewMatrixAutoUpdateChanged(bool enabled);
+ void wrapXRotationChanged(bool isEnabled);
+ void wrapYRotationChanged(bool isEnabled);
+
+protected:
+ void setMinXRotation(qreal rotation);
+ void setMinYRotation(qreal rotation);
+ void setMaxXRotation(qreal rotation);
+ void setMaxYRotation(qreal rotation);
+
+private:
+ QScopedPointer<Q3DCameraPrivate> d_ptr;
+
+ Q_DISABLE_COPY(Q3DCamera)
+
+ friend class Q3DCameraPrivate;
+ friend class Q3DScenePrivate;
+ friend class Bars3DRenderer;
+ friend class Surface3DRenderer;
+ friend class Scatter3DRenderer;
+ friend class SelectionPointer;
+ friend class Q3DInputHandler;
+ friend class QTouch3DInputHandlerPrivate;
+ friend class QMac3DInputHandler;
+};
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
+#endif // Q3DCAMERA_H
diff --git a/src/datavisualization/engine/q3dcamera_p.h b/src/datavisualization/engine/q3dcamera_p.h
new file mode 100644
index 00000000..e0528dcc
--- /dev/null
+++ b/src/datavisualization/engine/q3dcamera_p.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 QtDataVisualization 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 QtDataVisualization 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 Q3DCAMERA_P_H
+#define Q3DCAMERA_P_H
+
+#include "datavisualizationglobal_p.h"
+#include "q3dcamera.h"
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class Q3DCamera;
+
+class Q3DCameraPrivate
+{
+public:
+ Q3DCameraPrivate(Q3DCamera *q);
+ ~Q3DCameraPrivate();
+
+ void sync(Q3DCamera &other);
+
+ void setXRotation(qreal rotation);
+ void setYRotation(qreal rotation);
+ void setMinXRotation(qreal rotation);
+ void setMinYRotation(qreal rotation);
+ void setMaxXRotation(qreal rotation);
+ void setMaxYRotation(qreal rotation);
+
+ void updateViewMatrix(qreal zoomAdjustment);
+
+public:
+ Q3DCamera *q_ptr;
+
+ QVector3D m_target;
+ QVector3D m_up;
+
+ QMatrix4x4 m_viewMatrix;
+ bool m_isViewMatrixUpdateActive;
+
+ GLfloat m_xRotation;
+ GLfloat m_yRotation;
+ GLfloat m_minXRotation;
+ GLfloat m_minYRotation;
+ GLfloat m_maxXRotation;
+ GLfloat m_maxYRotation;
+ bool m_wrapXRotation;
+ bool m_wrapYRotation;
+ int m_zoomLevel;
+ QDataVis::CameraPreset m_activePreset;
+
+ friend class Bars3DRenderer;
+ friend class Surface3DRenderer;
+ friend class Scatter3DRenderer;
+ friend class SelectionPointer;
+ friend class Q3DInputHandler;
+ friend class QTouch3DInputHandler;
+ friend class QMac3DInputHandler;
+};
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
+#endif // Q3DCAMERA_P_H
diff --git a/src/datavisualization/engine/q3dlight.cpp b/src/datavisualization/engine/q3dlight.cpp
new file mode 100644
index 00000000..c482e62a
--- /dev/null
+++ b/src/datavisualization/engine/q3dlight.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 QtDataVisualization 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 "q3dlight.h"
+#include "q3dscene.h"
+#include "q3dlight_p.h"
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+/*!
+ \class Q3DLight
+ \inmodule QtDataVisualization
+ \brief Representation of a light source in 3D space.
+ \since 1.0.0
+
+ Q3DLight represents a monochrome non variable light source in 3D space.
+*/
+
+/*!
+ * Constructs a new 3D light located at origo. An optional \a parent parameter can be given
+ * and is then passed to QObject constructor.
+ */
+Q3DLight::Q3DLight(QObject *parent) :
+ Q3DObject(parent),
+ d_ptr(new Q3DLightPrivate(this))
+{
+}
+
+/*!
+ * Copies the properties of the 3D light from the given source \a source light to this light instance.
+ */
+void Q3DLight::copyValuesFrom(const Q3DLight &source)
+{
+ Q3DObject::copyValuesFrom(source);
+}
+
+/*!
+ * Destroys the light object.
+ */
+Q3DLight::~Q3DLight()
+{
+}
+
+Q3DLightPrivate::Q3DLightPrivate(Q3DLight *q) :
+ q_ptr(q)
+{
+}
+
+Q3DLightPrivate::~Q3DLightPrivate()
+{
+}
+
+void Q3DLightPrivate::sync(Q3DLight &other)
+{
+ // Copies changed values from this light to the other light. If the other light had same changes,
+ // those changes are discarded.
+ if (q_ptr->isDirty()) {
+ other.copyValuesFrom(*q_ptr);
+ q_ptr->setDirty(false);
+ other.setDirty(false);
+ }
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualization/engine/q3dlight.h b/src/datavisualization/engine/q3dlight.h
new file mode 100644
index 00000000..0a4ba174
--- /dev/null
+++ b/src/datavisualization/engine/q3dlight.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 Q3DLIGHT_H
+#define Q3DLIGHT_H
+
+#include <QtDataVisualization/q3dobject.h>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class Q3DLightPrivate;
+class Q3DScene;
+
+class QT_DATAVISUALIZATION_EXPORT Q3DLight : public Q3DObject
+{
+ Q_OBJECT
+
+public:
+ Q3DLight(QObject *parent = 0);
+ virtual ~Q3DLight();
+
+ void copyValuesFrom(const Q3DLight &source);
+
+private:
+ QScopedPointer<Q3DLightPrivate> d_ptr;
+
+ Q_DISABLE_COPY(Q3DLight)
+
+ friend class Q3DLightPrivate;
+ friend class Q3DScenePrivate;
+};
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
+#endif // Q3DLIGHT_H
diff --git a/src/datavisualization/engine/q3dlight_p.h b/src/datavisualization/engine/q3dlight_p.h
new file mode 100644
index 00000000..dad6d670
--- /dev/null
+++ b/src/datavisualization/engine/q3dlight_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 QtDataVisualization 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 QtDataVisualization 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 Q3DLIGHT_P_H
+#define Q3DLIGHT_P_H
+
+#include "datavisualizationglobal_p.h"
+#include "q3dlight.h"
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class Q3DScene;
+class Q3DLight;
+
+class Q3DLightPrivate
+{
+public:
+ Q3DLightPrivate(Q3DLight *q);
+ ~Q3DLightPrivate();
+
+ void sync(Q3DLight &other);
+
+public:
+ Q3DLight *q_ptr;
+};
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
+#endif // Q3DLIGHT_P_H
+
+
+
+
+
diff --git a/src/datavisualization/engine/q3dobject.cpp b/src/datavisualization/engine/q3dobject.cpp
new file mode 100644
index 00000000..ae13af7d
--- /dev/null
+++ b/src/datavisualization/engine/q3dobject.cpp
@@ -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 QtDataVisualization 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 "q3dobject.h"
+#include "q3dobject_p.h"
+#include "q3dscene.h"
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+/*!
+ \class Q3DObject
+ \inmodule QtDataVisualization
+ \brief Simple baseclass for all the objects in the 3D scene.
+ \since 1.0.0
+
+ Q3DObject is a baseclass that contains only position information for an object in 3D scene.
+ The object is considered to be a single point in the coordinate space without dimensions.
+*/
+
+/*!
+ * Constructs a new 3D object with position set to origo by default. An
+ * optional \a parent parameter can be given and is then passed to QObject constructor.
+ */
+Q3DObject::Q3DObject(QObject *parent) :
+ QObject(parent),
+ d_ptr(new Q3DObjectPrivate(this))
+{
+}
+
+/*!
+ * Destroys the 3D object.
+ */
+Q3DObject::~Q3DObject()
+{
+}
+
+/*!
+ * Copies the 3D object position from the given \a source 3D object to this 3D object instance.
+ */
+void Q3DObject::copyValuesFrom(const Q3DObject &source)
+{
+ d_ptr->m_position.setX(source.d_ptr->m_position.x());
+ d_ptr->m_position.setY(source.d_ptr->m_position.y());
+ d_ptr->m_position.setZ(source.d_ptr->m_position.z());
+ setDirty(true);
+}
+
+/*!
+ * \property Q3DObject::parentScene
+ *
+ * This property contains the parent scene as read only value.
+ * If the object has no parent scene the value is 0.
+ */
+Q3DScene *Q3DObject::parentScene()
+{
+ return qobject_cast<Q3DScene *>(parent());
+}
+
+/*!
+ * \property Q3DObject::position
+ *
+ * This property contains the 3D position of the object.
+ */
+QVector3D Q3DObject::position() const
+{
+ return d_ptr->m_position;
+}
+
+void Q3DObject::setPosition(const QVector3D &position)
+{
+ if (d_ptr->m_position != position) {
+ d_ptr->m_position = position;
+ setDirty(true);
+ emit positionChanged(d_ptr->m_position);
+ }
+}
+
+/*!
+ * Sets and clears the \a dirty flag that is used to track
+ * when the 3D object has changed since last update.
+ */
+void Q3DObject::setDirty(bool dirty)
+{
+ d_ptr->m_isDirty = dirty;
+}
+
+/*!
+ * \return flag that indicates if the 3D object has changed.
+ */
+bool Q3DObject::isDirty() const
+{
+ return d_ptr->m_isDirty;
+}
+
+Q3DObjectPrivate::Q3DObjectPrivate(Q3DObject *q) :
+ q_ptr(q),
+ m_isDirty(true)
+{
+}
+
+Q3DObjectPrivate::~Q3DObjectPrivate()
+{
+
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualization/engine/q3dobject.h b/src/datavisualization/engine/q3dobject.h
new file mode 100644
index 00000000..930bb022
--- /dev/null
+++ b/src/datavisualization/engine/q3dobject.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 QtDataVisualization 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 Q3DOBJECT_H
+#define Q3DOBJECT_H
+
+#include <QtDataVisualization/qdatavisualizationenums.h>
+#include <QtDataVisualization/q3dscene.h>
+
+#include <QObject>
+#include <QVector3D>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+class Q3DObjectPrivate;
+
+class Q3DObject : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(Q3DScene* parentScene READ parentScene)
+ Q_PROPERTY(QVector3D position READ position WRITE setPosition NOTIFY positionChanged)
+
+public:
+ Q3DObject(QObject *parent = 0);
+ virtual ~Q3DObject();
+
+ void copyValuesFrom(const Q3DObject &source);
+
+ Q3DScene *parentScene();
+
+ QVector3D position() const;
+ void setPosition(const QVector3D &position);
+
+signals:
+ void positionChanged(QVector3D position);
+
+protected:
+ void setDirty(bool dirty);
+ bool isDirty() const;
+
+private:
+ QScopedPointer<Q3DObjectPrivate> d_ptr;
+
+ Q_DISABLE_COPY(Q3DObject)
+
+ friend class Q3DScenePrivate;
+};
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
+#endif // Q3DOBJECT_H
diff --git a/src/datavisualization/engine/q3dobject_p.h b/src/datavisualization/engine/q3dobject_p.h
new file mode 100644
index 00000000..bac18cfe
--- /dev/null
+++ b/src/datavisualization/engine/q3dobject_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 QtDataVisualization 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 QtDataVisualization 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 Q3DOBJECT_P_H
+#define Q3DOBJECT_P_H
+
+#include "datavisualizationglobal_p.h"
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class Q3DObject;
+class Q3DScene;
+
+class Q3DObjectPrivate
+{
+public:
+ Q3DObjectPrivate(Q3DObject *q);
+ ~Q3DObjectPrivate();
+
+public:
+ Q3DObject *q_ptr;
+ QVector3D m_position;
+ bool m_isDirty;
+};
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
+#endif // Q3DOBJECT_P_H
diff --git a/src/datavisualization/engine/q3dscatter.cpp b/src/datavisualization/engine/q3dscatter.cpp
new file mode 100644
index 00000000..a5053bf3
--- /dev/null
+++ b/src/datavisualization/engine/q3dscatter.cpp
@@ -0,0 +1,568 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 "q3dvalueaxis.h"
+#include "qscatterdataproxy.h"
+#include "q3dcamera.h"
+
+#include <QMouseEvent>
+#include <QDebug>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+/*!
+ * \class Q3DScatter
+ * \inmodule QtDataVisualization
+ * \brief The Q3DScatter class provides methods for rendering 3D scatter graphs.
+ * \since 1.0.0
+ *
+ * This class enables developers to render scatter 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.
+ *
+ * If no axes are explicitly set to Q3DScatter, temporary default axes with no labels are created.
+ * These default axes can be modified via axis accessors, but as soon any axis is explicitly
+ * set for the orientation, the default axis for that orientation is destroyed.
+ *
+ * Data proxies work similarly: If no data proxy is explicitly set, Q3DScatter creates a default
+ * proxy. If any other proxy is set as active data proxy later, the default proxy and all data
+ * added to it is destroyed.
+ *
+ * Methods are provided for changing item styles, themes, item selection modes and so on. See the
+ * methods for more detailed descriptions.
+ *
+ * \section1 How to construct a minimal Q3DScatter graph
+ *
+ * First, construct Q3DScatter:
+ *
+ * \snippet doc_src_q3dscatter_construction.cpp 0
+ *
+ * Now Q3DScatter is ready to receive data to be rendered. Add one set of 3 QVector3D items:
+ *
+ * \snippet doc_src_q3dscatter_construction.cpp 1
+ *
+ * Finally you will need to set it visible:
+ *
+ * \snippet doc_src_q3dscatter_construction.cpp 2
+ *
+ * The complete code needed to create and display this graph 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{Scatter Example}.
+ *
+ * \sa Q3DBars, Q3DSurface, {Qt Data Visualization C++ Classes}
+ */
+
+/*!
+ * Constructs a new 3D scatter window.
+ */
+Q3DScatter::Q3DScatter()
+ : d_ptr(new Q3DScatterPrivate(this, geometry()))
+{
+ setVisualController(d_ptr->m_shared);
+ d_ptr->m_shared->initializeOpenGL();
+ QObject::connect(d_ptr->m_shared, &Scatter3DController::selectedItemIndexChanged, this,
+ &Q3DScatter::selectedItemIndexChanged);
+ QObject::connect(d_ptr->m_shared, &Abstract3DController::needRender, this,
+ &Q3DWindow::renderLater);
+}
+
+/*!
+ * Destroys the 3D scatter window.
+ */
+Q3DScatter::~Q3DScatter()
+{
+}
+
+/*!
+ * \internal
+ */
+void Q3DScatter::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ d_ptr->m_shared->mouseDoubleClickEvent(event);
+}
+
+/*!
+ * \internal
+ */
+void Q3DScatter::touchEvent(QTouchEvent *event)
+{
+ d_ptr->m_shared->touchEvent(event);
+}
+
+/*!
+ * \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());
+}
+
+/*!
+ * Sets window \a width.
+ */
+void Q3DScatter::setWidth(const int width)
+{
+ d_ptr->m_shared->setWidth(width);
+ QWindow::setWidth(width);
+}
+
+/*!
+ * Sets window \a height.
+ */
+void Q3DScatter::setHeight(const int height)
+{
+ d_ptr->m_shared->setHeight(height);
+ QWindow::setHeight(height);
+}
+
+/*!
+ * Sets the item \a style to one of the values in \c QDataVis::MeshStyle. It is preset to
+ * \c QDataVis::MeshStyleSpheres by default. A \a smooth flag can be used to set shading to smooth.
+ * It is \c false by default.
+ *
+ * \sa setMeshFileName()
+ */
+void Q3DScatter::setObjectType(QDataVis::MeshStyle style, bool smooth)
+{
+ d_ptr->m_shared->setObjectType(style, smooth);
+}
+
+/*!
+ * Sets a predefined \a theme from \c QDataVis::Theme. It is preset to \c QDataVis::ThemeQt by
+ * default. Theme affects bar colors, label colors, text color, background color, window color and
+ * grid color. Lighting is also adjusted by themes.
+ *
+ * \sa setObjectColor()
+ *
+ * \warning This method is subject to change.
+ */
+void Q3DScatter::setTheme(QDataVis::Theme theme)
+{
+ d_ptr->m_shared->setTheme(theme);
+}
+
+/*!
+ * Set item color using your own colors. \a baseColor sets the base color of a item. The \a uniform
+ * -flag is used to define if color needs to be uniform throughout item's length, or will the colors
+ * be applied by height. It is \c true by default.
+ *
+ * Calling this method overrides colors from theme.
+ *
+ * \sa setTheme()
+ *
+ * \warning This method is subject to change.
+ */
+void Q3DScatter::setObjectColor(const QColor &baseColor, bool uniform)
+{
+ d_ptr->m_shared->setObjectColor(baseColor, uniform);
+}
+
+/*!
+ * \return item color in use.
+ */
+QColor Q3DScatter::objectColor() const
+{
+ return d_ptr->m_shared->objectColor();
+}
+
+/*!
+ * \property Q3DScatter::selectionMode
+ *
+ * Sets item selection \a mode to one of \c QDataVis::SelectionMode. It is preset to
+ * \c QDataVis::SelectionModeItem by default.
+ */
+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::meshFileName
+ *
+ * Override item type with a mesh object located in \a objFileName.
+ * \note Object needs to be in Wavefront obj format and include vertices, normals and UVs.
+ * It also needs to be in triangles.
+ *
+ * \sa setObjectType()
+ */
+void Q3DScatter::setMeshFileName(const QString &objFileName)
+{
+ d_ptr->m_shared->setMeshFileName(objFileName);
+}
+
+QString Q3DScatter::meshFileName() const
+{
+ return d_ptr->m_shared->meshFileName();
+}
+
+/*!
+ * \property Q3DScatter::font
+ *
+ * Sets the \a font for labels. It is preset to \c Arial by default.
+ */
+void Q3DScatter::setFont(const QFont &font)
+{
+ d_ptr->m_shared->setFont(font);
+}
+
+QFont Q3DScatter::font() const
+{
+ return d_ptr->m_shared->font();
+}
+
+/*!
+ * \property Q3DScatter::scene
+ *
+ * This property contains the read only Q3DScene that can be used to access e.g. camera object.
+ */
+Q3DScene *Q3DScatter::scene() const
+{
+ return d_ptr->m_shared->scene();
+}
+
+/*!
+ * \property Q3DScatter::labelStyle
+ *
+ * Sets label \a style to one of \c QDataVis::LabelStyle. It is preset to
+ * \c QDataVis::LabelStyleFromTheme by default.
+ */
+void Q3DScatter::setLabelStyle(QDataVis::LabelStyle style)
+{
+ d_ptr->m_shared->setLabelStyle(style);
+}
+
+QDataVis::LabelStyle Q3DScatter::labelStyle() const
+{
+ return d_ptr->m_shared->labelStyle();
+}
+
+/*!
+ * \property Q3DScatter::gridVisible
+ *
+ * Sets grid visibility to \a visible. It is preset to \c true by default.
+ */
+void Q3DScatter::setGridVisible(bool visible)
+{
+ d_ptr->m_shared->setGridEnabled(visible);
+}
+
+bool Q3DScatter::isGridVisible() const
+{
+ return d_ptr->m_shared->gridEnabled();
+}
+
+/*!
+ * \property Q3DScatter::backgroundVisible
+ *
+ * Sets background visibility to \a visible. It is preset to \c true by default.
+ */
+void Q3DScatter::setBackgroundVisible(bool visible)
+{
+ d_ptr->m_shared->setBackgroundEnabled(visible);
+}
+
+bool Q3DScatter::isBackgroundVisible() const
+{
+ return d_ptr->m_shared->backgroundEnabled();
+}
+
+/*!
+ * \property Q3DScatter::selectedItemIndex
+ *
+ * Selects an item in the \a index. Only one item can be selected at a time.
+ * To clear selection, specify an illegal \a index, e.g. -1.
+ */
+void Q3DScatter::setSelectedItemIndex(int index)
+{
+ d_ptr->m_shared->setSelectedItemIndex(index);
+}
+
+int Q3DScatter::selectedItemIndex() const
+{
+ return d_ptr->m_shared->selectedItemIndex();
+}
+
+/*!
+ * \property Q3DScatter::shadowQuality
+ *
+ * Sets shadow \a quality to one of \c QDataVis::ShadowQuality. It is preset to
+ * \c QDataVis::ShadowQualityMedium by default.
+ *
+ * \note 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();
+}
+
+/*!
+ * Sets a user-defined X-axis. Implicitly calls addAxis() to transfer ownership
+ * of the \a axis to this graph.
+ *
+ * If the \a axis is null, a temporary default axis with no labels and automatically adjusting
+ * range is created.
+ * This temporary axis is destroyed if another \a axis is explicitly set to same orientation.
+ *
+ * \sa addAxis(), releaseAxis()
+ */
+void Q3DScatter::setAxisX(Q3DValueAxis *axis)
+{
+ d_ptr->m_shared->setAxisX(axis);
+}
+
+/*!
+ * \return used X-axis.
+ */
+Q3DValueAxis *Q3DScatter::axisX() const
+{
+ return static_cast<Q3DValueAxis *>(d_ptr->m_shared->axisX());
+}
+
+/*!
+ * Sets a user-defined Y-axis. Implicitly calls addAxis() to transfer ownership
+ * of the \a axis to this graph.
+ *
+ * If the \a axis is null, a temporary default axis with no labels and automatically adjusting
+ * range is created.
+ * This temporary axis is destroyed if another \a axis is explicitly set to same orientation.
+ *
+ * \sa addAxis(), releaseAxis()
+ */
+void Q3DScatter::setAxisY(Q3DValueAxis *axis)
+{
+ d_ptr->m_shared->setAxisY(axis);
+}
+
+/*!
+ * \return used Y-axis.
+ */
+Q3DValueAxis *Q3DScatter::axisY() const
+{
+ return static_cast<Q3DValueAxis *>(d_ptr->m_shared->axisY());
+}
+
+/*!
+ * Sets a user-defined Z-axis. Implicitly calls addAxis() to transfer ownership
+ * of the \a axis to this graph.
+ *
+ * If the \a axis is null, a temporary default axis with no labels and automatically adjusting
+ * range is created.
+ * This temporary axis is destroyed if another \a axis is explicitly set to same orientation.
+ *
+ * \sa addAxis(), releaseAxis()
+ */
+void Q3DScatter::setAxisZ(Q3DValueAxis *axis)
+{
+ d_ptr->m_shared->setAxisZ(axis);
+}
+
+/*!
+ * \return used Z-axis.
+ */
+Q3DValueAxis *Q3DScatter::axisZ() const
+{
+ return static_cast<Q3DValueAxis *>(d_ptr->m_shared->axisZ());
+}
+
+/*!
+ * Adds \a axis to the graph. The axes added via addAxis are not yet taken to use,
+ * addAxis is simply used to give the ownership of the \a axis to the graph.
+ * The \a axis must not be null or added to another graph.
+ *
+ * \sa releaseAxis(), setAxisX(), setAxisY(), setAxisZ()
+ */
+void Q3DScatter::addAxis(Q3DValueAxis *axis)
+{
+ d_ptr->m_shared->addAxis(axis);
+}
+
+/*!
+ * Releases the ownership of the \a axis back to the caller, if it is added to this graph.
+ * If the released \a axis is in use, a new default axis will be created and set active.
+ *
+ * If the default axis is released and added back later, it behaves as any other axis would.
+ *
+ * \sa addAxis(), setAxisX(), setAxisY(), setAxisZ()
+ */
+void Q3DScatter::releaseAxis(Q3DValueAxis *axis)
+{
+ d_ptr->m_shared->releaseAxis(axis);
+}
+
+/*!
+ * \return list of all added axes.
+ *
+ * \sa addAxis()
+ */
+QList<Q3DValueAxis *> Q3DScatter::axes() const
+{
+ QList<Q3DAbstractAxis *> abstractAxes = d_ptr->m_shared->axes();
+ QList<Q3DValueAxis *> retList;
+ foreach (Q3DAbstractAxis *axis, abstractAxes)
+ retList.append(static_cast<Q3DValueAxis *>(axis));
+
+ return retList;
+}
+
+/*!
+ * Sets the active data \a proxy. Implicitly calls addDataProxy() to transfer ownership of
+ * the \a proxy to this graph.
+ *
+ * If the \a proxy is null, a temporary default proxy is created and activated.
+ * This temporary proxy is destroyed if another \a proxy is explicitly set active via this method.
+ *
+ * \sa addDataProxy(), releaseDataProxy()
+ */
+void Q3DScatter::setActiveDataProxy(QScatterDataProxy *proxy)
+{
+ d_ptr->m_shared->setActiveDataProxy(proxy);
+}
+
+/*!
+ * \return active data proxy.
+ */
+QScatterDataProxy *Q3DScatter::activeDataProxy() const
+{
+ return static_cast<QScatterDataProxy *>(d_ptr->m_shared->activeDataProxy());
+}
+
+/*!
+ * Adds data \a proxy to the graph. The proxies added via addDataProxy are not yet taken to use,
+ * addDataProxy is simply used to give the ownership of the data \a proxy to the graph.
+ * The \a proxy must not be null or added to another graph.
+ *
+ * \sa releaseDataProxy(), setActiveDataProxy()
+ */
+void Q3DScatter::addDataProxy(QScatterDataProxy *proxy)
+{
+ d_ptr->m_shared->addDataProxy(proxy);
+}
+
+/*!
+ * Releases the ownership of the data \a proxy back to the caller, if it is added to this graph.
+ * If the released \a proxy is in use, a new empty default proxy is created and taken to use.
+ *
+ * If the default \a proxy is released and added back later, it behaves as any other proxy would.
+ *
+ * \sa addDataProxy(), setActiveDataProxy()
+ */
+void Q3DScatter::releaseDataProxy(QScatterDataProxy *proxy)
+{
+ d_ptr->m_shared->releaseDataProxy(proxy);
+}
+
+/*!
+ * \return list of all added data proxies.
+ *
+ * \sa addDataProxy()
+ */
+QList<QScatterDataProxy *> Q3DScatter::dataProxies() const
+{
+ QList<QScatterDataProxy *> retList;
+ QList<QAbstractDataProxy *> abstractList = d_ptr->m_shared->dataProxies();
+ foreach (QAbstractDataProxy *proxy, abstractList)
+ retList.append(static_cast<QScatterDataProxy *>(proxy));
+
+ return retList;
+}
+
+/*!
+ * \fn void Q3DScatter::shadowQualityChanged(QDataVis::ShadowQuality quality)
+ *
+ * This signal is emitted when shadow \a quality changes.
+ */
+
+Q3DScatterPrivate::Q3DScatterPrivate(Q3DScatter *q, QRect rect)
+ : q_ptr(q),
+ m_shared(new Scatter3DController(rect))
+{
+ QObject::connect(m_shared, &Abstract3DController::shadowQualityChanged, this,
+ &Q3DScatterPrivate::handleShadowQualityUpdate);
+}
+
+Q3DScatterPrivate::~Q3DScatterPrivate()
+{
+ qDebug() << "Destroying Q3DScatterPrivate";
+ delete m_shared;
+}
+
+void Q3DScatterPrivate::handleShadowQualityUpdate(QDataVis::ShadowQuality quality)
+{
+ emit q_ptr->shadowQualityChanged(quality);
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
diff --git a/src/datavisualization/engine/q3dscatter.h b/src/datavisualization/engine/q3dscatter.h
new file mode 100644
index 00000000..fdea604e
--- /dev/null
+++ b/src/datavisualization/engine/q3dscatter.h
@@ -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 QtDataVisualization 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 <QtDataVisualization/qdatavisualizationenums.h>
+#include <QtDataVisualization/q3dwindow.h>
+#include <QtDataVisualization/q3dscene.h>
+#include <QFont>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class Q3DScatterPrivate;
+class LabelItem;
+class Q3DValueAxis;
+class Q3DCategoryAxis;
+class QScatterDataProxy;
+
+class QT_DATAVISUALIZATION_EXPORT Q3DScatter : public Q3DWindow
+{
+ Q_OBJECT
+ Q_PROPERTY(QtDataVisualization::QDataVis::SelectionMode selectionMode READ selectionMode WRITE setSelectionMode)
+ Q_PROPERTY(QtDataVisualization::QDataVis::LabelStyle labelStyle READ labelStyle WRITE setLabelStyle)
+ Q_PROPERTY(QtDataVisualization::QDataVis::ShadowQuality shadowQuality READ shadowQuality WRITE setShadowQuality)
+ Q_PROPERTY(QString meshFileName READ meshFileName WRITE setMeshFileName)
+ Q_PROPERTY(QFont font READ font WRITE setFont)
+ Q_PROPERTY(bool gridVisible READ isGridVisible WRITE setGridVisible)
+ Q_PROPERTY(bool backgroundVisible READ isBackgroundVisible WRITE setBackgroundVisible)
+ Q_PROPERTY(int selectedItemIndex READ selectedItemIndex WRITE setSelectedItemIndex NOTIFY selectedItemIndexChanged)
+ Q_PROPERTY(Q3DScene* scene READ scene)
+ Q_ENUMS(QtDataVisualization::QDataVis::SelectionMode)
+ Q_ENUMS(QtDataVisualization::QDataVis::ShadowQuality)
+ Q_ENUMS(QtDataVisualization::QDataVis::LabelStyle)
+ Q_ENUMS(QtDataVisualization::QDataVis::CameraPreset)
+
+public:
+ explicit Q3DScatter();
+ ~Q3DScatter();
+
+ void setObjectType(QDataVis::MeshStyle style, bool smooth = false);
+
+ void setTheme(QDataVis::Theme theme);
+
+ void setObjectColor(const QColor &baseColor, bool uniform = true);
+ QColor objectColor() const;
+
+ void setMeshFileName(const QString &objFileName);
+ QString meshFileName() const;
+
+ void setSelectionMode(QDataVis::SelectionMode mode);
+ QDataVis::SelectionMode selectionMode() const;
+
+ void setFont(const QFont &font);
+ QFont font() const;
+
+ Q3DScene *scene() const;
+
+ void setLabelStyle(QDataVis::LabelStyle style);
+ QDataVis::LabelStyle labelStyle() const;
+
+ void setGridVisible(bool visible);
+ bool isGridVisible() const;
+
+ void setWidth(const int width);
+ void setHeight(const int height);
+
+ void setBackgroundVisible(bool visible);
+ bool isBackgroundVisible() const;
+
+ void setSelectedItemIndex(int index);
+ int selectedItemIndex() const;
+
+ void setShadowQuality(QDataVis::ShadowQuality quality);
+ QDataVis::ShadowQuality shadowQuality() const;
+
+ void setAxisX(Q3DValueAxis *axis);
+ Q3DValueAxis *axisX() const;
+ void setAxisY(Q3DValueAxis *axis);
+ Q3DValueAxis *axisY() const;
+ void setAxisZ(Q3DValueAxis *axis);
+ Q3DValueAxis *axisZ() const;
+ void addAxis(Q3DValueAxis *axis);
+ void releaseAxis(Q3DValueAxis *axis);
+ QList<Q3DValueAxis *> axes() const;
+
+ void setActiveDataProxy(QScatterDataProxy *proxy);
+ QScatterDataProxy *activeDataProxy() const;
+ void addDataProxy(QScatterDataProxy *proxy);
+ void releaseDataProxy(QScatterDataProxy *proxy);
+ QList<QScatterDataProxy *> dataProxies() const;
+
+signals:
+ void shadowQualityChanged(QDataVis::ShadowQuality quality);
+ void selectedItemIndexChanged(int index);
+
+protected:
+ void mouseDoubleClickEvent(QMouseEvent *event);
+ void touchEvent(QTouchEvent *event);
+ 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_DATAVISUALIZATION_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3d/engine/q3dscatter_p.h b/src/datavisualization/engine/q3dscatter_p.h
index ab2e2b06..775344d0 100644
--- a/src/datavis3d/engine/q3dscatter_p.h
+++ b/src/datavisualization/engine/q3dscatter_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -30,9 +30,9 @@
#define Q3DSCATTER_p_H
#include "scatter3dcontroller_p.h"
-#include "qdatavis3denums.h"
+#include "qdatavisualizationenums.h"
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
class Q3DScatter;
@@ -42,10 +42,13 @@ public:
Q3DScatterPrivate(Q3DScatter *q, QRect rect);
~Q3DScatterPrivate();
+ // Used to detect when shadow quality changes autonomously due to e.g. resizing.
+ void handleShadowQualityUpdate(QDataVis::ShadowQuality quality);
+
Q3DScatter *q_ptr;
Scatter3DController *m_shared;
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif
diff --git a/src/datavisualization/engine/q3dscene.cpp b/src/datavisualization/engine/q3dscene.cpp
new file mode 100644
index 00000000..4908bde4
--- /dev/null
+++ b/src/datavisualization/engine/q3dscene.cpp
@@ -0,0 +1,375 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 <qmath.h>
+
+#include "datavisualizationglobal_p.h"
+
+#include "q3dscene.h"
+#include "q3dscene_p.h"
+#include "q3dcamera_p.h"
+#include "q3dlight_p.h"
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+/*!
+ * \class Q3DScene
+ * \inmodule QtDataVisualization
+ * \brief Q3DScene class provides description of the 3D scene being visualized.
+ * \since 1.0.0
+ *
+ * The 3D scene contains a single active camera and a single active light source.
+ * Visualized data is assumed to be at a fixed location.
+ *
+ * The 3D scene also keeps track of the viewport in which visualization rendering is done,
+ * the primary subviewport inside the viewport where the main 3D data visualization view resides
+ * and the secondary subviewport where the 2D sliced view of the data resides.
+ *
+ * Also the scene has flag for tracking if the secondary 2D slicing view is currently active or not.
+ * \note Not all visualizations support the secondary 2D slicing view.
+ */
+
+/*!
+ * Constructs a basic scene with one light and one camera in it. An
+ * optional \a parent parameter can be given and is then passed to QObject constructor.
+ */
+Q3DScene::Q3DScene(QObject *parent) :
+ QObject(parent),
+ d_ptr(new Q3DScenePrivate(this))
+{
+ setActiveCamera(new Q3DCamera(0));
+ setActiveLight(new Q3DLight(0));
+}
+
+/*!
+ * Destroys the 3D scene and all the objects contained within it.
+ */
+Q3DScene::~Q3DScene()
+{
+}
+
+/*!
+ * \property Q3DScene::viewport
+ *
+ * This property contains the current viewport rectangle where all 3D rendering
+ * is targeted.
+ */
+QRect Q3DScene::viewport() const
+{
+ return d_ptr->m_viewport;
+}
+
+void Q3DScene::setViewport(const QRect &viewport)
+{
+ if (d_ptr->m_viewport.width() != viewport.width()
+ || d_ptr->m_viewport.height() != viewport.height()) {
+ d_ptr->m_viewport = viewport;
+ d_ptr->m_viewport.setX(0);
+ d_ptr->m_viewport.setY(0);
+ d_ptr->m_changeTracker.viewportChanged = true;
+ emit viewportChanged(viewport);
+ }
+}
+
+/*!
+ * Sets the \a width and \a height of the viewport only, without changing its location.
+ */
+void Q3DScene::setViewportSize(int width, int height)
+{
+ if (d_ptr->m_viewport.width() != width
+ || d_ptr->m_viewport.height() != height) {
+ d_ptr->m_viewport.setWidth(width);
+ d_ptr->m_viewport.setHeight(height);
+ d_ptr->m_changeTracker.viewportChanged = true;
+ emit viewportChanged(d_ptr->m_viewport);
+ }
+}
+
+/*!
+ * \property Q3DScene::primarySubViewport
+ *
+ * This property contains the current main viewport rectangle inside the viewport where the
+ * primary view of the data visualization is targeted to.
+ */
+QRect Q3DScene::primarySubViewport() const
+{
+ return d_ptr->m_primarySubViewport;
+}
+
+void Q3DScene::setPrimarySubViewport(const QRect &primarySubViewport)
+{
+ if (d_ptr->m_primarySubViewport != primarySubViewport) {
+ d_ptr->m_primarySubViewport = primarySubViewport;
+ d_ptr->m_changeTracker.primarySubViewportChanged = true;
+ emit primarySubViewportChanged(primarySubViewport);
+ }
+}
+
+/*!
+ * Returns whether the given \a point resides inside the primary subview or not.
+ * The method takes care of correctly mapping between OpenGL coordinates used in the
+ * viewport definitions and the Qt event coordinate system used in the input system.
+ * \return true if the point is inside the primary subview.
+ */
+bool Q3DScene::isPointInPrimarySubView(const QPoint &point)
+{
+ // TODO: Needs fixing. Doesn't respect whether slice or main view is on top or if slicing is even activated currently.
+ int x = point.x();
+ int y = point.y();
+ int areaMinX = d_ptr->m_primarySubViewport.x();
+ int areaMaxX = d_ptr->m_primarySubViewport.x() + d_ptr->m_primarySubViewport.width();
+ int areaMaxY = d_ptr->m_viewport.height() - d_ptr->m_primarySubViewport.y();
+ int areaMinY = d_ptr->m_viewport.height() - (d_ptr->m_primarySubViewport.y() + d_ptr->m_primarySubViewport.height());
+
+ return ( x > areaMinX && x < areaMaxX && y > areaMinY && y < areaMaxY );
+}
+
+/*!
+ * Returns whether the given \a point resides inside the secondary subview or not.
+ * The method takes care of correctly mapping between OpenGL coordinates used in the
+ * viewport definitions and the Qt event coordinate system used in the input system.
+ * \return true if the point is inside the secondary subview.
+ */
+bool Q3DScene::isPointInSecondarySubView(const QPoint &point)
+{
+ // TODO: Needs fixing. Doesn't respect whether slice or main view is on top or if slicing is even activated currently.
+ int x = point.x();
+ int y = point.y();
+ int areaMinX = d_ptr->m_secondarySubViewport.x();
+ int areaMaxX = d_ptr->m_secondarySubViewport.x() + d_ptr->m_secondarySubViewport.width();
+ int areaMaxY = d_ptr->m_viewport.height() - d_ptr->m_secondarySubViewport.y();
+ int areaMinY = d_ptr->m_viewport.height() - (d_ptr->m_secondarySubViewport.y() + d_ptr->m_secondarySubViewport.height());
+
+ return ( x > areaMinX && x < areaMaxX && y > areaMinY && y < areaMaxY );
+}
+
+/*!
+ * \property Q3DScene::secondarySubViewport
+ *
+ * This property contains the secondary viewport rectangle inside the viewport. The secondary
+ * viewport is used for drawing the 2D slice view in some visualizations.
+ */
+QRect Q3DScene::secondarySubViewport() const
+{
+ return d_ptr->m_secondarySubViewport;
+}
+
+void Q3DScene::setSecondarySubViewport(const QRect &secondarySubViewport)
+{
+ if (d_ptr->m_secondarySubViewport != secondarySubViewport) {
+ d_ptr->m_secondarySubViewport = secondarySubViewport;
+ d_ptr->m_changeTracker.secondarySubViewportChanged = true;
+ emit secondarySubViewportChanged(secondarySubViewport);
+ }
+}
+
+/*!
+ * \property Q3DScene::slicingActive
+ *
+ * This property contains whether 2D slicing view is currently active or not.
+ * \note Not all visualizations support the 2D slicing view.
+ */
+bool Q3DScene::isSlicingActive() const
+{
+ return d_ptr->m_isSlicingActive;
+}
+
+void Q3DScene::setSlicingActive(bool isSlicing)
+{
+ if (d_ptr->m_isSlicingActive != isSlicing) {
+ d_ptr->m_isSlicingActive = isSlicing;
+ d_ptr->m_changeTracker.slicingActivatedChanged = true;
+ emit slicingActiveChanged(isSlicing);
+ emitNeedRender();
+ }
+}
+
+/*!
+ * \property Q3DScene::activeCamera
+ *
+ * This property contains the currently active camera in the 3D scene.
+ * When a new Q3DCamera objects is set in the property it gets automatically added as child of the scene.
+ */
+Q3DCamera *Q3DScene::activeCamera() const
+{
+ return d_ptr->m_camera;
+}
+
+void Q3DScene::setActiveCamera(Q3DCamera *camera)
+{
+ Q_ASSERT(camera);
+
+ // Add new camera as child of the scene
+ if (camera->parent() != this)
+ camera->setParent(this);
+
+ if (camera != d_ptr->m_camera) {
+ if (d_ptr->m_camera) {
+ disconnect(d_ptr->m_camera, &Q3DCamera::xRotationChanged, this,
+ &Q3DScene::emitNeedRender);
+ disconnect(d_ptr->m_camera, &Q3DCamera::yRotationChanged, this,
+ &Q3DScene::emitNeedRender);
+ }
+
+ d_ptr->m_camera = camera;
+ d_ptr->m_changeTracker.cameraChanged = true;
+
+ if (camera) {
+ connect(camera, &Q3DCamera::xRotationChanged, this,
+ &Q3DScene::emitNeedRender);
+ connect(camera, &Q3DCamera::yRotationChanged, this,
+ &Q3DScene::emitNeedRender);
+ }
+
+ emit activeCameraChanged(camera);
+ emitNeedRender();
+ }
+}
+
+void Q3DScene::emitNeedRender()
+{
+ emit needRender();
+}
+
+/*!
+ * \property Q3DScene::activeLight
+ *
+ * This property contains the currently active light in the 3D scene.
+ * When a new Q3DLight objects is set in the property it gets automatically added as child of the scene.
+ */
+Q3DLight *Q3DScene::activeLight() const
+{
+ return d_ptr->m_light;
+}
+
+void Q3DScene::setActiveLight(Q3DLight *light)
+{
+ Q_ASSERT(light);
+
+ // Add new light as child of the scene
+ if (light->parent() != this)
+ light->setParent(this);
+
+ if (light != d_ptr->m_light) {
+ d_ptr->m_light = light;
+ d_ptr->m_changeTracker.lightChanged = true;
+ emit activeLightChanged(light);
+ }
+}
+
+/*!
+ * \property Q3DScene::devicePixelRatio
+ *
+ * This property contains the current device pixel ratio that is used when mapping input
+ * coordinates to pixel coordinates.
+ */
+qreal Q3DScene::devicePixelRatio() const
+{
+ return d_ptr->m_devicePixelRatio;
+}
+
+void Q3DScene::setDevicePixelRatio(qreal pixelRatio)
+{
+ if (d_ptr->m_devicePixelRatio != pixelRatio) {
+ d_ptr->m_devicePixelRatio = pixelRatio;
+ emit devicePixelRatioChanged(pixelRatio);
+ }
+}
+
+/*!
+ * Calculates and sets the light position relative to the currently active camera using the given parameters.
+ * \a relativePosition defines the relative 3D offset to the current camera position.
+ * Optional \a fixedRotation fixes the light rotation around the data visualization area to the given value in degrees.
+ * Optional \a distanceModifier modifies the distance of the light from the data visualization.
+ */
+void Q3DScene::setLightPositionRelativeToCamera(const QVector3D &relativePosition,
+ qreal fixedRotation, qreal distanceModifier)
+{
+ d_ptr->m_light->setPosition(
+ d_ptr->m_camera->calculatePositionRelativeToCamera(relativePosition,
+ fixedRotation,
+ distanceModifier));
+}
+
+/*!
+ * \fn Q3DScene::needRender()
+ * \internal
+ */
+
+Q3DScenePrivate::Q3DScenePrivate(Q3DScene *q) :
+ q_ptr(q),
+ m_devicePixelRatio(1.f),
+ m_camera(),
+ m_light(),
+ m_isUnderSideCameraEnabled(false),
+ m_isSlicingActive(false)
+{
+}
+
+Q3DScenePrivate::~Q3DScenePrivate()
+{
+ delete m_camera;
+ delete m_light;
+}
+
+// Copies changed values from this scene to the other scene. If the other scene had same changes,
+// those changes are discarded.
+void Q3DScenePrivate::sync(Q3DScenePrivate &other)
+{
+ if (m_changeTracker.viewportChanged) {
+ other.q_ptr->setViewport(q_ptr->viewport());
+ m_changeTracker.viewportChanged = false;
+ other.m_changeTracker.viewportChanged = false;
+ }
+ if (m_changeTracker.primarySubViewportChanged) {
+ other.q_ptr->setPrimarySubViewport(q_ptr->primarySubViewport());
+ m_changeTracker.primarySubViewportChanged = false;
+ other.m_changeTracker.primarySubViewportChanged = false;
+ }
+ if (m_changeTracker.secondarySubViewportChanged) {
+ other.q_ptr->setSecondarySubViewport(q_ptr->secondarySubViewport());
+ m_changeTracker.secondarySubViewportChanged = false;
+ other.m_changeTracker.secondarySubViewportChanged = false;
+ }
+ if (m_changeTracker.cameraChanged) {
+ m_camera->setDirty(true);
+ m_changeTracker.cameraChanged = false;
+ other.m_changeTracker.cameraChanged = false;
+ }
+ m_camera->d_ptr->sync(*other.m_camera);
+
+ if (m_changeTracker.lightChanged) {
+ m_light->setDirty(true);
+ m_changeTracker.lightChanged = false;
+ other.m_changeTracker.lightChanged = false;
+ }
+ m_light->d_ptr->sync(*other.m_light);
+
+ if (m_changeTracker.slicingActivatedChanged) {
+ other.q_ptr->setSlicingActive(q_ptr->isSlicingActive());
+ m_changeTracker.slicingActivatedChanged = false;
+ other.m_changeTracker.slicingActivatedChanged = false;
+ }
+
+ if (m_changeTracker.devicePixelRatioChanged) {
+ other.q_ptr->setDevicePixelRatio(q_ptr->devicePixelRatio());
+ m_changeTracker.devicePixelRatioChanged = false;
+ other.m_changeTracker.devicePixelRatioChanged = false;
+ }
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualization/engine/q3dscene.h b/src/datavisualization/engine/q3dscene.h
new file mode 100644
index 00000000..745cef72
--- /dev/null
+++ b/src/datavisualization/engine/q3dscene.h
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 Q3DSCENE_H
+#define Q3DSCENE_H
+
+#include <QtDataVisualization/qdatavisualizationenums.h>
+#include <QObject>
+#include <QRect>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class Q3DCamera;
+class Q3DBox;
+class Q3DLight;
+class Q3DScenePrivate;
+
+class QT_DATAVISUALIZATION_EXPORT Q3DScene : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QRect viewport READ viewport WRITE setViewport NOTIFY viewportChanged)
+ Q_PROPERTY(QRect primarySubViewport READ primarySubViewport WRITE setPrimarySubViewport NOTIFY primarySubViewportChanged)
+ Q_PROPERTY(QRect secondarySubViewport READ secondarySubViewport WRITE setSecondarySubViewport NOTIFY secondarySubViewportChanged)
+ Q_PROPERTY(bool slicingActive READ isSlicingActive WRITE setSlicingActive NOTIFY slicingActiveChanged)
+ Q_PROPERTY(Q3DCamera* activeCamera READ activeCamera WRITE setActiveCamera NOTIFY activeCameraChanged)
+ Q_PROPERTY(Q3DLight* activeLight READ activeLight WRITE setActiveLight NOTIFY activeLightChanged)
+ Q_PROPERTY(qreal devicePixelRatio READ devicePixelRatio WRITE setDevicePixelRatio NOTIFY devicePixelRatioChanged)
+
+public:
+ Q3DScene(QObject *parent = 0);
+ ~Q3DScene();
+
+ QRect viewport() const;
+ void setViewport(const QRect &viewport);
+ void setViewportSize(int width, int height);
+
+ QRect primarySubViewport() const;
+ void setPrimarySubViewport(const QRect &primarySubViewport);
+ bool isPointInPrimarySubView(const QPoint &point);
+
+ QRect secondarySubViewport() const;
+ void setSecondarySubViewport(const QRect &secondarySubViewport);
+ bool isPointInSecondarySubView(const QPoint &point);
+
+ void setSlicingActive(bool isSlicing);
+ bool isSlicingActive() const;
+
+ Q3DCamera *activeCamera() const;
+ void setActiveCamera(Q3DCamera *camera);
+
+ Q3DLight *activeLight() const;
+ void setActiveLight(Q3DLight *light);
+
+ qreal devicePixelRatio() const;
+ void setDevicePixelRatio(qreal pixelRatio);
+
+ void setLightPositionRelativeToCamera(const QVector3D &relativePosition,
+ qreal fixedRotation = 0.0,
+ qreal distanceModifier = 0.0);
+private:
+ void emitNeedRender();
+
+signals:
+ void viewportChanged(QRect viewport);
+ void primarySubViewportChanged(QRect subViewport);
+ void secondarySubViewportChanged(QRect subViewport);
+ void slicingActiveChanged(bool isSlicingActive);
+ void activeCameraChanged(const Q3DCamera *camera);
+ void activeLightChanged(const Q3DLight *light);
+ void devicePixelRatioChanged(qreal pixelRatio);
+ void needRender();
+
+private:
+ QScopedPointer<Q3DScenePrivate> d_ptr;
+
+ Q_DISABLE_COPY(Q3DScene)
+
+ friend class Q3DScenePrivate;
+ friend class Abstract3DRenderer;
+ friend class Bars3DRenderer;
+ friend class Surface3DRenderer;
+ friend class Scatter3DRenderer;
+ friend class Q3DCameraPrivate;
+};
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
+#endif // Q3DSCENE_H
diff --git a/src/datavisualization/engine/q3dscene_p.h b/src/datavisualization/engine/q3dscene_p.h
new file mode 100644
index 00000000..b28baaae
--- /dev/null
+++ b/src/datavisualization/engine/q3dscene_p.h
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 QtDataVisualization 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 Q3DSCENE_P_H
+#define Q3DSCENE_P_H
+
+#include "datavisualizationglobal_p.h"
+#include <QRect>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class Q3DCamera;
+class Q3DLight;
+class Q3DScene;
+
+struct Q3DSceneChangeBitField {
+ bool viewportChanged : 1;
+ bool primarySubViewportChanged : 1;
+ bool secondarySubViewportChanged : 1;
+ bool cameraChanged : 1;
+ bool lightChanged : 1;
+ bool slicingActivatedChanged : 1;
+ bool devicePixelRatioChanged : 1;
+
+ Q3DSceneChangeBitField()
+ : viewportChanged(true),
+ primarySubViewportChanged(true),
+ secondarySubViewportChanged(true),
+ cameraChanged(true),
+ lightChanged(true),
+ slicingActivatedChanged(true),
+ devicePixelRatioChanged(true)
+ {
+ }
+};
+
+class Q3DScenePrivate
+{
+public:
+ Q3DScenePrivate(Q3DScene *q);
+ ~Q3DScenePrivate();
+
+ void sync(Q3DScenePrivate &other);
+
+ Q3DScene *q_ptr;
+ Q3DSceneChangeBitField m_changeTracker;
+
+ QRect m_viewport;
+ QRect m_primarySubViewport;
+ QRect m_secondarySubViewport;
+ qreal m_devicePixelRatio;
+ Q3DCamera *m_camera;
+ Q3DLight *m_light;
+ bool m_isUnderSideCameraEnabled;
+ bool m_isSlicingActive;
+};
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
+#endif // Q3DSCENE_P_H
diff --git a/src/datavisualization/engine/q3dsurface.cpp b/src/datavisualization/engine/q3dsurface.cpp
new file mode 100644
index 00000000..7990f362
--- /dev/null
+++ b/src/datavisualization/engine/q3dsurface.cpp
@@ -0,0 +1,542 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 "q3dvalueaxis.h"
+#include "qsurfacedataproxy.h"
+#include "q3dcamera.h"
+
+#include <QMouseEvent>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+/*!
+ * \class Q3DSurface
+ * \inmodule QtDataVisualization
+ * \brief The Q3DSurface class provides methods for rendering 3D surface plots.
+ * \since 1.0.0
+ *
+ * This class enables developers to render 3D surface plots and to view them by rotating the scene
+ * freely. The class provides configurable gradient texture to illustrate the height on the data. The
+ * surface plotting includes also gridline that can be set on or off. The visual appearance of the
+ * surface can be changed by controlling the smooth status.
+ *
+ * The Q3DSurface supports selection by showing a highlighted ball on the data point where the user has clicked
+ * with left mouse button (when default input handler is in use). The selection pointer is accompanied with
+ * a label which in default case shows the value of the data point and the coordinates of the point.
+ *
+ * The value range and the label format shown on the axis can be controlled through Q3DValueAxis.
+ * The Q3DSurface supports only a grid with fixed steps, so when setting ranges set a value that matches
+ * the grid step. To calculate the steps divide the whole data range with the number of segments.
+ *
+ * To rotate the graph, hold down the right mouse button and move the mouse. Zooming is done using mouse
+ * wheel. Both assume the default input handler is in use.
+ *
+ * If no axes are explicitly set to Q3DSurface, temporary default axes with no labels are created.
+ * These default axes can be modified via axis accessors, but as soon any axis is explicitly
+ * set for the orientation, the default axis for that orientation is destroyed.
+ *
+ * Data proxies work similarly: If no data proxy is explicitly set, Q3DSurface creates a default
+ * proxy. If any other proxy is set as active data proxy later, the default proxy and all data
+ * added to it is destroyed.
+ *
+ * \section1 How to construct a minimal Q3DSurface graph
+ *
+ * First, construct Q3DSurface:
+ *
+ * \snippet doc_src_q3dsurface_construction.cpp 0
+ *
+ * Now Q3DSurface is ready to receive data to be rendered. Create data elements to receive values:
+ *
+ * \snippet doc_src_q3dsurface_construction.cpp 1
+ *
+ * First feed the data to the row element and then add it's pointer to the data element:
+ *
+ * \snippet doc_src_q3dsurface_construction.cpp 2
+ *
+ * For the active data proxy set pointer of the data element:
+ *
+ * \snippet doc_src_q3dsurface_construction.cpp 3
+ *
+ * Finally you will need to set it visible:
+ *
+ * \snippet doc_src_q3dsurface_construction.cpp 4
+ *
+ * The complete code needed to create and display this graph is:
+ *
+ * \snippet doc_src_q3dsurface_construction.cpp 5
+ *
+ * And this is what those few lines of code produce:
+ *
+ * \image q3dsurface-minimal.png
+ *
+ * The scene can be rotated and zoomed into, but no other interaction is included in this minimal
+ * code example.
+ *
+ *
+ * \sa Q3DBars, Q3DScatter, {Qt Data Visualization C++ Classes}
+ */
+
+/*!
+ * Constructs a new 3D surface window.
+ */
+Q3DSurface::Q3DSurface()
+ : d_ptr(new Q3DSurfacePrivate(this, geometry()))
+{
+ setVisualController(d_ptr->m_shared);
+ d_ptr->m_shared->initializeOpenGL();
+ QObject::connect(d_ptr->m_shared, &Abstract3DController::needRender, this,
+ &Q3DWindow::renderLater);
+}
+
+/*!
+ * Destroys the 3D surface window.
+ */
+Q3DSurface::~Q3DSurface()
+{
+}
+
+/*!
+ * \internal
+ */
+void Q3DSurface::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ d_ptr->m_shared->mouseDoubleClickEvent(event);
+}
+
+/*!
+ * \internal
+ */
+void Q3DSurface::touchEvent(QTouchEvent *event)
+{
+ d_ptr->m_shared->touchEvent(event);
+}
+
+/*!
+ * \internal
+ */
+void Q3DSurface::mousePressEvent(QMouseEvent *event)
+{
+ d_ptr->m_shared->mousePressEvent(event, event->pos());
+}
+
+/*!
+ * \internal
+ */
+void Q3DSurface::mouseReleaseEvent(QMouseEvent *event)
+{
+ d_ptr->m_shared->mouseReleaseEvent(event, event->pos());
+}
+
+/*!
+ * \internal
+ */
+void Q3DSurface::mouseMoveEvent(QMouseEvent *event)
+{
+ d_ptr->m_shared->mouseMoveEvent(event, event->pos());
+}
+
+/*!
+ * \internal
+ */
+void Q3DSurface::wheelEvent(QWheelEvent *event)
+{
+ d_ptr->m_shared->wheelEvent(event);
+}
+
+/*!
+ * \internal
+ */
+void Q3DSurface::resizeEvent(QResizeEvent *event)
+{
+ Q_UNUSED(event);
+ d_ptr->m_shared->setWidth(width());
+ d_ptr->m_shared->setHeight(height());
+}
+
+/*!
+ * \property Q3DSurface::gridVisible
+ *
+ * Sets grid visibility to \a visible. It is preset to \c true by default.
+ */
+void Q3DSurface::setGridVisible(bool visible)
+{
+ d_ptr->m_shared->setGridEnabled(visible);
+}
+
+bool Q3DSurface::isGridVisible() const
+{
+ return d_ptr->m_shared->gridEnabled();
+}
+
+/*!
+ * \property Q3DSurface::backgroundVisible
+ *
+ * Sets background visibility to \a visible. It is preset to \c true by default.
+ */
+void Q3DSurface::setBackgroundVisible(bool visible)
+{
+ d_ptr->m_shared->setBackgroundEnabled(visible);
+}
+
+bool Q3DSurface::isBackgroundVisible() const
+{
+ return d_ptr->m_shared->backgroundEnabled();
+}
+
+/*!
+ * \property Q3DSurface::theme
+ *
+ * A predefined \a theme from \c QDataVis::Theme. It is preset to \c QDataVis::ThemeQt by
+ * default. Theme affects label colors, text color, background color, window color and
+ * grid color. Lighting is also adjusted by themes.
+ *
+ * \warning This property is subject to change.
+ */
+void Q3DSurface::setTheme(QDataVis::Theme theme)
+{
+ d_ptr->m_shared->setTheme(theme);
+}
+
+QDataVis::Theme Q3DSurface::theme() const
+{
+ return d_ptr->m_shared->theme().theme();
+}
+
+/*!
+ * \property Q3DSurface::shadowQuality
+ *
+ * Sets shadow \a quality to one of \c QDataVis::ShadowQuality. It is preset to
+ * \c QDataVis::ShadowQualityMedium by default.
+ *
+ * \note 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 Q3DSurface::setShadowQuality(QDataVis::ShadowQuality quality)
+{
+ return d_ptr->m_shared->setShadowQuality(quality);
+}
+
+QDataVis::ShadowQuality Q3DSurface::shadowQuality() const
+{
+ return d_ptr->m_shared->shadowQuality();
+}
+
+/*!
+ * \property Q3DSurface::smoothSurfaceEnabled
+ *
+ * Sets surface smoothing to \a enabled. It is preset to \c false by default.
+ * When enabled the normals on the surface are interpolated making edges looking round. If turned
+ * off the normals are kept same on a triangle making the color of the triangle solid. This makes
+ * the data more readable from the model.
+ */
+void Q3DSurface::setSmoothSurfaceEnabled(bool enabled)
+{
+ d_ptr->m_shared->setSmoothSurface(enabled);
+}
+
+bool Q3DSurface::isSmoothSurfaceEnabled() const
+{
+ return d_ptr->m_shared->smoothSurface();
+}
+
+/*!
+ * \property Q3DSurface::selectionMode
+ *
+ * Sets point selection \a mode to one of \c QDataVis::SelectionMode. Surface supports SelectionModeItem,
+ * SelectionModeSliceRow and SelectionModeSliceColumn. It is preset to \c QDataVis::SelectionModeItem by default.
+ */
+void Q3DSurface::setSelectionMode(QDataVis::SelectionMode mode)
+{
+ d_ptr->m_shared->setSelectionMode(mode);
+}
+
+QDataVis::SelectionMode Q3DSurface::selectionMode() const
+{
+ return d_ptr->m_shared->selectionMode();
+}
+
+
+/*!
+ * \property Q3DSurface::surfaceGridEnabled
+ *
+ * Sets surface grid to \a enabled. It is preset to \c true by default.
+ */
+void Q3DSurface::setSurfaceGridEnabled(bool enabled)
+{
+ d_ptr->m_shared->setSurfaceGrid(enabled);
+}
+
+bool Q3DSurface::isSurfaceGridEnabled() const
+{
+ return d_ptr->m_shared->surfaceGrid();
+}
+
+/*!
+ * \property Q3DSurface::gradient
+ *
+ * The current surface gradient. Setting this property replaces the previous gradient with
+ * the given \a gradient.
+ */
+void Q3DSurface::setGradient(const QLinearGradient &gradient)
+{
+ d_ptr->m_shared->setGradient(gradient);
+}
+
+QLinearGradient Q3DSurface::gradient() const
+{
+ return d_ptr->m_shared->gradient();
+}
+
+/*!
+ * \property Q3DSurface::font
+ *
+ * Sets the \a font for labels. It is preset to \c Arial by default.
+ */
+void Q3DSurface::setFont(const QFont &font)
+{
+ d_ptr->m_shared->setFont(font);
+}
+
+QFont Q3DSurface::font() const
+{
+ return d_ptr->m_shared->font();
+}
+
+/*!
+ * \property Q3DSurface::scene
+ *
+ * This property contains the read only Q3DScene that can be used to access e.g. camera object.
+ */
+Q3DScene *Q3DSurface::scene() const
+{
+ return d_ptr->m_shared->scene();
+}
+
+/*!
+ * \property Q3DSurface::labelStyle
+ *
+ * Sets label \a style to one of \c QDataVis::LabelStyle. It is preset to
+ * \c QDataVis::LabelStyleFromTheme by default.
+ */
+void Q3DSurface::setLabelStyle(QDataVis::LabelStyle style)
+{
+ d_ptr->m_shared->setLabelStyle(style);
+}
+
+QDataVis::LabelStyle Q3DSurface::labelStyle() const
+{
+ return d_ptr->m_shared->labelStyle();
+}
+
+/*!
+ * Sets a user-defined X-axis. Implicitly calls addAxis() to transfer ownership
+ * of the \a axis to this graph.
+ *
+ * If the \a axis is null, a temporary default axis with no labels and automatically adjusting
+ * range is created.
+ * This temporary axis is destroyed if another \a axis is explicitly set to same orientation.
+ *
+ * \sa addAxis(), releaseAxis()
+ */
+void Q3DSurface::setAxisX(Q3DValueAxis *axis)
+{
+ d_ptr->m_shared->setAxisX(axis);
+}
+
+/*!
+ * \return used X-axis.
+ */
+Q3DValueAxis *Q3DSurface::axisX() const
+{
+ return static_cast<Q3DValueAxis *>(d_ptr->m_shared->axisX());
+}
+
+/*!
+ * Sets a user-defined Y-axis. Implicitly calls addAxis() to transfer ownership
+ * of the \a axis to this graph.
+ *
+ * If the \a axis is null, a temporary default axis with no labels and automatically adjusting
+ * range is created.
+ * This temporary axis is destroyed if another \a axis is explicitly set to same orientation.
+ *
+ * \sa addAxis(), releaseAxis()
+ */
+void Q3DSurface::setAxisY(Q3DValueAxis *axis)
+{
+ d_ptr->m_shared->setAxisY(axis);
+}
+
+/*!
+ * \return used Y-axis.
+ */
+Q3DValueAxis *Q3DSurface::axisY() const
+{
+ return static_cast<Q3DValueAxis *>(d_ptr->m_shared->axisY());
+}
+
+/*!
+ * Sets a user-defined Z-axis. Implicitly calls addAxis() to transfer ownership
+ * of the \a axis to this graph.
+ *
+ * If the \a axis is null, a temporary default axis with no labels and automatically adjusting
+ * range is created.
+ * This temporary axis is destroyed if another \a axis is explicitly set to same orientation.
+ *
+ * \sa addAxis(), releaseAxis()
+ */
+void Q3DSurface::setAxisZ(Q3DValueAxis *axis)
+{
+ d_ptr->m_shared->setAxisZ(axis);
+}
+
+/*!
+ * \return used Z-axis.
+ */
+Q3DValueAxis *Q3DSurface::axisZ() const
+{
+ return static_cast<Q3DValueAxis *>(d_ptr->m_shared->axisZ());
+}
+
+/*!
+ * Adds \a axis to the graph. The axes added via addAxis are not yet taken to use,
+ * addAxis is simply used to give the ownership of the \a axis to the graph.
+ * The \a axis must not be null or added to another graph.
+ *
+ * \sa releaseAxis(), setAxisX(), setAxisY(), setAxisZ()
+ */
+void Q3DSurface::addAxis(Q3DValueAxis *axis)
+{
+ d_ptr->m_shared->addAxis(axis);
+}
+
+/*!
+ * Releases the ownership of the \a axis back to the caller, if it is added to this graph.
+ * If the released \a axis is in use, a new default axis will be created and set active.
+ *
+ * If the default axis is released and added back later, it behaves as any other axis would.
+ *
+ * \sa addAxis(), setAxisX(), setAxisY(), setAxisZ()
+ */
+void Q3DSurface::releaseAxis(Q3DValueAxis *axis)
+{
+ d_ptr->m_shared->releaseAxis(axis);
+}
+
+/*!
+ * \return list of all added axes.
+ *
+ * \sa addAxis()
+ */
+QList<Q3DValueAxis *> Q3DSurface::axes() const
+{
+ QList<Q3DAbstractAxis *> abstractAxes = d_ptr->m_shared->axes();
+ QList<Q3DValueAxis *> retList;
+ foreach (Q3DAbstractAxis *axis, abstractAxes)
+ retList.append(static_cast<Q3DValueAxis *>(axis));
+
+ return retList;
+}
+
+/*!
+ * Sets the active data \a proxy. Implicitly calls addDataProxy() to transfer ownership of
+ * the \a proxy to this graph.
+ *
+ * If the \a proxy is null, a temporary default proxy is created and activated.
+ * This temporary proxy is destroyed if another \a proxy is explicitly set active via this method.
+ *
+ * \sa addDataProxy(), releaseDataProxy()
+ */
+void Q3DSurface::setActiveDataProxy(QSurfaceDataProxy *proxy)
+{
+ d_ptr->m_shared->setActiveDataProxy(proxy);
+}
+
+/*!
+ * \return active data proxy.
+ */
+QSurfaceDataProxy *Q3DSurface::activeDataProxy() const
+{
+ return static_cast<QSurfaceDataProxy *>(d_ptr->m_shared->activeDataProxy());
+}
+
+/*!
+ * Adds data \a proxy to the graph. The proxies added via addDataProxy are not yet taken to use,
+ * addDataProxy is simply used to give the ownership of the data \a proxy to the graph.
+ * The \a proxy must not be null or added to another graph.
+ *
+ * \sa releaseDataProxy(), setActiveDataProxy()
+ */
+void Q3DSurface::addDataProxy(QSurfaceDataProxy *proxy)
+{
+ d_ptr->m_shared->addDataProxy(proxy);
+}
+
+/*!
+ * Releases the ownership of the data \a proxy back to the caller, if it is added to this graph.
+ * If the released \a proxy is in use, a new empty default proxy is created and taken to use.
+ *
+ * If the default \a proxy is released and added back later, it behaves as any other proxy would.
+ *
+ * \sa addDataProxy(), setActiveDataProxy()
+ */
+void Q3DSurface::releaseDataProxy(QSurfaceDataProxy *proxy)
+{
+ d_ptr->m_shared->releaseDataProxy(proxy);
+}
+
+/*!
+ * \return list of all added data proxies.
+ *
+ * \sa addDataProxy()
+ */
+QList<QSurfaceDataProxy *> Q3DSurface::dataProxies() const
+{
+ QList<QSurfaceDataProxy *> retList;
+ QList<QAbstractDataProxy *> abstractList = d_ptr->m_shared->dataProxies();
+ foreach (QAbstractDataProxy *proxy, abstractList)
+ retList.append(static_cast<QSurfaceDataProxy *>(proxy));
+
+ return retList;
+}
+
+
+/*!
+ * Modifies the current surface gradient. Sets gradient color to \a color at \a pos.
+ */
+void Q3DSurface::setGradientColorAt(qreal pos, const QColor &color)
+{
+ d_ptr->m_shared->setGradientColorAt(pos, color);
+}
+
+/////////////////// PRIVATE ///////////////////////////////////
+
+Q3DSurfacePrivate::Q3DSurfacePrivate(Q3DSurface *q, QRect rect)
+ : q_ptr(q),
+ m_shared(new Surface3DController(rect))
+{
+}
+
+Q3DSurfacePrivate::~Q3DSurfacePrivate()
+{
+ delete m_shared;
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualization/engine/q3dsurface.h b/src/datavisualization/engine/q3dsurface.h
new file mode 100644
index 00000000..1b572a36
--- /dev/null
+++ b/src/datavisualization/engine/q3dsurface.h
@@ -0,0 +1,123 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 <QtDataVisualization/qdatavisualizationenums.h>
+#include <QtDataVisualization/q3dwindow.h>
+#include <QtDataVisualization/q3dscene.h>
+#include <QFont>
+#include <QLinearGradient>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class Q3DSurfacePrivate;
+class Q3DValueAxis;
+class QSurfaceDataProxy;
+
+class QT_DATAVISUALIZATION_EXPORT Q3DSurface : public Q3DWindow
+{
+ Q_OBJECT
+ Q_PROPERTY(QtDataVisualization::QDataVis::SelectionMode selectionMode READ selectionMode WRITE setSelectionMode)
+ Q_PROPERTY(QtDataVisualization::QDataVis::LabelStyle labelStyle READ labelStyle WRITE setLabelStyle)
+ Q_PROPERTY(QtDataVisualization::QDataVis::Theme theme READ theme WRITE setTheme)
+ Q_PROPERTY(QtDataVisualization::QDataVis::ShadowQuality shadowQuality READ shadowQuality WRITE setShadowQuality)
+ Q_PROPERTY(bool gridVisible READ isGridVisible WRITE setGridVisible)
+ Q_PROPERTY(bool backgroundVisible READ isBackgroundVisible WRITE setBackgroundVisible)
+ Q_PROPERTY(bool smoothSurfaceEnabled READ isSmoothSurfaceEnabled WRITE setSmoothSurfaceEnabled)
+ Q_PROPERTY(bool surfaceGridEnabled READ isSurfaceGridEnabled WRITE setSurfaceGridEnabled)
+ Q_PROPERTY(QLinearGradient gradient READ gradient WRITE setGradient)
+ Q_PROPERTY(QFont font READ font WRITE setFont)
+ Q_PROPERTY(Q3DScene* scene READ scene)
+ Q_ENUMS(QtDataVisualization::QDataVis::SelectionMode)
+ Q_ENUMS(QtDataVisualization::QDataVis::ShadowQuality)
+ Q_ENUMS(QtDataVisualization::QDataVis::LabelStyle)
+ Q_ENUMS(QtDataVisualization::QDataVis::CameraPreset)
+
+public:
+ explicit Q3DSurface();
+ ~Q3DSurface();
+
+ void setGridVisible(bool visible);
+ bool isGridVisible() const;
+
+ void setBackgroundVisible(bool visible);
+ bool isBackgroundVisible() const;
+
+ void setTheme(QDataVis::Theme theme);
+ QDataVis::Theme theme() const;
+
+ void setShadowQuality(QDataVis::ShadowQuality quality);
+ QDataVis::ShadowQuality shadowQuality() const;
+
+ void setSmoothSurfaceEnabled(bool enabled);
+ bool isSmoothSurfaceEnabled() const;
+
+ void setSelectionMode(QDataVis::SelectionMode mode);
+ QDataVis::SelectionMode selectionMode() const;
+ void setSurfaceGridEnabled(bool enabled);
+ bool isSurfaceGridEnabled() const;
+
+ void setGradient(const QLinearGradient &gradient);
+ QLinearGradient gradient() const;
+
+ void setGradientColorAt(qreal pos, const QColor &color);
+
+ // Axes
+ void setAxisX(Q3DValueAxis *axis);
+ Q3DValueAxis *axisX() const;
+ void setAxisY(Q3DValueAxis *axis);
+ Q3DValueAxis *axisY() const;
+ void setAxisZ(Q3DValueAxis *axis);
+ Q3DValueAxis *axisZ() const;
+ void addAxis(Q3DValueAxis *axis);
+ void releaseAxis(Q3DValueAxis *axis);
+ QList<Q3DValueAxis *> axes() const;
+
+ void setActiveDataProxy(QSurfaceDataProxy *proxy);
+ QSurfaceDataProxy *activeDataProxy() const;
+ void addDataProxy(QSurfaceDataProxy *proxy);
+ void releaseDataProxy(QSurfaceDataProxy *proxy);
+ QList<QSurfaceDataProxy *> dataProxies() const;
+
+ void setFont(const QFont &font);
+ QFont font() const;
+
+ Q3DScene *scene() const;
+
+ void setLabelStyle(QDataVis::LabelStyle style);
+ QDataVis::LabelStyle labelStyle() const;
+
+protected:
+ void mouseDoubleClickEvent(QMouseEvent *event);
+ void touchEvent(QTouchEvent *event);
+ 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_DATAVISUALIZATION_END_NAMESPACE
+
+#endif // Q3DSURFACE_H
diff --git a/src/datavis3d/engine/q3dsurface_p.h b/src/datavisualization/engine/q3dsurface_p.h
index 1e132416..7c70d08c 100644
--- a/src/datavis3d/engine/q3dsurface_p.h
+++ b/src/datavisualization/engine/q3dsurface_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -30,11 +30,11 @@
#define Q3DSURFACE_P_H
#include "surface3dcontroller_p.h"
-#include "qdatavis3denums.h"
+#include "qdatavisualizationenums.h"
#include <QList>
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
class Q3DSurface;
@@ -44,19 +44,10 @@ 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
+ Surface3DController *m_shared;
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif // Q3DSURFACE_P_H
diff --git a/src/datavis3d/engine/q3dwindow.cpp b/src/datavisualization/engine/q3dwindow.cpp
index 5b2b70ab..9b607e1d 100644
--- a/src/datavis3d/engine/q3dwindow.cpp
+++ b/src/datavisualization/engine/q3dwindow.cpp
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -18,7 +18,7 @@
#include "q3dwindow.h"
#include "q3dwindow_p.h"
-
+#include "abstract3dcontroller_p.h"
#include <QGuiApplication>
#include <QOpenGLContext>
@@ -27,25 +27,23 @@
#include <QDebug>
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
/*!
* \class Q3DWindow
- * \inmodule QtDataVis3D
+ * \inmodule QtDataVisualization
* \brief The Q3DWindow class provides a window and render loop.
* \since 1.0.0
*
* This class creates a QWindow and provides render loop for visualization types inheriting it.
* \warning This class is not intended to be used directly by developers.
*
- * \sa Q3DBars, Q3DMaps, {Qt Data Visualization 3D C++ Classes}
+ * \sa Q3DBars, Q3DScatter, Q3DSurface, {Qt Data Visualization C++ Classes}
*/
/*!
- * \a parent A QWindow parent.
- *
- * Constructs Q3DWindow. It creates a QWindow and an OpenGL context. It also sets surface
- * format and initializes OpenGL functions for use.
+ * Constructs Q3DWindow with \a parent. It creates a QWindow and an OpenGL context. It also sets
+ * surface format and initializes OpenGL functions for use.
*/
Q3DWindow::Q3DWindow(QWindow *parent)
: QWindow(parent),
@@ -82,7 +80,7 @@ Q3DWindow::Q3DWindow(QWindow *parent)
if (splitversionstr[0].toFloat() < 1.2)
qFatal("GLSL version must be 1.20 or higher. Try installing latest display drivers.");
#endif
- setAnimating(true);
+ renderLater();
}
/*!
@@ -95,8 +93,33 @@ Q3DWindow::~Q3DWindow()
/*!
* \internal
*/
+void Q3DWindow::setVisualController(Abstract3DController *controller)
+{
+ d_ptr->m_visualController = controller;
+}
+
+/*!
+ * \internal
+ */
+void Q3DWindow::handleDevicePixelRatioChange()
+{
+ if (QWindow::devicePixelRatio() == d_ptr->m_devicePixelRatio || !d_ptr->m_visualController)
+ return;
+
+ // Device pixel ratio changed, resize accordingly and inform the scene
+ d_ptr->m_devicePixelRatio = QWindow::devicePixelRatio();
+ d_ptr->m_visualController->updateDevicePixelRatio(d_ptr->m_devicePixelRatio);
+
+}
+
+/*!
+ * \internal
+ */
void Q3DWindow::render()
{
+ handleDevicePixelRatioChange();
+ d_ptr->m_visualController->synchDataToRenderer();
+ d_ptr->m_visualController->render();
}
/*!
@@ -119,6 +142,12 @@ bool Q3DWindow::event(QEvent *event)
case QEvent::UpdateRequest:
renderNow();
return true;
+ case QEvent::TouchBegin:
+ case QEvent::TouchCancel:
+ case QEvent::TouchUpdate:
+ case QEvent::TouchEnd:
+ d_ptr->m_visualController->touchEvent(static_cast<QTouchEvent *>(event));
+ return true;
default:
return QWindow::event(event);
}
@@ -150,27 +179,14 @@ void Q3DWindow::renderNow()
render();
d_ptr->m_context->swapBuffers(this);
-
- if (d_ptr->m_animating)
- renderLater();
-}
-
-/*!
- * \internal
- */
-void Q3DWindow::setAnimating(bool animating)
-{
- d_ptr->m_animating = animating;
-
- if (animating)
- renderLater();
}
Q3DWindowPrivate::Q3DWindowPrivate(Q3DWindow *q)
: q_ptr(q),
m_updatePending(false),
- m_animating(false),
- m_context(new QOpenGLContext(q))
+ m_context(new QOpenGLContext(q)),
+ m_visualController(0),
+ m_devicePixelRatio(1.f)
{
}
@@ -178,4 +194,4 @@ Q3DWindowPrivate::~Q3DWindowPrivate()
{
}
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavis3d/engine/q3dwindow.h b/src/datavisualization/engine/q3dwindow.h
index e9f8fe1d..1848ff29 100644
--- a/src/datavis3d/engine/q3dwindow.h
+++ b/src/datavisualization/engine/q3dwindow.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -19,43 +19,47 @@
#ifndef Q3DWINDOW_H
#define Q3DWINDOW_H
-#include <QtDataVis3D/qdatavis3denums.h>
+#include <QtDataVisualization/qdatavisualizationenums.h>
#include <QWindow>
#include <QOpenGLFunctions>
+#include <QScreen>
class QPainter;
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
class Q3DWindowPrivate;
+class Abstract3DController;
-class QT_DATAVIS3D_EXPORT Q3DWindow : public QWindow, protected QOpenGLFunctions
+class QT_DATAVISUALIZATION_EXPORT Q3DWindow : public QWindow, protected QOpenGLFunctions
{
Q_OBJECT
public:
explicit Q3DWindow(QWindow *parent = 0);
- ~Q3DWindow();
+ virtual ~Q3DWindow();
-private slots:
+protected slots:
void renderLater();
void renderNow();
protected:
virtual void render();
- void setAnimating(bool animating);
bool event(QEvent *event);
void exposeEvent(QExposeEvent *event);
+ void setVisualController(Abstract3DController *controller);
+ void handleDevicePixelRatioChange();
private:
QScopedPointer<Q3DWindowPrivate> d_ptr;
- friend class Q3DBarsPrivate;
friend class Q3DBars;
+ friend class Q3DScatter;
+ friend class Q3DSurface;
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif
diff --git a/src/datavis3d/engine/q3dwindow_p.h b/src/datavisualization/engine/q3dwindow_p.h
index d32facfa..6bef7e10 100644
--- a/src/datavis3d/engine/q3dwindow_p.h
+++ b/src/datavisualization/engine/q3dwindow_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -29,14 +29,15 @@
#ifndef Q3DWINDOW_p_H
#define Q3DWINDOW_p_H
-#include "datavis3dglobal_p.h"
+#include "datavisualizationglobal_p.h"
class QOpenGLContext;
class QOpenGLPaintDevice;
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
class Q3DWindow;
+class Abstract3DController;
class Q3DWindowPrivate
{
@@ -48,11 +49,11 @@ public:
Q3DWindow *q_ptr;
bool m_updatePending;
- bool m_animating;
-
QOpenGLContext *m_context;
+ Abstract3DController *m_visualController;
+ qreal m_devicePixelRatio;
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif
diff --git a/src/datavisualization/engine/scatter3dcontroller.cpp b/src/datavisualization/engine/scatter3dcontroller.cpp
new file mode 100644
index 00000000..9f43d94e
--- /dev/null
+++ b/src/datavisualization/engine/scatter3dcontroller.cpp
@@ -0,0 +1,271 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 "q3dabstractaxis_p.h"
+#include "q3dvalueaxis_p.h"
+#include "qscatterdataproxy_p.h"
+
+#include <QMatrix4x4>
+#include <qmath.h>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+Scatter3DController::Scatter3DController(QRect boundRect)
+ : Abstract3DController(boundRect),
+ m_renderer(0),
+ m_selectedItemIndex(noSelectionIndex())
+{
+ // Default object type; specific to scatter
+ setObjectType(QDataVis::MeshStyleSpheres, false);
+
+ setActiveDataProxy(new QScatterDataProxy);
+
+ // Setting a null axis creates a new default axis according to orientation and graph type.
+ // Note: These cannot be set in Abstract3DController constructor, as they will call virtual
+ // functions implemented by subclasses.
+ setAxisX(0);
+ setAxisY(0);
+ setAxisZ(0);
+}
+
+Scatter3DController::~Scatter3DController()
+{
+}
+
+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);
+ synchDataToRenderer();
+
+ QObject::connect(m_renderer, &Scatter3DRenderer::selectedItemIndexChanged, this,
+ &Scatter3DController::handleSelectedItemIndexChanged, Qt::QueuedConnection);
+ emitNeedRender();
+}
+
+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_changeTracker.selectedItemIndexChanged) {
+ m_renderer->updateSelectedItemIndex(m_selectedItemIndex);
+ m_changeTracker.selectedItemIndexChanged = false;
+ }
+
+ if (m_isDataDirty) {
+ m_renderer->updateDataModel(static_cast<QScatterDataProxy *>(m_data));
+ m_isDataDirty = false;
+ }
+}
+
+
+void Scatter3DController::setActiveDataProxy(QAbstractDataProxy *proxy)
+{
+ // Setting null proxy indicates default proxy
+ if (!proxy) {
+ proxy = new QScatterDataProxy;
+ proxy->d_ptr->setDefaultProxy(true);
+ }
+
+ Q_ASSERT(proxy->type() == QAbstractDataProxy::DataTypeScatter);
+
+ Abstract3DController::setActiveDataProxy(proxy);
+
+ QScatterDataProxy *scatterDataProxy = static_cast<QScatterDataProxy *>(m_data);
+
+ QObject::connect(scatterDataProxy, &QScatterDataProxy::arrayReset,
+ this, &Scatter3DController::handleArrayReset);
+ QObject::connect(scatterDataProxy, &QScatterDataProxy::itemsAdded,
+ this, &Scatter3DController::handleItemsAdded);
+ QObject::connect(scatterDataProxy, &QScatterDataProxy::itemsChanged,
+ this, &Scatter3DController::handleItemsChanged);
+ QObject::connect(scatterDataProxy, &QScatterDataProxy::itemsRemoved,
+ this, &Scatter3DController::handleItemsRemoved);
+ QObject::connect(scatterDataProxy, &QScatterDataProxy::itemsInserted,
+ this, &Scatter3DController::handleItemsInserted);
+
+ adjustValueAxisRange();
+ setSelectedItemIndex(noSelectionIndex());
+ setSlicingActive(false);
+ m_isDataDirty = true;
+ emitNeedRender();
+}
+
+void Scatter3DController::handleArrayReset()
+{
+ setSlicingActive(false);
+ adjustValueAxisRange();
+ m_isDataDirty = true;
+ setSelectedItemIndex(noSelectionIndex());
+ emitNeedRender();
+}
+
+void Scatter3DController::handleItemsAdded(int startIndex, int count)
+{
+ Q_UNUSED(startIndex)
+ Q_UNUSED(count)
+ // TODO should dirty only affected values?
+ adjustValueAxisRange();
+ m_isDataDirty = true;
+ emitNeedRender();
+}
+
+void Scatter3DController::handleItemsChanged(int startIndex, int count)
+{
+ Q_UNUSED(startIndex)
+ Q_UNUSED(count)
+ // TODO should dirty only affected values?
+ adjustValueAxisRange();
+ m_isDataDirty = true;
+ emitNeedRender();
+}
+
+void Scatter3DController::handleItemsRemoved(int startIndex, int count)
+{
+ Q_UNUSED(startIndex)
+ Q_UNUSED(count)
+ // TODO should dirty only affected values?
+ adjustValueAxisRange();
+ m_isDataDirty = true;
+ if (startIndex >= static_cast<QScatterDataProxy *>(m_data)->itemCount())
+ setSelectedItemIndex(noSelectionIndex());
+ emitNeedRender();
+}
+
+void Scatter3DController::handleItemsInserted(int startIndex, int count)
+{
+ Q_UNUSED(startIndex)
+ Q_UNUSED(count)
+ // TODO should dirty only affected values?
+ adjustValueAxisRange();
+ m_isDataDirty = true;
+ emitNeedRender();
+}
+
+void Scatter3DController::handleSelectedItemIndexChanged(int index)
+{
+ if (index != m_selectedItemIndex) {
+ m_selectedItemIndex = index;
+ emit selectedItemIndexChanged(index);
+ emitNeedRender();
+ }
+}
+
+void Scatter3DController::handleAxisAutoAdjustRangeChangedInOrientation(
+ Q3DAbstractAxis::AxisOrientation orientation, bool autoAdjust)
+{
+ Q_UNUSED(orientation)
+ Q_UNUSED(autoAdjust)
+ adjustValueAxisRange();
+}
+
+void Scatter3DController::setObjectType(QDataVis::MeshStyle style, bool smooth)
+{
+ QString objFile;
+ if (style == QDataVis::MeshStyleSpheres) {
+ 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::SelectionModeItem) {
+ qWarning("Unsupported selection mode.");
+ return;
+ }
+ // Disable zoom if selection mode changes
+ setSlicingActive(false);
+ Abstract3DController::setSelectionMode(mode);
+}
+
+void Scatter3DController::setSelectedItemIndex(int index)
+{
+ // TODO If items not within axis ranges are culled from drawing, should they be
+ // TODO unselectable as well?
+ if (index < 0 || index >= static_cast<QScatterDataProxy *>(m_data)->itemCount())
+ index = noSelectionIndex();
+
+ if (index != m_selectedItemIndex) {
+ m_selectedItemIndex = index;
+ m_changeTracker.selectedItemIndexChanged = true;
+ emit selectedItemIndexChanged(index);
+ emitNeedRender();
+ }
+}
+
+int Scatter3DController::selectedItemIndex() const
+{
+ return m_selectedItemIndex;
+}
+
+void Scatter3DController::adjustValueAxisRange()
+{
+ if (m_data) {
+ QVector3D limits = static_cast<QScatterDataProxy *>(m_data)->dptr()->limitValues();
+ Q3DValueAxis *valueAxis = static_cast<Q3DValueAxis *>(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<Q3DValueAxis *>(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<Q3DValueAxis *>(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_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavis3d/engine/scatter3dcontroller_p.h b/src/datavisualization/engine/scatter3dcontroller_p.h
index 437664b7..63735aca 100644
--- a/src/datavis3d/engine/scatter3dcontroller_p.h
+++ b/src/datavisualization/engine/scatter3dcontroller_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -29,40 +29,37 @@
#ifndef Q3DSCATTERCONTROLLER_p_H
#define Q3DSCATTERCONTROLLER_p_H
-#include "datavis3dglobal_p.h"
+#include "datavisualizationglobal_p.h"
#include "abstract3dcontroller_p.h"
//#define DISPLAY_RENDER_SPEED
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
class Scatter3DRenderer;
class QScatterDataProxy;
struct Scatter3DChangeBitField {
bool slicingActiveChanged : 1;
+ bool selectedItemIndexChanged : 1;
Scatter3DChangeBitField() :
- slicingActiveChanged(true)
+ slicingActiveChanged(true),
+ selectedItemIndexChanged(true)
{
}
};
-class QT_DATAVIS3D_EXPORT Scatter3DController : public Abstract3DController
+class QT_DATAVISUALIZATION_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;
+ int m_selectedItemIndex;
public:
explicit Scatter3DController(QRect rect);
@@ -70,37 +67,21 @@ public:
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);
+ void setSelectedItemIndex(int index);
+ int selectedItemIndex() const;
+ static inline int noSelectionIndex() { return -1; }
- // Sets the data proxy. Assumes ownership of the data proxy. Deletes old proxy.
- void setDataProxy(QScatterDataProxy *proxy);
- QScatterDataProxy *dataProxy();
+ virtual void setActiveDataProxy(QAbstractDataProxy *proxy);
void synchDataToRenderer();
- virtual void handleAxisAutoAdjustRangeChangedInOrientation(QAbstractAxis::AxisOrientation orientation, bool autoAdjust);
+ virtual void handleAxisAutoAdjustRangeChangedInOrientation(Q3DAbstractAxis::AxisOrientation orientation, bool autoAdjust);
public slots:
void handleArrayReset();
@@ -108,9 +89,10 @@ public slots:
void handleItemsChanged(int startIndex, int count);
void handleItemsRemoved(int startIndex, int count);
void handleItemsInserted(int startIndex, int count);
+ void handleSelectedItemIndexChanged(int index);
signals:
- void slicingActiveChanged(bool isSlicing);
+ void selectedItemIndexChanged(int index);
private:
void adjustValueAxisRange();
@@ -119,6 +101,6 @@ private:
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif
diff --git a/src/datavis3d/engine/scatter3drenderer.cpp b/src/datavisualization/engine/scatter3drenderer.cpp
index a7657547..a482cc42 100644
--- a/src/datavis3d/engine/scatter3drenderer.cpp
+++ b/src/datavisualization/engine/scatter3drenderer.cpp
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -18,11 +18,13 @@
#include "scatter3drenderer_p.h"
#include "scatter3dcontroller_p.h"
-#include "camerahelper_p.h"
+#include "q3dcamera.h"
+#include "q3dcamera_p.h"
#include "shaderhelper_p.h"
#include "objecthelper_p.h"
#include "texturehelper_p.h"
#include "utils_p.h"
+#include "q3dlight.h"
#include <QMatrix4x4>
#include <QMouseEvent>
@@ -38,17 +40,12 @@
// 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
+QT_DATAVISUALIZATION_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.
+const GLfloat labelMargin = 0.05f;
// 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;
@@ -58,7 +55,6 @@ Scatter3DRenderer::Scatter3DRenderer(Scatter3DController *controller)
: Abstract3DRenderer(controller),
m_controller(controller),
m_selectedItem(0),
- m_previouslySelectedItem(0),
m_xFlipped(false),
m_zFlipped(false),
m_yFlipped(false),
@@ -78,27 +74,22 @@ Scatter3DRenderer::Scatter3DRenderer(Scatter3DController *controller)
m_depthFrameBuffer(0),
m_selectionFrameBuffer(0),
m_selectionDepthBuffer(0),
- m_shadowQualityToShader(33.3f),
+ m_shadowQualityToShader(100.0f),
+ m_shadowQualityMultiplier(3),
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
+ m_previousSelection(selectionSkipColor),
+ m_areaSize(QSizeF(0.0, 0.0)),
+ m_dotSizeScale(1.0f),
+ m_hasHeightAdjustmentChanged(true)
{
- //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);
@@ -108,17 +99,16 @@ Scatter3DRenderer::~Scatter3DRenderer()
delete m_depthShader;
delete m_selectionShader;
delete m_backgroundShader;
+ delete m_labelShader;
delete m_dotObj;
delete m_backgroundObj;
delete m_gridLineObj;
- delete m_textureHelper;
+ delete m_labelObj;
}
void Scatter3DRenderer::initializeOpenGL()
{
- //qDebug() << __FUNCTION__;
- m_textureHelper = new TextureHelper();
- m_drawer->initializeOpenGL();
+ Abstract3DRenderer::initializeOpenGL();
// Initialize shaders
handleShadowQualityChange();
@@ -140,30 +130,12 @@ void Scatter3DRenderer::initializeOpenGL()
// 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)
@@ -171,69 +143,69 @@ void Scatter3DRenderer::updateDataModel(QScatterDataProxy *dataProxy)
const QScatterDataArray &dataArray = *dataProxy->array();
calculateSceneScalingFactors();
int dataSize = dataArray.size();
- m_renderItemArray.resize(dataSize);
+ float minX = float(m_axisCacheX.min());
+ float maxX = float(m_axisCacheX.max());
+ float minY = float(m_axisCacheY.min());
+ float maxY = float(m_axisCacheY.max());
+ float minZ = float(m_axisCacheZ.min());
+ float maxZ = float(m_axisCacheZ.max());
+
+ if (dataSize != m_renderItemArray.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);
+ QVector3D dotPos = dataArray.at(i).position();
+ // TODO: Check if this still works always when ranges are no longer required to be zero centered
+ // TODO: qreal -> float conversion for axis min/max may cause issues like in surface
+ if ((dotPos.x() >= minX && dotPos.x() <= maxX )
+ && (dotPos.y() >= minY && dotPos.y() <= maxY)
+ && (dotPos.z() >= minZ && dotPos.z() <= maxZ)) {
+ m_renderItemArray[i].setPosition(dotPos);
+ m_renderItemArray[i].setVisible(true);
+ calculateTranslation(m_renderItemArray[i]);
+ } else {
+ m_renderItemArray[i].setVisible(false);
+ }
}
- m_dotSizeScale = (GLfloat)qBound(0.01, (qreal)(2.0f / qSqrt((qreal)dataSize)), 0.1);
+ m_dotSizeScale = (GLfloat)qBound(0.01, (2.0 / qSqrt((qreal)dataSize)), 0.1);
+ m_selectedItem = 0;
Abstract3DRenderer::updateDataModel(dataProxy);
}
-void Scatter3DRenderer::render(CameraHelper *camera, const GLuint defaultFboHandle)
+void Scatter3DRenderer::updateScene(Q3DScene *scene)
{
- //qDebug() << __FUNCTION__;
+ // TODO: Move these to more suitable place e.g. controller should be controlling the viewports.
+ scene->setPrimarySubViewport(m_mainViewPort);
-#ifdef DISPLAY_RENDER_SPEED
- // For speed computation
- if (m_isFirstFrame) {
- m_lastFrameTime.start();
- m_isFirstFrame = false;
- }
+ // TODO: See QTRD-2374
+ scene->activeCamera()->setMinYRotation(-90.0f);
- // 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();
+ if (m_hasHeightAdjustmentChanged) {
+ // Set initial m_cachedScene->activeCamera() position. Also update if height adjustment has changed.
+ scene->activeCamera()->setBaseOrientation(QVector3D(0.0f, 0.0f, cameraDistance + zComp),
+ QVector3D(0.0f, 0.0f, zComp),
+ QVector3D(0.0f, 1.0f, 0.0f));
+ m_hasHeightAdjustmentChanged = false;
}
-#endif
- if (defaultFboHandle) {
- glDepthMask(true);
- glEnable(GL_DEPTH_TEST);
- glDepthFunc(GL_LESS);
- glEnable(GL_CULL_FACE);
- glCullFace(GL_BACK);
- }
+ scene->activeCamera()->d_ptr->updateViewMatrix(m_autoScaleAdjustment);
+ // Set light position (rotate light with m_cachedScene->activeCamera(), a bit above it (as set in defaultLightPos))
+ scene->setLightPositionRelativeToCamera(defaultLightPos);
- 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);
+ Abstract3DRenderer::updateScene(scene);
+}
- 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;
- }
+void Scatter3DRenderer::render(GLuint defaultFboHandle)
+{
+ // Handle GL state setup for FBO buffers and clearing of the render surface
+ Abstract3DRenderer::render(defaultFboHandle);
- // Draw bars scene
- drawScene(camera, defaultFboHandle);
+ // Draw dots scene
+ drawScene(defaultFboHandle);
}
-void Scatter3DRenderer::drawScene(CameraHelper *camera,
- const GLuint defaultFboHandle)
+void Scatter3DRenderer::drawScene(const GLuint defaultFboHandle)
{
- //qDebug() << __FUNCTION__;
GLfloat backgroundRotation = 0;
// Specify viewport
@@ -246,11 +218,7 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
/ (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);
+ QMatrix4x4 viewMatrix = m_cachedScene->activeCamera()->viewMatrix();
// Calculate label flipping
if (viewMatrix.row(0).x() > 0)
@@ -278,8 +246,8 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
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);
+ // Get light position from the scene
+ QVector3D lightPos = m_cachedScene->activeLight()->position();
// Map adjustment direction to model matrix scaling
// TODO: Let's use these for testing the autoscaling of dots based on their number
@@ -289,63 +257,21 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
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) {
+ if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) {
// 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);
+ m_mainViewPort.width() * m_shadowQualityMultiplier,
+ m_mainViewPort.height() * m_shadowQualityMultiplier);
// Enable drawing to framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, m_depthFrameBuffer);
@@ -356,12 +282,13 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
// 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 depthLightPos = m_cachedScene->activeCamera()->calculatePositionRelativeToCamera(
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);
+ // 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
@@ -377,10 +304,10 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
-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())
+ // Draw dots to depth buffer
+ for (int dot = 0; dot < m_renderItemArray.size(); dot++) {
+ const ScatterRenderItem &item = m_renderItemArray.at(dot);
+ if (!item.isVisible())
continue;
QMatrix4x4 modelMatrix;
@@ -452,23 +379,24 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
#endif
// Skip selection mode drawing if we have no selection mode
- if (m_cachedSelectionMode > QDataVis::ModeNone) {
+ if (m_cachedSelectionMode > QDataVis::SelectionModeNone) {
// Bind selection shader
m_selectionShader->bind();
- // Draw bars to selection buffer
+ // Draw dots 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)
+ glClearColor(1.0f, 1.0f, 1.0f, 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())
+
+ int arraySize = m_renderItemArray.size();
+ if (arraySize > 0xfffffe) // Max possible different selection colors, 0xffffff being skipColor
+ qFatal("Too many objects");
+
+ for (int dot = 0; dot < arraySize; dot++) {
+ const ScatterRenderItem &item = m_renderItemArray.at(dot);
+ if (!item.isVisible())
continue;
QMatrix4x4 modelMatrix;
@@ -486,23 +414,11 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
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);
+ QVector3D dotColor = indexToSelectionColor(dot);
+ dotColor /= 255.0f;
m_selectionShader->setUniformValue(m_selectionShader->MVP(), MVPMatrix);
- m_selectionShader->setUniformValue(m_selectionShader->color(), barColor);
+ m_selectionShader->setUniformValue(m_selectionShader->color(), dotColor);
// 1st attribute buffer : vertices
glEnableVertexAttribArray(m_selectionShader->posAtt());
@@ -524,18 +440,10 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
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,
+ if (QDataVis::InputStateOnScene == m_controller->inputState()) {
+ m_selection = Utils::getSelection(m_controller->inputPosition(),
m_cachedBoundingRect.height());
- emit selectionUpdated(m_selection);
}
- locker.unlock();
glBindFramebuffer(GL_FRAMEBUFFER, defaultFboHandle);
@@ -561,17 +469,33 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
#endif
}
- // Bind bar shader
+ // Bind dot 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())
+ // Draw dots
+ bool dotSelectionFound = false;
+ int selectedIndex;
+ if (m_selection == selectionSkipColor) {
+ selectedIndex = Scatter3DController::noSelectionIndex();
+ } else {
+ selectedIndex = int(m_selection.x())
+ + (int(m_selection.y()) << 8)
+ + (int(m_selection.z()) << 16);
+ }
+
+ if (m_selection != m_previousSelection) {
+ emit selectedItemIndexChanged(selectedIndex);
+ m_previousSelection = m_selection;
+ }
+
+ ScatterRenderItem *selectedItem(0);
+
+ for (int dot = 0; dot < m_renderItemArray.size(); dot++) {
+ ScatterRenderItem &item = m_renderItemArray[dot];
+ if (!item.isVisible())
continue;
QMatrix4x4 modelMatrix;
@@ -602,35 +526,23 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
#endif
depthMVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
+#if 0
QVector3D baseColor = Utils::vectorFromColor(m_cachedTheme.m_baseColor);
QVector3D heightColor =
Utils::vectorFromColor(m_cachedTheme.m_heightColor) * item.translation().y();
- QVector3D barColor = baseColor + heightColor;
+ QVector3D dotColor = baseColor + heightColor;
+#else
+ QVector3D dotColor = Utils::vectorFromColor(m_cachedTheme.m_baseColor);
+#endif
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;
- }
- }
+ if (m_cachedSelectionMode > QDataVis::SelectionModeNone && (selectedIndex == dot)) {
+ dotColor = 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
+ selectedItem = &item;
+ dotSelectionFound = true;
}
// Set shader bindings
@@ -640,11 +552,11 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
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->color(), dotColor);
m_dotShader->setUniformValue(m_dotShader->ambientS(), m_cachedTheme.m_ambientStrength);
#if !defined(QT_OPENGL_ES_2)
- if (m_cachedShadowQuality > QDataVis::ShadowNone) {
+ if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) {
// Set shadow shader bindings
m_dotShader->setUniformValue(m_dotShader->shadowQ(), m_shadowQualityToShader);
m_dotShader->setUniformValue(m_dotShader->depth(), depthMVPMatrix);
@@ -663,7 +575,7 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
}
}
- // Release bar shader
+ // Release dot shader
m_dotShader->release();
// Bind background shader
@@ -678,20 +590,18 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
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));
+ QVector3D bgScale((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)));
+ QVector3D bgScale((aspectRatio * backgroundMargin),
+ backgroundMargin,
+ (aspectRatio * backgroundMargin));
#endif
- // We can copy modelMatrix to itModelMatrix as it has not been translated
- itModelMatrix = modelMatrix;
+ modelMatrix.translate(0.0f, 0.0f, zComp);
+ modelMatrix.scale(bgScale);
+ itModelMatrix.scale(bgScale);
// If we're viewing from below, background object must be flipped
if (m_yFlipped) {
modelMatrix.rotate(180.0f, 1.0, 0.0, 0.0);
@@ -721,7 +631,7 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
m_cachedTheme.m_ambientStrength * 2.0f);
#if !defined(QT_OPENGL_ES_2)
- if (m_cachedShadowQuality > QDataVis::ShadowNone) {
+ if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) {
// Set shadow shader bindings
m_backgroundShader->setUniformValue(m_backgroundShader->shadowQ(),
m_shadowQualityToShader);
@@ -759,21 +669,23 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
#endif
if (m_cachedIsGridEnabled && m_heightNormalizer) {
- // Bind bar shader
- m_dotShader->bind();
+ ShaderHelper *lineShader = m_backgroundShader;
+ // Bind line shader
+ lineShader->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);
+ QVector3D lineColor = Utils::vectorFromColor(m_cachedTheme.m_gridLine);
+ lineShader->setUniformValue(lineShader->lightP(), lightPos);
+ lineShader->setUniformValue(lineShader->view(), viewMatrix);
+ lineShader->setUniformValue(lineShader->color(), lineColor);
+ lineShader->setUniformValue(lineShader->ambientS(), m_cachedTheme.m_ambientStrength);
- // Floor lines: rows (= Z)
+ // Rows (= Z)
if (m_axisCacheZ.segmentCount() > 0) {
+ // Floor lines
#ifndef USE_UNIFORM_SCALING
GLfloat lineStep = aspectRatio * m_axisCacheZ.subSegmentStep();
- GLfloat linePos = aspectRatio * m_axisCacheZ.min(); // Start line
+ GLfloat linePos = -aspectRatio * m_axisCacheZ.min(); // Start line
int lastSegment = m_axisCacheZ.subSegmentCount() * m_axisCacheZ.segmentCount();
#else
GLfloat lineStep = aspectRatio * axisCacheMax->subSegmentStep();
@@ -787,15 +699,10 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
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);
- }
+ 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(
@@ -820,37 +727,92 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
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);
+ lineShader->setUniformValue(lineShader->model(), modelMatrix);
+ lineShader->setUniformValue(lineShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ lineShader->setUniformValue(lineShader->MVP(), MVPMatrix);
#if !defined(QT_OPENGL_ES_2)
- if (m_cachedShadowQuality > QDataVis::ShadowNone) {
+ if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) {
// 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);
+ lineShader->setUniformValue(lineShader->shadowQ(), m_shadowQualityToShader);
+ lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix);
+ lineShader->setUniformValue(lineShader->lightS(),
+ m_cachedTheme.m_lightStrength / 10.0f);
// Draw the object
- m_drawer->drawObject(m_dotShader, m_gridLineObj, 0, m_depthTexture);
+ m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture);
} else
#endif
{
// Set shadowless shader bindings
- m_dotShader->setUniformValue(m_dotShader->lightS(),
- m_cachedTheme.m_lightStrength);
+ lineShader->setUniformValue(lineShader->lightS(),
+ m_cachedTheme.m_lightStrength);
// Draw the object
- m_drawer->drawObject(m_dotShader, m_gridLineObj);
+ m_drawer->drawObject(lineShader, m_gridLineObj);
}
- linePos += lineStep;
+ linePos -= lineStep;
+ }
+
+ // Side wall lines
+#ifndef USE_UNIFORM_SCALING
+ GLfloat lineXTrans = (aspectRatio * backgroundMargin * m_areaSize.width())
+ / m_scaleFactor;
+ linePos = -aspectRatio * m_axisCacheZ.min(); // Start line
+#else
+ GLfloat lineXTrans = aspectRatio * backgroundMargin;
+ linePos = -aspectRatio * m_scaleFactor; // Start line
+#endif
+ if (!m_xFlipped)
+ lineXTrans = -lineXTrans;
+
+ for (int segment = 0; segment <= lastSegment; segment++) {
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+ QMatrix4x4 depthMVPMatrix;
+ QMatrix4x4 itModelMatrix;
+
+ modelMatrix.translate(lineXTrans, 0.0f, linePos / m_scaleFactor + zComp);
+ modelMatrix.scale(QVector3D(gridLineWidth, backgroundMargin, gridLineWidth));
+ itModelMatrix.scale(QVector3D(gridLineWidth, backgroundMargin, gridLineWidth));
+
+ MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
+ depthMVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
+
+ // Set the rest of the shader bindings
+ lineShader->setUniformValue(lineShader->model(), modelMatrix);
+ lineShader->setUniformValue(lineShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ lineShader->setUniformValue(lineShader->MVP(), MVPMatrix);
+
+#if !defined(QT_OPENGL_ES_2)
+ if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) {
+ // Set shadow shader bindings
+ lineShader->setUniformValue(lineShader->shadowQ(), m_shadowQualityToShader);
+ lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix);
+ lineShader->setUniformValue(lineShader->lightS(),
+ m_cachedTheme.m_lightStrength / 10.0f);
+
+ // Draw the object
+ m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture);
+ } else
+#endif
+ {
+ // Set shadowless shader bindings
+ lineShader->setUniformValue(lineShader->lightS(),
+ m_cachedTheme.m_lightStrength);
+
+ // Draw the object
+ m_drawer->drawObject(lineShader, m_gridLineObj);
+ }
+ linePos -= lineStep;
}
}
- // Floor lines: columns (= X)
+ // Columns (= X)
if (m_axisCacheX.segmentCount() > 0) {
+ // Floor lines
#ifndef USE_UNIFORM_SCALING
GLfloat lineStep = aspectRatio * m_axisCacheX.subSegmentStep();
GLfloat linePos = aspectRatio * m_axisCacheX.min();
@@ -867,15 +829,10 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
QMatrix4x4 depthMVPMatrix;
QMatrix4x4 itModelMatrix;
- if (m_yFlipped) {
- modelMatrix.translate(linePos / m_scaleFactor,
- backgroundMargin,
- zComp);
- } else {
- modelMatrix.translate(linePos / m_scaleFactor,
- -backgroundMargin,
- zComp);
- }
+ 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(
@@ -900,58 +857,111 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
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);
+ lineShader->setUniformValue(lineShader->model(), modelMatrix);
+ lineShader->setUniformValue(lineShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ lineShader->setUniformValue(lineShader->MVP(), MVPMatrix);
#if !defined(QT_OPENGL_ES_2)
- if (m_cachedShadowQuality > QDataVis::ShadowNone) {
+ if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) {
// 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);
+ lineShader->setUniformValue(lineShader->shadowQ(), m_shadowQualityToShader);
+ lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix);
+ lineShader->setUniformValue(lineShader->lightS(),
+ m_cachedTheme.m_lightStrength / 10.0f);
// Draw the object
- m_drawer->drawObject(m_dotShader, m_gridLineObj, 0, m_depthTexture);
+ m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture);
} else
#endif
{
// Set shadowless shader bindings
- m_dotShader->setUniformValue(m_dotShader->lightS(), m_cachedTheme.m_lightStrength);
+ lineShader->setUniformValue(lineShader->lightS(), m_cachedTheme.m_lightStrength);
// Draw the object
- m_drawer->drawObject(m_dotShader, m_gridLineObj);
+ m_drawer->drawObject(lineShader, m_gridLineObj);
+ }
+ linePos += lineStep;
+ }
+
+ // Back wall lines
+#ifndef USE_UNIFORM_SCALING
+ GLfloat lineZTrans = (aspectRatio * backgroundMargin * m_areaSize.height())
+ / m_scaleFactor;
+ linePos = aspectRatio * m_axisCacheX.min();
+#else
+ GLfloat lineZTrans = aspectRatio * backgroundMargin;
+ linePos = -aspectRatio * m_scaleFactor;
+#endif
+ if (!m_zFlipped)
+ lineZTrans = -lineZTrans;
+
+ for (int segment = 0; segment <= lastSegment; segment++) {
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+ QMatrix4x4 depthMVPMatrix;
+ QMatrix4x4 itModelMatrix;
+
+ modelMatrix.translate(linePos / m_scaleFactor, 0.0f, lineZTrans + zComp);
+ modelMatrix.scale(QVector3D(gridLineWidth, backgroundMargin, gridLineWidth));
+ itModelMatrix.scale(QVector3D(gridLineWidth, backgroundMargin, gridLineWidth));
+
+ MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
+ depthMVPMatrix = depthProjectionMatrix * depthViewMatrix * modelMatrix;
+
+ // Set the rest of the shader bindings
+ lineShader->setUniformValue(lineShader->model(), modelMatrix);
+ lineShader->setUniformValue(lineShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ lineShader->setUniformValue(lineShader->MVP(), MVPMatrix);
+
+#if !defined(QT_OPENGL_ES_2)
+ if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) {
+ // Set shadow shader bindings
+ lineShader->setUniformValue(lineShader->shadowQ(), m_shadowQualityToShader);
+ lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix);
+ lineShader->setUniformValue(lineShader->lightS(),
+ m_cachedTheme.m_lightStrength / 10.0f);
+
+ // Draw the object
+ m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture);
+ } else
+#endif
+ {
+ // Set shadowless shader bindings
+ lineShader->setUniformValue(lineShader->lightS(),
+ m_cachedTheme.m_lightStrength);
+
+ // Draw the object
+ m_drawer->drawObject(lineShader, m_gridLineObj);
}
linePos += lineStep;
}
}
- // Wall lines: back wall
+ // Horizontal wall lines
if (m_axisCacheY.segmentCount() > 0) {
+ // Back wall
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;
+ 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;
+ GLfloat lineZTrans = aspectRatio * backgroundMargin;
#endif
+ if (!m_zFlipped)
+ lineZTrans = -lineZTrans;
+
+ for (int segment = 0; segment <= lastSegment; segment++) {
QMatrix4x4 modelMatrix;
QMatrix4x4 MVPMatrix;
QMatrix4x4 depthMVPMatrix;
QMatrix4x4 itModelMatrix;
- if (!m_zFlipped)
- lineZTrans = -lineZTrans;
-
- modelMatrix.translate(0.0f,
- linePos / m_heightNormalizer,
- lineZTrans + zComp);
+ 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(
@@ -972,55 +982,52 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
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);
+ lineShader->setUniformValue(lineShader->model(), modelMatrix);
+ lineShader->setUniformValue(lineShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ lineShader->setUniformValue(lineShader->MVP(), MVPMatrix);
#if !defined(QT_OPENGL_ES_2)
- if (m_cachedShadowQuality > QDataVis::ShadowNone) {
+ if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) {
// 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);
+ lineShader->setUniformValue(lineShader->shadowQ(), m_shadowQualityToShader);
+ lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix);
+ lineShader->setUniformValue(lineShader->lightS(),
+ m_cachedTheme.m_lightStrength / 10.0f);
// Draw the object
- m_drawer->drawObject(m_dotShader, m_gridLineObj, 0, m_depthTexture);
+ m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture);
} else
#endif
{
// Set shadowless shader bindings
- m_dotShader->setUniformValue(m_dotShader->lightS(), m_cachedTheme.m_lightStrength);
+ lineShader->setUniformValue(lineShader->lightS(), m_cachedTheme.m_lightStrength);
// Draw the object
- m_drawer->drawObject(m_dotShader, m_gridLineObj);
+ m_drawer->drawObject(lineShader, m_gridLineObj);
}
linePos += lineStep;
}
- // Wall lines: side wall
+ // 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;
+ 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;
+ GLfloat lineXTrans = aspectRatio * backgroundMargin;
#endif
+ if (!m_xFlipped)
+ lineXTrans = -lineXTrans;
+
+ for (int segment = 0; segment <= lastSegment; segment++) {
QMatrix4x4 modelMatrix;
QMatrix4x4 MVPMatrix;
QMatrix4x4 depthMVPMatrix;
QMatrix4x4 itModelMatrix;
- if (!m_xFlipped)
- lineXTrans = -lineXTrans;
-
- modelMatrix.translate(lineXTrans,
- linePos / m_heightNormalizer,
- zComp);
+ 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(
@@ -1042,91 +1049,37 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
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);
+ lineShader->setUniformValue(lineShader->model(), modelMatrix);
+ lineShader->setUniformValue(lineShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ lineShader->setUniformValue(lineShader->MVP(), MVPMatrix);
#if !defined(QT_OPENGL_ES_2)
- if (m_cachedShadowQuality > QDataVis::ShadowNone) {
+ if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) {
// 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);
+ lineShader->setUniformValue(lineShader->shadowQ(), m_shadowQualityToShader);
+ lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix);
+ lineShader->setUniformValue(lineShader->lightS(),
+ m_cachedTheme.m_lightStrength / 10.0f);
// Draw the object
- m_drawer->drawObject(m_dotShader, m_gridLineObj, 0, m_depthTexture);
+ m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture);
} else
#endif
{
// Set shadowless shader bindings
- m_dotShader->setUniformValue(m_dotShader->lightS(), m_cachedTheme.m_lightStrength);
+ lineShader->setUniformValue(lineShader->lightS(),
+ m_cachedTheme.m_lightStrength);
// Draw the object
- m_drawer->drawObject(m_dotShader, m_gridLineObj);
+ m_drawer->drawObject(lineShader, 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;
+ // Release line shader
+ lineShader->release();
}
// Draw axis labels
@@ -1136,20 +1089,18 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
m_labelShader->bind();
glEnable(GL_TEXTURE_2D);
- if (m_cachedLabelTransparency > QDataVis::TransparencyNone) {
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- }
+ 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();
+ GLfloat labelPos = -aspectRatio * m_axisCacheZ.min();
int lastSegment = m_axisCacheZ.segmentCount();
#else
GLfloat posStep = aspectRatio * axisCacheMax->segmentStep();
- GLfloat labelPos = -aspectRatio * m_scaleFactor;
+ GLfloat labelPos = aspectRatio * m_scaleFactor;
int lastSegment = axisCacheMax->segmentCount();
#endif
int labelNbr = 0;
@@ -1157,10 +1108,10 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
#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;
+ / m_scaleFactor + labelMargin;
#else // ..and this if we want uniform scaling based on largest dimension
if (axisCacheMax->labelItems().size() > labelNbr) {
- GLfloat labelXTrans = aspectRatio * backgroundMargin;
+ GLfloat labelXTrans = aspectRatio * backgroundMargin + labelMargin;
#endif
GLfloat labelYTrans = -backgroundMargin;
GLfloat rotLabelX = -90.0f;
@@ -1195,11 +1146,11 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
QVector3D(0.0f, 0.0f, zComp),
QVector3D(rotLabelX, rotLabelY, rotLabelZ),
0, m_cachedSelectionMode,
- m_labelShader, m_labelObj, camera, true, true, Drawer::LabelMid,
+ m_labelShader, m_labelObj, m_cachedScene->activeCamera(), true, true, Drawer::LabelMid,
alignment);
}
labelNbr++;
- labelPos += posStep;
+ labelPos -= posStep;
}
}
// X Labels
@@ -1218,10 +1169,10 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
#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;
+ / m_scaleFactor + labelMargin;
#else // ..and this if we want uniform scaling based on largest dimension
if (axisCacheMax->labelItems().size() > labelNbr) {
- GLfloat labelZTrans = aspectRatio * backgroundMargin;
+ GLfloat labelZTrans = aspectRatio * backgroundMargin + labelMargin;
#endif
GLfloat labelYTrans = -backgroundMargin;
GLfloat rotLabelX = -90.0f;
@@ -1255,7 +1206,7 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
QVector3D(0.0f, 0.0f, zComp),
QVector3D(rotLabelX, rotLabelY, rotLabelZ),
0, m_cachedSelectionMode,
- m_labelShader, m_labelObj, camera, true, true, Drawer::LabelMid,
+ m_labelShader, m_labelObj, m_cachedScene->activeCamera(), true, true, Drawer::LabelMid,
alignment);
}
labelNbr++;
@@ -1271,13 +1222,15 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
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;
+ / m_scaleFactor;
GLfloat labelZTrans = (aspectRatio * backgroundMargin * m_areaSize.height())
- / m_scaleFactor;
+ / m_scaleFactor;
#else // ..and this if we want uniform scaling based on largest dimension
GLfloat labelXTrans = aspectRatio * backgroundMargin;
GLfloat labelZTrans = labelXTrans;
#endif
+ GLfloat labelMarginXTrans = labelMargin;
+ GLfloat labelMarginZTrans = labelMargin;
GLfloat labelYTrans = labelPos / m_heightNormalizer;
GLfloat rotLabelX = 0.0f;
GLfloat rotLabelY = -90.0f;
@@ -1285,17 +1238,20 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
Qt::AlignmentFlag alignment = Qt::AlignLeft;
if (!m_xFlipped) {
labelXTrans = -labelXTrans;
+ labelMarginXTrans = -labelMargin;
rotLabelY = 90.0f;
}
if (m_zFlipped) {
labelZTrans = -labelZTrans;
+ labelMarginZTrans = -labelMargin;
alignment = Qt::AlignRight;
}
const LabelItem &axisLabelItem = *m_axisCacheY.labelItems().at(labelNbr);
// Back wall
- QVector3D labelTrans = QVector3D(labelXTrans, labelYTrans, labelZTrans + zComp);
+ QVector3D labelTrans = QVector3D(labelXTrans, labelYTrans,
+ labelZTrans + labelMarginZTrans + zComp);
// Draw the label here
m_dummyRenderItem.setTranslation(labelTrans);
@@ -1303,7 +1259,7 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
QVector3D(0.0f, 0.0f, zComp),
QVector3D(rotLabelX, rotLabelY, rotLabelZ),
0, m_cachedSelectionMode,
- m_labelShader, m_labelObj, camera, true, true, Drawer::LabelMid,
+ m_labelShader, m_labelObj, m_cachedScene->activeCamera(), true, true, Drawer::LabelMid,
alignment);
// Side wall
@@ -1316,7 +1272,8 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
else
rotLabelY = 0.0f;
- labelTrans = QVector3D(-labelXTrans, labelYTrans, -labelZTrans + zComp);
+ labelTrans = QVector3D(-labelXTrans - labelMarginXTrans, labelYTrans,
+ -labelZTrans + zComp);
// Draw the label here
m_dummyRenderItem.setTranslation(labelTrans);
@@ -1324,33 +1281,99 @@ void Scatter3DRenderer::drawScene(CameraHelper *camera,
QVector3D(0.0f, 0.0f, zComp),
QVector3D(rotLabelX, rotLabelY, rotLabelZ),
0, m_cachedSelectionMode,
- m_labelShader, m_labelObj, camera, true, true, Drawer::LabelMid,
+ m_labelShader, m_labelObj, m_cachedScene->activeCamera(), true, true, Drawer::LabelMid,
alignment);
}
labelNbr++;
labelPos += posStep;
}
}
+
+ // Handle selection clearing and selection label drawing
+ if (!dotSelectionFound) {
+ // We have no ownership, don't delete. Just NULL the pointer.
+ m_selectedItem = NULL;
+ } else {
+ glDisable(GL_DEPTH_TEST);
+ // Draw the selection label
+ LabelItem &labelItem = selectedItem->selectionLabelItem();
+ if (m_selectedItem != selectedItem || m_updateLabels
+ || !labelItem.textureId()) {
+ QString labelText = selectedItem->selectionLabel();
+ if (labelText.isNull()) {
+ static const QString xTitleTag(QStringLiteral("@xTitle"));
+ static const QString yTitleTag(QStringLiteral("@yTitle"));
+ static const QString zTitleTag(QStringLiteral("@zTitle"));
+ static const QString xLabelTag(QStringLiteral("@xLabel"));
+ static const QString yLabelTag(QStringLiteral("@yLabel"));
+ static const QString zLabelTag(QStringLiteral("@zLabel"));
+
+ labelText = itemLabelFormat();
+
+ labelText.replace(xTitleTag, m_axisCacheX.title());
+ labelText.replace(yTitleTag, m_axisCacheY.title());
+ labelText.replace(zTitleTag, m_axisCacheZ.title());
+
+ if (labelText.contains(xLabelTag)) {
+ QString labelFormat = m_axisCacheX.labelFormat();
+ if (labelFormat.isEmpty())
+ labelFormat = Utils::defaultLabelFormat();
+ QString valueLabelText = generateValueLabel(labelFormat,
+ selectedItem->position().x());
+ labelText.replace(xLabelTag, valueLabelText);
+ }
+ if (labelText.contains(yLabelTag)) {
+ QString labelFormat = m_axisCacheY.labelFormat();
+ if (labelFormat.isEmpty())
+ labelFormat = Utils::defaultLabelFormat();
+ QString valueLabelText = generateValueLabel(labelFormat,
+ selectedItem->position().y());
+ labelText.replace(yLabelTag, valueLabelText);
+ }
+ if (labelText.contains(zLabelTag)) {
+ QString labelFormat = m_axisCacheZ.labelFormat();
+ if (labelFormat.isEmpty())
+ labelFormat = Utils::defaultLabelFormat();
+ QString valueLabelText = generateValueLabel(labelFormat,
+ selectedItem->position().z());
+ labelText.replace(zLabelTag, valueLabelText);
+ }
+
+ selectedItem->setSelectionLabel(labelText);
+ }
+ m_drawer->generateLabelItem(labelItem, labelText);
+ m_selectedItem = selectedItem;
+ }
+
+ m_drawer->drawLabel(*selectedItem, labelItem, viewMatrix, projectionMatrix,
+ QVector3D(0.0f, 0.0f, zComp),
+ QVector3D(0.0f, 0.0f, 0.0f), 0,
+ m_cachedSelectionMode, m_labelShader,
+ m_labelObj, m_cachedScene->activeCamera(), true, false,
+ Drawer::LabelMid);
+
+ // Reset label update flag; they should have been updated when we get here
+ m_updateLabels = false;
+ glEnable(GL_DEPTH_TEST);
+ }
+
glDisable(GL_TEXTURE_2D);
- if (m_cachedLabelTransparency > QDataVis::TransparencyNone)
- glDisable(GL_BLEND);
+ glDisable(GL_BLEND);
// Release label shader
m_labelShader->release();
}
-void Scatter3DRenderer::requestSelectionAtPoint(const QPoint &point)
+void Scatter3DRenderer::updateSelectedItemIndex(int index)
{
- //qDebug() << __FUNCTION__;
- QMutexLocker locker(&m_mutex);
- m_selectionPointRequest.setX(point.x());
- m_selectionPointRequest.setY(point.y());
- m_isSelectionPointRequestActive = true;
+ if (index == Scatter3DController::noSelectionIndex())
+ m_selection = selectionSkipColor;
+ else
+ m_selection = indexToSelectionColor(index);
}
void Scatter3DRenderer::handleResize()
{
- //qDebug() << __FUNCTION__;
if (m_cachedBoundingRect.width() == 0 || m_cachedBoundingRect.height() == 0)
return;
@@ -1360,36 +1383,45 @@ void Scatter3DRenderer::handleResize()
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
+ loadMeshFile(); // Load changed dot type
}
}
void Scatter3DRenderer::updateShadowQuality(QDataVis::ShadowQuality quality)
{
- qDebug() << __FUNCTION__ << quality;
m_cachedShadowQuality = quality;
switch (quality) {
- case QDataVis::ShadowLow:
+ case QDataVis::ShadowQualityLow:
m_shadowQualityToShader = 33.3f;
+ m_shadowQualityMultiplier = 1;
break;
- case QDataVis::ShadowMedium:
+ case QDataVis::ShadowQualityMedium:
m_shadowQualityToShader = 100.0f;
+ m_shadowQualityMultiplier = 3;
break;
- case QDataVis::ShadowHigh:
+ case QDataVis::ShadowQualityHigh:
m_shadowQualityToShader = 200.0f;
+ m_shadowQualityMultiplier = 5;
+ break;
+ case QDataVis::ShadowQualitySoftLow:
+ m_shadowQualityToShader = 5.0f;
+ m_shadowQualityMultiplier = 1;
+ break;
+ case QDataVis::ShadowQualitySoftMedium:
+ m_shadowQualityToShader = 10.0f;
+ m_shadowQualityMultiplier = 3;
+ break;
+ case QDataVis::ShadowQualitySoftHigh:
+ m_shadowQualityToShader = 15.0f;
+ m_shadowQualityMultiplier = 4;
break;
default:
m_shadowQualityToShader = 0.0f;
+ m_shadowQualityMultiplier = 1;
break;
}
@@ -1401,9 +1433,8 @@ void Scatter3DRenderer::updateShadowQuality(QDataVis::ShadowQuality quality)
#endif
}
-void Scatter3DRenderer::loadBarMesh()
+void Scatter3DRenderer::loadMeshFile()
{
- //qDebug() << __FUNCTION__;
QString objectFileName = m_cachedObjFile;
if (m_dotObj)
delete m_dotObj;
@@ -1413,7 +1444,6 @@ void Scatter3DRenderer::loadBarMesh()
void Scatter3DRenderer::loadBackgroundMesh()
{
- //qDebug() << __FUNCTION__;
if (m_backgroundObj)
delete m_backgroundObj;
m_backgroundObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/background"));
@@ -1422,7 +1452,6 @@ void Scatter3DRenderer::loadBackgroundMesh()
void Scatter3DRenderer::loadGridLineMesh()
{
- //qDebug() << __FUNCTION__;
if (m_gridLineObj)
delete m_gridLineObj;
m_gridLineObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/bar"));
@@ -1431,7 +1460,6 @@ void Scatter3DRenderer::loadGridLineMesh()
void Scatter3DRenderer::loadLabelMesh()
{
- //qDebug() << __FUNCTION__;
if (m_labelObj)
delete m_labelObj;
m_labelObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/label"));
@@ -1440,12 +1468,11 @@ void Scatter3DRenderer::loadLabelMesh()
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,
+void Scatter3DRenderer::updateAxisRange(Q3DAbstractAxis::AxisOrientation orientation,
qreal min, qreal max)
{
Abstract3DRenderer::updateAxisRange(orientation, min, max);
@@ -1453,14 +1480,12 @@ void Scatter3DRenderer::updateAxisRange(QAbstractAxis::AxisOrientation orientati
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 zTrans = -(aspectRatio * item.position().z()) / m_scaleFactor;
GLfloat yTrans = item.position().y() / m_heightNormalizer;
item.setTranslation(QVector3D(xTrans, yTrans, zTrans + zComp));
//qDebug() << item.translation();
@@ -1468,61 +1493,20 @@ void Scatter3DRenderer::calculateTranslation(ScatterRenderItem &item)
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_heightNormalizer = (GLfloat)qMax(qAbs(m_axisCacheY.max()), qAbs(m_axisCacheY.min()));
+ m_areaSize.setHeight(qMax(qAbs(m_axisCacheZ.max()), qAbs(m_axisCacheZ.min())));
+ m_areaSize.setWidth(qMax(qAbs(m_axisCacheX.max()), qAbs(m_axisCacheX.min())));
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);
@@ -1531,7 +1515,6 @@ void Scatter3DRenderer::initShaders(const QString &vertexShader, const QString &
void Scatter3DRenderer::initSelectionShader()
{
- //qDebug() << __FUNCTION__;
if (m_selectionShader)
delete m_selectionShader;
m_selectionShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexSelection"),
@@ -1541,7 +1524,6 @@ void Scatter3DRenderer::initSelectionShader()
void Scatter3DRenderer::initSelectionBuffer()
{
- //qDebug() << __FUNCTION__;
if (m_selectionTexture)
m_textureHelper->deleteTexture(&m_selectionTexture);
@@ -1553,7 +1535,6 @@ void Scatter3DRenderer::initSelectionBuffer()
#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"),
@@ -1563,29 +1544,46 @@ void Scatter3DRenderer::initDepthShader()
void Scatter3DRenderer::updateDepthBuffer()
{
- //qDebug() << __FUNCTION__;
if (m_depthTexture) {
m_textureHelper->deleteTexture(&m_depthTexture);
m_depthTexture = 0;
}
- if (m_cachedShadowQuality > QDataVis::ShadowNone) {
+ if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) {
m_depthTexture = m_textureHelper->createDepthTexture(m_mainViewPort.size(),
m_depthFrameBuffer,
- m_cachedShadowQuality);
+ m_shadowQualityMultiplier);
if (!m_depthTexture) {
switch (m_cachedShadowQuality) {
- case QDataVis::ShadowHigh:
+ case QDataVis::ShadowQualityHigh:
qWarning("Creating high quality shadows failed. Changing to medium quality.");
- (void)m_controller->setShadowQuality(QDataVis::ShadowMedium);
+ (void)m_controller->setShadowQuality(QDataVis::ShadowQualityMedium);
+ updateShadowQuality(QDataVis::ShadowQualityMedium);
break;
- case QDataVis::ShadowMedium:
+ case QDataVis::ShadowQualityMedium:
qWarning("Creating medium quality shadows failed. Changing to low quality.");
- (void)m_controller->setShadowQuality(QDataVis::ShadowLow);
+ (void)m_controller->setShadowQuality(QDataVis::ShadowQualityLow);
+ updateShadowQuality(QDataVis::ShadowQualityLow);
break;
- case QDataVis::ShadowLow:
+ case QDataVis::ShadowQualityLow:
qWarning("Creating low quality shadows failed. Switching shadows off.");
- (void)m_controller->setShadowQuality(QDataVis::ShadowNone);
+ (void)m_controller->setShadowQuality(QDataVis::ShadowQualityNone);
+ updateShadowQuality(QDataVis::ShadowQualityNone);
+ break;
+ case QDataVis::ShadowQualitySoftHigh:
+ qWarning("Creating soft high quality shadows failed. Changing to soft medium quality.");
+ (void)m_controller->setShadowQuality(QDataVis::ShadowQualitySoftMedium);
+ updateShadowQuality(QDataVis::ShadowQualitySoftMedium);
+ break;
+ case QDataVis::ShadowQualitySoftMedium:
+ qWarning("Creating soft medium quality shadows failed. Changing to soft low quality.");
+ (void)m_controller->setShadowQuality(QDataVis::ShadowQualitySoftLow);
+ updateShadowQuality(QDataVis::ShadowQualitySoftLow);
+ break;
+ case QDataVis::ShadowQualitySoftLow:
+ qWarning("Creating soft low quality shadows failed. Switching shadows off.");
+ (void)m_controller->setShadowQuality(QDataVis::ShadowQualityNone);
+ updateShadowQuality(QDataVis::ShadowQualityNone);
break;
default:
// You'll never get here
@@ -1599,7 +1597,6 @@ void Scatter3DRenderer::updateDepthBuffer()
void Scatter3DRenderer::initBackgroundShaders(const QString &vertexShader,
const QString &fragmentShader)
{
- //qDebug() << __FUNCTION__;
if (m_backgroundShader)
delete m_backgroundShader;
m_backgroundShader = new ShaderHelper(this, vertexShader, fragmentShader);
@@ -1608,11 +1605,19 @@ void Scatter3DRenderer::initBackgroundShaders(const QString &vertexShader,
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
+QVector3D Scatter3DRenderer::indexToSelectionColor(GLint index)
+{
+ GLubyte dotIdxRed = index & 0xff;
+ GLubyte dotIdxGreen = (index & 0xff00) >> 8;
+ GLubyte dotIdxBlue = (index & 0xff0000) >> 16;
+
+ return QVector3D(dotIdxRed, dotIdxGreen, dotIdxBlue);
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavis3d/engine/scatter3drenderer_p.h b/src/datavisualization/engine/scatter3drenderer_p.h
index 45054db4..f444f891 100644
--- a/src/datavis3d/engine/scatter3drenderer_p.h
+++ b/src/datavisualization/engine/scatter3drenderer_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -29,36 +29,25 @@
#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 "datavisualizationglobal_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
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
class ShaderHelper;
class ObjectHelper;
-class TextureHelper;
class LabelItem;
-class CameraHelper;
+class Q3DScene;
class QAbstractAxisPrivate;
-class QT_DATAVIS3D_EXPORT Scatter3DRenderer : public Abstract3DRenderer
+class QT_DATAVISUALIZATION_EXPORT Scatter3DRenderer : public Abstract3DRenderer
{
Q_OBJECT
@@ -69,13 +58,8 @@ private:
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;
@@ -90,7 +74,6 @@ private:
ObjectHelper *m_backgroundObj;
ObjectHelper *m_gridLineObj;
ObjectHelper *m_labelObj;
- TextureHelper *m_textureHelper;
GLuint m_bgrTexture;
GLuint m_depthTexture;
GLuint m_selectionTexture;
@@ -98,60 +81,41 @@ private:
GLuint m_selectionFrameBuffer;
GLuint m_selectionDepthBuffer;
GLfloat m_shadowQualityToShader;
+ GLint m_shadowQualityMultiplier;
GLfloat m_heightNormalizer;
GLfloat m_scaleFactor;
QVector3D m_selection;
+ QVector3D m_previousSelection;
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);
+ void updateScene(Q3DScene *scene);
+ void render(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);
+protected:
+ virtual void initializeOpenGL();
+ virtual void loadMeshFile();
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 drawScene(GLuint defaultFboHandle);
void handleResize();
- void loadBarMesh();
void loadBackgroundMesh();
void loadGridLineMesh();
void loadLabelMesh();
@@ -165,14 +129,27 @@ private:
#endif
void calculateTranslation(ScatterRenderItem &item);
void calculateSceneScalingFactors();
- Scatter3DController::SelectionType isSelected(GLint bar, const QVector3D &selection);
Q_DISABLE_COPY(Scatter3DRenderer)
friend class ScatterRenderItem;
-};
+public slots:
+ void updateBackgroundEnabled(bool enable);
+
+ // Overloaded from abstract renderer
+ virtual void updateAxisRange(Q3DAbstractAxis::AxisOrientation orientation, qreal min, qreal max);
+
+ void updateSelectedItemIndex(int index);
+
+signals:
+ void selectionUpdated(QVector3D selection);
+ void selectedItemIndexChanged(int index);
+
+private:
+ QVector3D indexToSelectionColor(GLint index);
+};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif
diff --git a/src/datavisualization/engine/selectionpointer.cpp b/src/datavisualization/engine/selectionpointer.cpp
new file mode 100644
index 00000000..6c3e0c8b
--- /dev/null
+++ b/src/datavisualization/engine/selectionpointer.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 QtDataVisualization 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 "selectionpointer_p.h"
+#include "surface3dcontroller_p.h"
+#include "shaderhelper_p.h"
+#include "objecthelper_p.h"
+#include "texturehelper_p.h"
+#include "q3dcamera.h"
+#include "q3dcamera_p.h"
+#include "drawer_p.h"
+#include "utils_p.h"
+#include "q3dlight.h"
+
+#include <QImage>
+#include <QMatrix4x4>
+
+#include <QDebug>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+const GLfloat sliceUnits = 2.5;
+
+SelectionPointer::SelectionPointer(Drawer *drawer)
+ : QObject(0),
+ m_labelShader(0),
+ m_pointShader(0),
+ m_labelObj(0),
+ m_pointObj(0),
+ m_textureHelper(0),
+ m_isInitialized(false),
+ m_cachedTheme(drawer->theme()),
+ m_labelStyle(QDataVis::LabelStyleFromTheme),
+ m_drawer(drawer),
+ m_cachedScene(0)
+{
+ initializeOpenGL();
+
+ QObject::connect(m_drawer, &Drawer::drawerChanged,
+ this, &SelectionPointer::handleDrawerChange);
+}
+
+SelectionPointer::~SelectionPointer()
+{
+ delete m_labelShader;
+ delete m_pointShader;
+ delete m_labelObj;
+ delete m_pointObj;
+ delete m_textureHelper;
+}
+
+void SelectionPointer::initializeOpenGL()
+{
+ if (m_isInitialized)
+ return;
+
+ initializeOpenGLFunctions();
+
+ m_textureHelper = new TextureHelper();
+ m_drawer->initializeOpenGL();
+
+ initShaders();
+
+ loadLabelMesh();
+ loadPointMesh();
+
+ // Set initialized -flag
+ m_isInitialized = true;
+}
+
+void SelectionPointer::updateScene(Q3DScene *scene)
+{
+ m_cachedScene = scene;
+}
+
+void SelectionPointer::render(GLuint defaultFboHandle)
+{
+ Q_UNUSED(defaultFboHandle)
+
+ glViewport(m_mainViewPort.x(), m_mainViewPort.y(),
+ m_mainViewPort.width(), m_mainViewPort.height());
+
+ Q3DCamera *camera = m_cachedScene->activeCamera();
+ QSize textureSize = m_labelItem.size();
+
+ QMatrix4x4 itModelMatrix;
+
+ // Get view matrix
+ QMatrix4x4 viewMatrix;
+ QMatrix4x4 projectionMatrix;
+ if (m_cachedIsSlicingActivated) {
+ GLfloat aspect = (GLfloat)m_mainViewPort.width() / (GLfloat)m_mainViewPort.height();
+ viewMatrix.lookAt(QVector3D(0.0f, 0.0f, zComp + 1.0),
+ QVector3D(0.0f, 0.0f, zComp),
+ QVector3D(0.0f, 1.0f, 0.0f));
+ projectionMatrix.ortho(-sliceUnits * aspect, sliceUnits * aspect,
+ -sliceUnits, sliceUnits, -1.0f, 14.0f);
+ } else {
+ viewMatrix = camera->viewMatrix();
+ projectionMatrix.perspective(45.0f, (GLfloat)m_mainViewPort.width()
+ / (GLfloat)m_mainViewPort.height(), 0.1f, 100.0f);
+ }
+
+ // Calculate scale factor to get uniform font size
+ GLfloat scaledFontSize = 0.05f + m_drawer->font().pointSizeF() / 500.0f;
+ GLfloat scaleFactor = scaledFontSize / (GLfloat)textureSize.height();
+
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+
+ // Position the pointer ball
+ modelMatrix.translate(m_position + QVector3D(0.0f, 0.0f, zComp));
+
+ // Scale the point with fixed values (at this point)
+ modelMatrix.scale(QVector3D(0.05f, 0.05f, 0.05f));
+
+ MVPMatrix = projectionMatrix * viewMatrix * modelMatrix;
+
+ // Enable texturing
+ glEnable(GL_TEXTURE_2D);
+
+ QVector3D lightPos = m_cachedScene->activeLight()->position();
+
+ //
+ // Draw the point
+ //
+ m_pointShader->bind();
+ m_pointShader->setUniformValue(m_pointShader->lightP(), lightPos);
+ m_pointShader->setUniformValue(m_pointShader->view(), viewMatrix);
+ m_pointShader->setUniformValue(m_pointShader->model(), modelMatrix);
+ m_pointShader->setUniformValue(m_pointShader->nModel(), itModelMatrix.inverted().transposed());
+ m_pointShader->setUniformValue(m_pointShader->color(),
+ Utils::vectorFromColor(m_cachedTheme.m_highlightBarColor));
+ m_pointShader->setUniformValue(m_pointShader->MVP(), MVPMatrix);
+ m_pointShader->setUniformValue(m_pointShader->ambientS(), m_cachedTheme.m_ambientStrength);
+ m_pointShader->setUniformValue(m_pointShader->lightS(), m_cachedTheme.m_lightStrength * 2.0f);
+
+ m_drawer->drawObject(m_pointShader, m_pointObj);
+
+ m_pointShader->release();
+
+ //
+ // Draw the label
+ //
+ QMatrix4x4 modelMatrixLabel;
+
+ // Position label
+ QVector3D labelAlign(0.0f, 1.0f * scaledFontSize + 0.05f, 0.0f);
+ modelMatrixLabel.translate(m_position + labelAlign + QVector3D(0.0f, 0.0f, zComp));
+
+ // Position the label towards the camera
+ qreal camRotationsX = camera->xRotation();
+ qreal camRotationsY = camera->yRotation();
+ if (!m_cachedIsSlicingActivated) {
+ modelMatrixLabel.rotate(-camRotationsX, 0.0f, 1.0f, 0.0f);
+ modelMatrixLabel.rotate(-camRotationsY, 1.0f, 0.0f, 0.0f);
+ }
+
+ // Scale label based on text size
+ modelMatrixLabel.scale(QVector3D((GLfloat)textureSize.width() * scaleFactor,
+ scaledFontSize,
+ 0.0f));
+
+ // Make label to be always on top
+ glDisable(GL_DEPTH_TEST);
+
+ // Make label transparent
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ m_labelShader->bind();
+
+ // Set shader bindings
+ MVPMatrix = projectionMatrix * viewMatrix * modelMatrixLabel;
+ m_labelShader->setUniformValue(m_labelShader->MVP(), MVPMatrix);
+
+ // Draw the object
+ m_drawer->drawObject(m_labelShader, m_labelObj, m_labelItem.textureId());
+
+ m_labelShader->release();
+
+ // Disable textures
+ glDisable(GL_TEXTURE_2D);
+
+ // Disable transparency
+ glDisable(GL_BLEND);
+
+ // Depth test back to normal
+ glEnable(GL_DEPTH_TEST);
+}
+
+void SelectionPointer::setPosition(QVector3D position)
+{
+ m_position = position;
+}
+
+void SelectionPointer::updateSliceData(bool sliceActivated, GLfloat autoScaleAdjustment)
+{
+ m_cachedIsSlicingActivated = sliceActivated;
+ m_autoScaleAdjustment = autoScaleAdjustment;
+}
+
+void SelectionPointer::setLabel(QString label)
+{
+ m_label = label;
+
+ m_drawer->generateLabelItem(m_labelItem, m_label);
+}
+
+void SelectionPointer::handleDrawerChange()
+{
+ m_cachedTheme = m_drawer->theme();
+ setLabel(m_label);
+}
+
+void SelectionPointer::updateBoundingRect(QRect rect)
+{
+ m_mainViewPort = rect;
+}
+
+void SelectionPointer::initShaders()
+{
+ // The shader for printing the text label
+ if (m_labelShader)
+ delete m_labelShader;
+ m_labelShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexLabel"),
+ QStringLiteral(":/shaders/fragmentLabel"));
+ m_labelShader->initialize();
+
+ // The shader for the small point ball
+ if (m_pointShader)
+ delete m_pointShader;
+#if defined (Q_OS_ANDROID)
+ m_pointShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexES2"),
+ QStringLiteral(":/shaders/fragmentES2"));
+#else
+ m_pointShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertex"),
+ QStringLiteral(":/shaders/fragment"));
+#endif
+ m_pointShader->initialize();
+
+}
+
+void SelectionPointer::loadLabelMesh()
+{
+ if (m_labelObj)
+ delete m_labelObj;
+ m_labelObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/label"));
+ m_labelObj->load();
+}
+
+void SelectionPointer::loadPointMesh()
+{
+ if (m_pointObj)
+ delete m_pointObj;
+ m_pointObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/sphereSmooth"));
+ m_pointObj->load();
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualization/engine/selectionpointer_p.h b/src/datavisualization/engine/selectionpointer_p.h
new file mode 100644
index 00000000..0e766035
--- /dev/null
+++ b/src/datavisualization/engine/selectionpointer_p.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 QtDataVisualization 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 NOTIFICATIONLABEL_P_H
+#define NOTIFICATIONLABEL_P_H
+
+#include <QtCore/QObject>
+#include <QtGui/QOpenGLFunctions>
+#include <QtGui/QFont>
+#include <QWindow>
+#include <QVector3D>
+
+#include "q3dscene.h"
+#include "datavisualizationglobal_p.h"
+#include "surface3dcontroller_p.h"
+
+class QOpenGLShaderProgram;
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class ShaderHelper;
+class ObjectHelper;
+class SurfaceObject;
+class TextureHelper;
+class Theme;
+class Drawer;
+class Q3DCamera;
+
+class QT_DATAVISUALIZATION_EXPORT SelectionPointer : public QObject, protected QOpenGLFunctions
+{
+ Q_OBJECT
+
+public:
+ explicit SelectionPointer(Drawer *drawer);
+ ~SelectionPointer();
+
+ void initializeOpenGL();
+ void render(GLuint defaultFboHandle = 0);
+ void setPosition(QVector3D position);
+ void setLabel(QString label);
+ void handleDrawerChange();
+ void updateBoundingRect(QRect rect);
+ void updateScene(Q3DScene *scene);
+ void updateSliceData(bool sliceActivated, GLfloat autoScaleAdjustment);
+
+private:
+ void initShaders();
+ void loadLabelMesh();
+ void loadPointMesh();
+
+private:
+ ShaderHelper *m_labelShader;
+ ShaderHelper *m_pointShader;
+ ObjectHelper *m_labelObj;
+ ObjectHelper *m_pointObj;
+ TextureHelper *m_textureHelper;
+ bool m_isInitialized;
+ Theme m_cachedTheme;
+ QDataVis::LabelStyle m_labelStyle;
+ LabelItem m_labelItem;
+ Drawer *m_drawer;
+ QRect m_mainViewPort;
+ QVector3D m_position;
+ Q3DScene *m_cachedScene;
+ QString m_label;
+ bool m_cachedIsSlicingActivated;
+ GLfloat m_autoScaleAdjustment;
+};
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
+#endif // NOTIFICATIONLABEL_P_H
diff --git a/src/datavis3d/engine/shaders/ambient.frag b/src/datavisualization/engine/shaders/ambient.frag
index 88f850f3..88f850f3 100644
--- a/src/datavis3d/engine/shaders/ambient.frag
+++ b/src/datavisualization/engine/shaders/ambient.frag
diff --git a/src/datavis3d/engine/shaders/colorOnY.frag b/src/datavisualization/engine/shaders/colorOnY.frag
index ee57e8e5..80e54a61 100644
--- a/src/datavis3d/engine/shaders/colorOnY.frag
+++ b/src/datavisualization/engine/shaders/colorOnY.frag
@@ -12,7 +12,8 @@ varying highp vec3 lightDirection_cmr;
varying highp vec2 coords_mdl;
void main() {
- highp vec3 materialDiffuseColor = vec3(coords_mdl.y * color_mdl.x, coords_mdl.y * color_mdl.y, coords_mdl.y * color_mdl.z);
+ highp float heightMod = (coords_mdl.y * 0.3) + 0.7; // Add 30% black to the bottom
+ highp vec3 materialDiffuseColor = heightMod * color_mdl;
highp vec3 materialAmbientColor = vec3(ambientStrength, ambientStrength, ambientStrength) * materialDiffuseColor;
highp vec3 materialSpecularColor = vec3(1.0, 1.0, 1.0);
@@ -27,7 +28,9 @@ void main() {
gl_FragColor.rgb =
materialAmbientColor +
- materialDiffuseColor * lightStrength * (cosTheta * cosTheta) / (distance * distance) +
- materialSpecularColor * lightStrength * pow(cosAlpha, 5) / (distance * distance);
+ materialDiffuseColor * lightStrength * (cosTheta * cosTheta) / distance +
+ materialSpecularColor * lightStrength * pow(cosAlpha, 5) / distance;
+ gl_FragColor.rgb = clamp(gl_FragColor.rgb, 0.0, 1.0);
+ gl_FragColor.a = 1.0;
}
diff --git a/src/datavis3d/engine/shaders/colorOnY_ES2.frag b/src/datavisualization/engine/shaders/colorOnY_ES2.frag
index 68c8ac39..aba52cfe 100644
--- a/src/datavis3d/engine/shaders/colorOnY_ES2.frag
+++ b/src/datavisualization/engine/shaders/colorOnY_ES2.frag
@@ -10,7 +10,8 @@ varying highp vec3 lightDirection_cmr;
varying highp vec2 coords_mdl;
void main() {
- highp vec3 materialDiffuseColor = vec3(coords_mdl.y * color_mdl.x, coords_mdl.y * color_mdl.y, coords_mdl.y * color_mdl.z);
+ highp float heightMod = (coords_mdl.y * 0.3) + 0.7; // Add 30% black to the bottom
+ highp vec3 materialDiffuseColor = heightMod * color_mdl;
highp vec3 materialAmbientColor = vec3(ambientStrength, ambientStrength, ambientStrength) * materialDiffuseColor;
highp vec3 materialSpecularColor = vec3(1.0, 1.0, 1.0);
@@ -29,8 +30,8 @@ void main() {
gl_FragColor.rgb =
materialAmbientColor +
- materialDiffuseColor * lightStrength * (cosTheta * cosTheta) / (distance * distance) +
- materialSpecularColor * lightStrength * (cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha) / (distance * distance);
+ materialDiffuseColor * lightStrength * (cosTheta * cosTheta) / distance +
+ materialSpecularColor * lightStrength * (cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha) / distance;
gl_FragColor.a = 1.0;
}
diff --git a/src/datavis3d/engine/shaders/default.frag b/src/datavisualization/engine/shaders/default.frag
index 5bf9c654..fba1ce4a 100644
--- a/src/datavis3d/engine/shaders/default.frag
+++ b/src/datavisualization/engine/shaders/default.frag
@@ -30,7 +30,7 @@ void main() {
gl_FragColor.rgb =
materialAmbientColor +
materialDiffuseColor * lightStrength * pow(cosTheta, 2) / distance +
- materialSpecularColor * lightStrength * pow(cosAlpha, 10) / distance;
+ materialSpecularColor * lightStrength * pow(cosAlpha, 5) / distance;
gl_FragColor.a = 1.0;
}
diff --git a/src/datavis3d/engine/shaders/default.vert b/src/datavisualization/engine/shaders/default.vert
index 14f77773..14f77773 100644
--- a/src/datavis3d/engine/shaders/default.vert
+++ b/src/datavisualization/engine/shaders/default.vert
diff --git a/src/datavis3d/engine/shaders/default_ES2.frag b/src/datavisualization/engine/shaders/default_ES2.frag
index a70ed241..7d6214b2 100644
--- a/src/datavis3d/engine/shaders/default_ES2.frag
+++ b/src/datavisualization/engine/shaders/default_ES2.frag
@@ -32,7 +32,7 @@ void main() {
gl_FragColor.rgb =
materialAmbientColor +
materialDiffuseColor * lightStrength * (cosTheta * cosTheta) / distance +
- materialSpecularColor * lightStrength * (cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha) / distance;
+ materialSpecularColor * lightStrength * (cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha) / distance;
gl_FragColor.a = 1.0;
}
diff --git a/src/datavis3d/engine/shaders/default_ES2.vert b/src/datavisualization/engine/shaders/default_ES2.vert
index efb40862..efb40862 100644
--- a/src/datavis3d/engine/shaders/default_ES2.vert
+++ b/src/datavisualization/engine/shaders/default_ES2.vert
diff --git a/src/datavis3d/engine/shaders/depth.frag b/src/datavisualization/engine/shaders/depth.frag
index 5cfd4b10..5cfd4b10 100644
--- a/src/datavis3d/engine/shaders/depth.frag
+++ b/src/datavisualization/engine/shaders/depth.frag
diff --git a/src/datavis3d/engine/shaders/depth.vert b/src/datavisualization/engine/shaders/depth.vert
index 9fe5a193..9fe5a193 100644
--- a/src/datavis3d/engine/shaders/depth.vert
+++ b/src/datavisualization/engine/shaders/depth.vert
diff --git a/src/datavis3d/engine/shaders/label.frag b/src/datavisualization/engine/shaders/label.frag
index 86021410..86021410 100644
--- a/src/datavis3d/engine/shaders/label.frag
+++ b/src/datavisualization/engine/shaders/label.frag
diff --git a/src/datavis3d/engine/shaders/label.vert b/src/datavisualization/engine/shaders/label.vert
index b4debe53..b4debe53 100644
--- a/src/datavis3d/engine/shaders/label.vert
+++ b/src/datavisualization/engine/shaders/label.vert
diff --git a/src/datavis3d/engine/shaders/selection.frag b/src/datavisualization/engine/shaders/selection.frag
index 099c87a1..099c87a1 100644
--- a/src/datavis3d/engine/shaders/selection.frag
+++ b/src/datavisualization/engine/shaders/selection.frag
diff --git a/src/datavis3d/engine/shaders/selection.vert b/src/datavisualization/engine/shaders/selection.vert
index 64d17e15..64d17e15 100644
--- a/src/datavis3d/engine/shaders/selection.vert
+++ b/src/datavisualization/engine/shaders/selection.vert
diff --git a/src/datavis3d/engine/shaders/shadow.frag b/src/datavisualization/engine/shaders/shadow.frag
index 919cedee..5309b5bb 100644
--- a/src/datavis3d/engine/shaders/shadow.frag
+++ b/src/datavisualization/engine/shaders/shadow.frag
@@ -13,22 +13,22 @@ varying highp vec3 normal_cmr;
varying highp vec3 eyeDirection_cmr;
varying highp vec3 lightDirection_cmr;
-const highp vec2 poissonDisk[16] = vec2[](vec2(-0.94201624, -0.39906216),
- vec2(0.94558609, -0.76890725),
- vec2(-0.094184101, -0.92938870),
- vec2(0.34495938, 0.29387760),
- vec2(-0.91588581, 0.45771432),
- vec2(-0.81544232, -0.87912464),
- vec2(-0.38277543, 0.27676845),
- vec2(0.97484398, 0.75648379),
- vec2(0.44323325, -0.97511554),
- vec2(0.53742981, -0.47373420),
- vec2(-0.26496911, -0.41893023),
- vec2(0.79197514, 0.19090188),
- vec2(-0.24188840, 0.99706507),
- vec2(-0.81409955, 0.91437590),
- vec2(0.19984126, 0.78641367),
- vec2(0.14383161, -0.14100790));
+highp vec2 poissonDisk[16] = vec2[16](vec2(-0.94201624, -0.39906216),
+ vec2(0.94558609, -0.76890725),
+ vec2(-0.094184101, -0.92938870),
+ vec2(0.34495938, 0.29387760),
+ vec2(-0.91588581, 0.45771432),
+ vec2(-0.81544232, -0.87912464),
+ vec2(-0.38277543, 0.27676845),
+ vec2(0.97484398, 0.75648379),
+ vec2(0.44323325, -0.97511554),
+ vec2(0.53742981, -0.47373420),
+ vec2(-0.26496911, -0.41893023),
+ vec2(0.79197514, 0.19090188),
+ vec2(-0.24188840, 0.99706507),
+ vec2(-0.81409955, 0.91437590),
+ vec2(0.19984126, 0.78641367),
+ vec2(0.14383161, -0.14100790));
/*float random(vec3 seed, int i) {
vec4 seed4 = vec4(seed, i);
@@ -58,7 +58,7 @@ void main() {
// direct method; needs large shadow texture to look good
//highp float visibility = 0.75 * shadow2DProj(shadowMap, shadCoords).r + 0.25;
// poisson disk sampling; smoothes edges
- highp float visibility = 0.4;
+ highp float visibility = 0.6;
for (int i = 0; i < 15; i++) {
vec4 shadCoordsPD = shadCoords;
shadCoordsPD.x += cos(poissonDisk[i].x) / shadowQuality;
diff --git a/src/datavis3d/engine/shaders/shadow.vert b/src/datavisualization/engine/shaders/shadow.vert
index e29a8a30..e29a8a30 100644
--- a/src/datavis3d/engine/shaders/shadow.vert
+++ b/src/datavisualization/engine/shaders/shadow.vert
diff --git a/src/datavis3d/engine/shaders/shadowNoTex.frag b/src/datavisualization/engine/shaders/shadowNoTex.frag
index 50f900ba..0252ba49 100644
--- a/src/datavis3d/engine/shaders/shadowNoTex.frag
+++ b/src/datavisualization/engine/shaders/shadowNoTex.frag
@@ -7,45 +7,44 @@ uniform highp vec3 color_mdl;
uniform highp sampler2DShadow shadowMap;
varying highp vec4 shadowCoord;
-varying highp vec2 UV;
varying highp vec3 position_wrld;
varying highp vec3 normal_cmr;
varying highp vec3 eyeDirection_cmr;
varying highp vec3 lightDirection_cmr;
-const highp vec2 poissonDisk[16] = vec2[](vec2(-0.94201624, -0.39906216),
- vec2(0.94558609, -0.76890725),
- vec2(-0.094184101, -0.92938870),
- vec2(0.34495938, 0.29387760),
- vec2(-0.91588581, 0.45771432),
- vec2(-0.81544232, -0.87912464),
- vec2(-0.38277543, 0.27676845),
- vec2(0.97484398, 0.75648379),
- vec2(0.44323325, -0.97511554),
- vec2(0.53742981, -0.47373420),
- vec2(-0.26496911, -0.41893023),
- vec2(0.79197514, 0.19090188),
- vec2(-0.24188840, 0.99706507),
- vec2(-0.81409955, 0.91437590),
- vec2(0.19984126, 0.78641367),
- vec2(0.14383161, -0.14100790));
+highp vec2 poissonDisk[16] = vec2[16](vec2(-0.94201624, -0.39906216),
+ vec2(0.94558609, -0.76890725),
+ vec2(-0.094184101, -0.92938870),
+ vec2(0.34495938, 0.29387760),
+ vec2(-0.91588581, 0.45771432),
+ vec2(-0.81544232, -0.87912464),
+ vec2(-0.38277543, 0.27676845),
+ vec2(0.97484398, 0.75648379),
+ vec2(0.44323325, -0.97511554),
+ vec2(0.53742981, -0.47373420),
+ vec2(-0.26496911, -0.41893023),
+ vec2(0.79197514, 0.19090188),
+ vec2(-0.24188840, 0.99706507),
+ vec2(-0.81409955, 0.91437590),
+ vec2(0.19984126, 0.78641367),
+ vec2(0.14383161, -0.14100790));
-/*const highp vec2 poissonDisk[16] = vec2[](vec2(-0.25, -0.25),
- vec2(0.25, -0.25),
- vec2(-0.25, 0.25),
- vec2(0.25, 0.25),
- vec2(-0.5, -0.5),
- vec2(0.5, -0.5),
- vec2(-0.5, 0.5),
- vec2(0.5, 0.5),
- vec2(-0.75, -0.75),
- vec2(0.75, -0.75),
- vec2(-0.75, 0.75),
- vec2(0.75, 0.75),
- vec2(-1.0, -1.0),
- vec2(1.0, -1.0),
- vec2(-1.0, 1.0),
- vec2(1.0, 1.0));*/
+/*highp vec2 poissonDisk[16] = vec2[16](vec2(-0.25, -0.25),
+ vec2(0.25, -0.25),
+ vec2(-0.25, 0.25),
+ vec2(0.25, 0.25),
+ vec2(-0.5, -0.5),
+ vec2(0.5, -0.5),
+ vec2(-0.5, 0.5),
+ vec2(0.5, 0.5),
+ vec2(-0.75, -0.75),
+ vec2(0.75, -0.75),
+ vec2(-0.75, 0.75),
+ vec2(0.75, 0.75),
+ vec2(-1.0, -1.0),
+ vec2(1.0, -1.0),
+ vec2(-1.0, 1.0),
+ vec2(1.0, 1.0));*/
/*float random(vec3 seed, int i) {
vec4 seed4 = vec4(seed, i);
@@ -75,7 +74,7 @@ void main() {
// direct method; needs large shadow texture to look good
//highp float visibility = 0.75 * shadow2DProj(shadowMap, shadCoords).r + 0.25;
// poisson disk sampling; smoothes edges
- highp float visibility = 0.4;
+ highp float visibility = 0.6;
for (int i = 0; i < 15; i++) {
vec4 shadCoordsPD = shadCoords;
shadCoordsPD.x += cos(poissonDisk[i].x) / shadowQuality;
diff --git a/src/datavis3d/engine/shaders/shadowNoTexColorOnY.frag b/src/datavisualization/engine/shaders/shadowNoTexColorOnY.frag
index 75f0e6d3..68ba2368 100644
--- a/src/datavis3d/engine/shaders/shadowNoTexColorOnY.frag
+++ b/src/datavisualization/engine/shaders/shadowNoTexColorOnY.frag
@@ -13,22 +13,22 @@ varying highp vec3 eyeDirection_cmr;
varying highp vec3 lightDirection_cmr;
varying highp vec2 coords_mdl;
-const highp vec2 poissonDisk[16] = vec2[](vec2(-0.94201624, -0.39906216),
- vec2(0.94558609, -0.76890725),
- vec2(-0.094184101, -0.92938870),
- vec2(0.34495938, 0.29387760),
- vec2(-0.91588581, 0.45771432),
- vec2(-0.81544232, -0.87912464),
- vec2(-0.38277543, 0.27676845),
- vec2(0.97484398, 0.75648379),
- vec2(0.44323325, -0.97511554),
- vec2(0.53742981, -0.47373420),
- vec2(-0.26496911, -0.41893023),
- vec2(0.79197514, 0.19090188),
- vec2(-0.24188840, 0.99706507),
- vec2(-0.81409955, 0.91437590),
- vec2(0.19984126, 0.78641367),
- vec2(0.14383161, -0.14100790));
+highp vec2 poissonDisk[16] = vec2[16](vec2(-0.94201624, -0.39906216),
+ vec2(0.94558609, -0.76890725),
+ vec2(-0.094184101, -0.92938870),
+ vec2(0.34495938, 0.29387760),
+ vec2(-0.91588581, 0.45771432),
+ vec2(-0.81544232, -0.87912464),
+ vec2(-0.38277543, 0.27676845),
+ vec2(0.97484398, 0.75648379),
+ vec2(0.44323325, -0.97511554),
+ vec2(0.53742981, -0.47373420),
+ vec2(-0.26496911, -0.41893023),
+ vec2(0.79197514, 0.19090188),
+ vec2(-0.24188840, 0.99706507),
+ vec2(-0.81409955, 0.91437590),
+ vec2(0.19984126, 0.78641367),
+ vec2(0.14383161, -0.14100790));
/*float random(vec3 seed, int i) {
vec4 seed4 = vec4(seed, i);
@@ -37,7 +37,8 @@ const highp vec2 poissonDisk[16] = vec2[](vec2(-0.94201624, -0.39906216),
}*/
void main() {
- highp vec3 materialDiffuseColor = vec3(coords_mdl.y * color_mdl.x, coords_mdl.y * color_mdl.y, coords_mdl.y * color_mdl.z);
+ highp float heightMod = (coords_mdl.y * 0.3) + 0.7; // Add 30% black to the bottom
+ highp vec3 materialDiffuseColor = heightMod * color_mdl;
highp vec3 materialAmbientColor = vec3(ambientStrength, ambientStrength, ambientStrength) * materialDiffuseColor;
highp vec3 materialSpecularColor = vec3(1.0, 1.0, 1.0);
@@ -58,7 +59,7 @@ void main() {
// direct method; needs large shadow texture to look good
//highp float visibility = 0.75 * shadow2DProj(shadowMap, shadCoords).r + 0.25;
// poisson disk sampling; smoothes edges
- highp float visibility = 0.4;
+ highp float visibility = 0.6;
for (int i = 0; i < 15; i++) {
vec4 shadCoordsPD = shadCoords;
shadCoordsPD.x += cos(poissonDisk[i].x) / shadowQuality;
@@ -76,5 +77,6 @@ void main() {
visibility * (materialAmbientColor +
materialDiffuseColor * lightStrength * cosTheta +
materialSpecularColor * lightStrength * pow(cosAlpha, 10));
+ gl_FragColor.rgb = clamp(gl_FragColor.rgb, 0.0, 1.0);
gl_FragColor.a = 1.0;
}
diff --git a/src/datavis3d/engine/shaders/surface.frag b/src/datavisualization/engine/shaders/surface.frag
index 9fe7f45b..4b1357b1 100644
--- a/src/datavis3d/engine/shaders/surface.frag
+++ b/src/datavisualization/engine/shaders/surface.frag
@@ -1,6 +1,5 @@
#version 120
-varying highp vec2 UV;
varying highp vec3 coords_mdl;
varying highp vec3 position_wrld;
varying highp vec3 normal_cmr;
@@ -13,7 +12,7 @@ uniform highp float lightStrength;
uniform highp float ambientStrength;
void main() {
- highp vec2 gradientUV = vec2(0.5, (coords_mdl.y + 1.0) / 2.0);
+ highp vec2 gradientUV = vec2(0.0, (coords_mdl.y + 1.001) / 2.0); // 1000 pixel texture, we need a margin for 1/1000 rounding error
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);
@@ -28,12 +27,10 @@ void main() {
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/datavisualization/engine/shaders/surface.vert
index cbfb7569..28152abc 100644
--- a/src/datavis3d/engine/shaders/surface.vert
+++ b/src/datavisualization/engine/shaders/surface.vert
@@ -1,7 +1,4 @@
-#version 120
-
attribute highp vec3 vertexPosition_mdl;
-attribute highp vec2 vertexUV;
attribute highp vec3 vertexNormal_mdl;
uniform highp mat4 MVP;
@@ -10,7 +7,6 @@ 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;
@@ -26,5 +22,4 @@ void main() {
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/datavisualization/engine/shaders/surfaceFlat.frag
index eb398582..a8a3dbb1 100644
--- a/src/datavis3d/engine/shaders/surfaceFlat.frag
+++ b/src/datavisualization/engine/shaders/surfaceFlat.frag
@@ -1,6 +1,5 @@
#version 150
-varying highp vec2 UV;
varying highp vec3 coords_mdl;
varying highp vec3 position_wrld;
flat in highp vec3 normal_cmr;
@@ -13,7 +12,7 @@ uniform highp float lightStrength;
uniform highp float ambientStrength;
void main() {
- highp vec2 gradientUV = vec2(0.5, (coords_mdl.y + 1.0) / 2.0);
+ highp vec2 gradientUV = vec2(0.0, (coords_mdl.y + 1.001) / 2.0); // 1000 pixel texture, we need a margin for 1/1000 rounding error
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);
@@ -28,7 +27,6 @@ void main() {
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 +
diff --git a/src/datavis3d/engine/shaders/surfaceFlat.vert b/src/datavisualization/engine/shaders/surfaceFlat.vert
index 24c9b9a3..7e248d02 100644
--- a/src/datavis3d/engine/shaders/surfaceFlat.vert
+++ b/src/datavisualization/engine/shaders/surfaceFlat.vert
@@ -1,7 +1,6 @@
#version 150
attribute highp vec3 vertexPosition_mdl;
-attribute highp vec2 vertexUV;
attribute highp vec3 vertexNormal_mdl;
uniform highp mat4 MVP;
@@ -10,7 +9,6 @@ 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;
@@ -26,5 +24,4 @@ void main() {
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/datavisualization/engine/shaders/surfaceGrid.frag b/src/datavisualization/engine/shaders/surfaceGrid.frag
new file mode 100644
index 00000000..1658b316
--- /dev/null
+++ b/src/datavisualization/engine/shaders/surfaceGrid.frag
@@ -0,0 +1,6 @@
+uniform highp vec3 color_mdl;
+
+void main() {
+ gl_FragColor.rgb = color_mdl;
+}
+
diff --git a/src/datavisualization/engine/shaders/surfaceGrid.vert b/src/datavisualization/engine/shaders/surfaceGrid.vert
new file mode 100644
index 00000000..5582d633
--- /dev/null
+++ b/src/datavisualization/engine/shaders/surfaceGrid.vert
@@ -0,0 +1,6 @@
+attribute highp vec3 vertexPosition_mdl;
+uniform highp mat4 MVP;
+
+void main() {
+ gl_Position = MVP * vec4(vertexPosition_mdl, 1.0);
+}
diff --git a/src/datavisualization/engine/shaders/surface_ES2.frag b/src/datavisualization/engine/shaders/surface_ES2.frag
new file mode 100644
index 00000000..a9aec528
--- /dev/null
+++ b/src/datavisualization/engine/shaders/surface_ES2.frag
@@ -0,0 +1,39 @@
+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 = dot(n, l);
+ if (cosTheta < 0.0) cosTheta = 0.0;
+ else if (cosTheta > 1.0) cosTheta = 1.0;
+
+ highp vec3 E = normalize(eyeDirection_cmr);
+ highp vec3 R = reflect(-l, n);
+ highp float cosAlpha = dot(E, R);
+ if (cosAlpha < 0.0) cosAlpha = 0.0;
+ else if (cosAlpha > 1.0) cosAlpha = 1.0;
+
+ gl_FragColor.rgb =
+ materialAmbientColor +
+ materialDiffuseColor * lightStrength * cosTheta * cosTheta / distance +
+ materialSpecularColor * lightStrength * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha / distance;
+ gl_FragColor.a = 1.0;
+}
+
diff --git a/src/datavis3d/engine/shaders/texture.frag b/src/datavisualization/engine/shaders/texture.frag
index a6d7b2eb..a6d7b2eb 100644
--- a/src/datavis3d/engine/shaders/texture.frag
+++ b/src/datavisualization/engine/shaders/texture.frag
diff --git a/src/datavis3d/engine/shaders/texture.vert b/src/datavisualization/engine/shaders/texture.vert
index 01f922e0..01f922e0 100644
--- a/src/datavis3d/engine/shaders/texture.vert
+++ b/src/datavisualization/engine/shaders/texture.vert
diff --git a/src/datavis3d/engine/shaders/texture_ES2.frag b/src/datavisualization/engine/shaders/texture_ES2.frag
index 16161035..58097ba5 100644
--- a/src/datavis3d/engine/shaders/texture_ES2.frag
+++ b/src/datavisualization/engine/shaders/texture_ES2.frag
@@ -31,7 +31,7 @@ void main() {
gl_FragColor.rgb =
materialAmbientColor +
materialDiffuseColor * lightStrength * (cosTheta * cosTheta) / distance +
- materialSpecularColor * lightStrength * (cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha) / distance;
+ materialSpecularColor * lightStrength * (cosAlpha * cosAlpha * cosAlpha * cosAlpha * cosAlpha) / distance;
gl_FragColor.a = texture2D(textureSampler, UV).a;
}
diff --git a/src/datavisualization/engine/surface3dcontroller.cpp b/src/datavisualization/engine/surface3dcontroller.cpp
new file mode 100644
index 00000000..2272b731
--- /dev/null
+++ b/src/datavisualization/engine/surface3dcontroller.cpp
@@ -0,0 +1,233 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 "q3dabstractaxis_p.h"
+#include "q3dvalueaxis_p.h"
+#include "q3dcategoryaxis.h"
+#include "qsurfacedataproxy_p.h"
+
+#include <QMatrix4x4>
+
+#include <QDebug>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+Surface3DController::Surface3DController(QRect rect)
+ : Abstract3DController(rect),
+ m_renderer(0),
+ m_isSmoothSurfaceEnabled(false),
+ m_isSurfaceGridEnabled(true)
+{
+ setActiveDataProxy(0);
+
+ // Setting a null axis creates a new default axis according to orientation and graph type.
+ // Note: These cannot be set in Abstract3DController constructor, as they will call virtual
+ // functions implemented by subclasses.
+ setAxisX(0);
+ setAxisY(0);
+ setAxisZ(0);
+
+ // Set the default from the theme
+ m_userDefinedGradient = theme().m_surfaceGradient;
+}
+
+Surface3DController::~Surface3DController()
+{
+}
+
+void Surface3DController::initializeOpenGL()
+{
+ // Initialization is called multiple times when Qt Quick components are used
+ if (isInitialized())
+ return;
+
+ m_renderer = new Surface3DRenderer(this);
+ setRenderer(m_renderer);
+ synchDataToRenderer();
+ emitNeedRender();
+}
+
+void Surface3DController::synchDataToRenderer()
+{
+ Abstract3DController::synchDataToRenderer();
+
+ if (!isInitialized())
+ return;
+
+ // Notify changes to renderer
+ if (m_changeTracker.gradientColorChanged) {
+ m_renderer->updateSurfaceGradient(m_userDefinedGradient);
+ m_changeTracker.gradientColorChanged = false;
+ }
+
+ if (m_changeTracker.smoothStatusChanged) {
+ m_isSmoothSurfaceEnabled = m_renderer->updateSmoothStatus(m_isSmoothSurfaceEnabled);
+ m_changeTracker.smoothStatusChanged = false;
+ }
+
+ if (m_changeTracker.surfaceGridChanged) {
+ m_renderer->updateSurfaceGridStatus(m_isSurfaceGridEnabled);
+ m_changeTracker.surfaceGridChanged = false;
+ }
+
+ if (m_isDataDirty) {
+ m_renderer->updateDataModel(static_cast<QSurfaceDataProxy *>(m_data));
+ m_isDataDirty = false;
+ }
+}
+
+void Surface3DController::handleAxisAutoAdjustRangeChangedInOrientation(Q3DAbstractAxis::AxisOrientation orientation, bool autoAdjust)
+{
+ Q_UNUSED(orientation)
+ Q_UNUSED(autoAdjust)
+
+ adjustValueAxisRange();
+}
+
+void Surface3DController::handleAxisRangeChangedBySender(QObject *sender)
+{
+ scene()->setSlicingActive(false);
+ Abstract3DController::handleAxisRangeChangedBySender(sender);
+}
+
+void Surface3DController::setSmoothSurface(bool enable)
+{
+ m_isSmoothSurfaceEnabled = enable;
+ m_changeTracker.smoothStatusChanged = true;
+ emitNeedRender();
+}
+
+bool Surface3DController::smoothSurface()
+{
+ return m_isSmoothSurfaceEnabled;
+}
+
+void Surface3DController::setSurfaceGrid(bool enable)
+{
+ m_isSurfaceGridEnabled = enable;
+ m_changeTracker.surfaceGridChanged = true;
+ emitNeedRender();
+}
+
+bool Surface3DController::surfaceGrid()
+{
+ return m_isSurfaceGridEnabled;
+}
+
+void Surface3DController::setGradient(const QLinearGradient &gradient)
+{
+ m_userDefinedGradient = gradient;
+ m_userDefinedGradient.setStart(1, 1000);
+ m_userDefinedGradient.setFinalStop(0, 0);
+ m_changeTracker.gradientColorChanged = true;
+ emitNeedRender();
+}
+
+QLinearGradient Surface3DController::gradient() const
+{
+ return m_userDefinedGradient;
+}
+
+void Surface3DController::setGradientColorAt(qreal pos, const QColor &color)
+{
+ m_userDefinedGradient.setColorAt(pos, color);
+ m_changeTracker.gradientColorChanged = true;
+ emitNeedRender();
+}
+
+void Surface3DController::setSelectionMode(QDataVis::SelectionMode mode)
+{
+ if (!(mode == QDataVis::SelectionModeNone || mode == QDataVis::SelectionModeItem
+ || mode == QDataVis::SelectionModeSliceRow
+ || mode == QDataVis::SelectionModeSliceColumn)) {
+ qWarning("Unsupported selection mode.");
+ return;
+ }
+ // Disable zoom if selection mode changes
+ setSlicingActive(false);
+ Abstract3DController::setSelectionMode(mode);
+}
+
+
+void Surface3DController::setActiveDataProxy(QAbstractDataProxy *proxy)
+{
+ // Setting null proxy indicates default proxy
+ if (!proxy) {
+ proxy = new QSurfaceDataProxy;
+ proxy->d_ptr->setDefaultProxy(true);
+ }
+
+ Q_ASSERT(proxy->type() == QAbstractDataProxy::DataTypeSurface);
+
+ Abstract3DController::setActiveDataProxy(proxy);
+
+ QSurfaceDataProxy *surfaceDataProxy = static_cast<QSurfaceDataProxy *>(m_data);
+
+ QObject::connect(surfaceDataProxy, &QSurfaceDataProxy::arrayReset,
+ this, &Surface3DController::handleArrayReset);
+
+ scene()->setSlicingActive(false);
+ adjustValueAxisRange();
+ m_isDataDirty = true;
+ emitNeedRender();
+}
+
+void Surface3DController::handleArrayReset()
+{
+ scene()->setSlicingActive(false);
+ adjustValueAxisRange();
+ m_isDataDirty = true;
+ emitNeedRender();
+}
+
+void Surface3DController::adjustValueAxisRange()
+{
+ if (m_data) {
+ QVector3D minLimits;
+ QVector3D maxLimits;
+ static_cast<QSurfaceDataProxy *>(m_data)->dptr()->limitValues(minLimits, maxLimits);
+ Q3DValueAxis *valueAxis = static_cast<Q3DValueAxis *>(m_axisX);
+ if (valueAxis && valueAxis->isAutoAdjustRange()) {
+ if (minLimits.x() != maxLimits.x())
+ valueAxis->dptr()->setRange(minLimits.x(), maxLimits.x());
+ else
+ valueAxis->dptr()->setRange(minLimits.x() - 1.0f, minLimits.x() + 1.0f); // Default to some valid range
+ }
+
+ valueAxis = static_cast<Q3DValueAxis *>(m_axisY);
+ if (valueAxis && valueAxis->isAutoAdjustRange()) {
+ if (minLimits.y() != maxLimits.y())
+ valueAxis->dptr()->setRange(minLimits.y(), maxLimits.y());
+ else
+ valueAxis->dptr()->setRange(minLimits.y() - 1.0f, minLimits.y() + 1.0f); // Default to some valid range
+ }
+
+ valueAxis = static_cast<Q3DValueAxis *>(m_axisZ);
+ if (valueAxis && valueAxis->isAutoAdjustRange()) {
+ if (minLimits.z() != maxLimits.z())
+ valueAxis->dptr()->setRange(minLimits.z(), maxLimits.z());
+ else
+ valueAxis->dptr()->setRange(minLimits.z() - 1.0f, minLimits.z() + 1.0f); // Default to some valid range
+ }
+ }
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualization/engine/surface3dcontroller_p.h b/src/datavisualization/engine/surface3dcontroller_p.h
new file mode 100644
index 00000000..0efece97
--- /dev/null
+++ b/src/datavisualization/engine/surface3dcontroller_p.h
@@ -0,0 +1,108 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 QtDataVisualization 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 "datavisualizationglobal_p.h"
+
+#include <QLinearGradient>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class Surface3DRenderer;
+
+struct Surface3DChangeBitField {
+ bool gradientColorChanged : 1;
+ bool smoothStatusChanged : 1;
+ bool surfaceGridChanged : 1;
+
+ Surface3DChangeBitField() :
+ gradientColorChanged(true),
+ smoothStatusChanged(true),
+ surfaceGridChanged(true)
+ {
+ }
+};
+
+class QT_DATAVISUALIZATION_EXPORT Surface3DController : public Abstract3DController
+{
+ Q_OBJECT
+
+private:
+ Surface3DChangeBitField m_changeTracker;
+
+ // Rendering
+ Surface3DRenderer *m_renderer;
+ bool m_isSmoothSurfaceEnabled;
+ bool m_isSurfaceGridEnabled;
+ QLinearGradient m_userDefinedGradient;
+
+public:
+ explicit Surface3DController(QRect rect);
+ ~Surface3DController();
+
+ void initializeOpenGL();
+ virtual void synchDataToRenderer();
+
+ void setSmoothSurface(bool enable);
+ bool smoothSurface();
+
+ void setSurfaceGrid(bool enable);
+ bool surfaceGrid();
+
+ void setGradient(const QLinearGradient &gradient);
+ QLinearGradient gradient() const;
+
+ void setGradientColorAt(qreal pos, const QColor &color);
+
+ void setSelectionMode(QDataVis::SelectionMode mode);
+
+ virtual void setActiveDataProxy(QAbstractDataProxy *proxy);
+
+ virtual void handleAxisAutoAdjustRangeChangedInOrientation(Q3DAbstractAxis::AxisOrientation orientation, bool autoAdjust);
+ virtual void handleAxisRangeChangedBySender(QObject *sender);
+
+public slots:
+ void handleArrayReset();
+
+signals:
+ void smoothStatusChanged(bool enable);
+ void surfaceGridChanged(bool enable);
+ void segmentCountChanged(GLint segmentCount, GLfloat step, GLfloat minimum);
+
+private:
+ void adjustValueAxisRange();
+
+ Q_DISABLE_COPY(Surface3DController)
+};
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
+#endif // SURFACE3DCONTROLLER_P_H
diff --git a/src/datavisualization/engine/surface3drenderer.cpp b/src/datavisualization/engine/surface3drenderer.cpp
new file mode 100644
index 00000000..a1dfc7e8
--- /dev/null
+++ b/src/datavisualization/engine/surface3drenderer.cpp
@@ -0,0 +1,2185 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 "q3dcamera.h"
+#include "q3dcamera_p.h"
+#include "shaderhelper_p.h"
+#include "objecthelper_p.h"
+#include "surfaceobject_p.h"
+#include "texturehelper_p.h"
+#include "selectionpointer_p.h"
+#include "theme_p.h"
+#include "utils_p.h"
+#include "drawer_p.h"
+#include "q3dlight.h"
+
+#include <QMatrix4x4>
+#include <QMouseEvent>
+#include <qmath.h>
+
+#include <QLinearGradient>
+#include <QPainter>
+
+#include <QDebug>
+
+static const int ID_TO_RGBA_MASK = 0xff;
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+//#define SHOW_DEPTH_TEXTURE_SCENE
+
+// TODO Uniform scaling is broken on surface
+//#define USE_UNIFORM_SCALING // Scale x and z uniformly, or based on autoscaled values
+
+const GLfloat aspectRatio = 2.0f; // Forced ratio of x and z to y. Dynamic will make it look odd.
+const GLfloat backgroundMargin = 1.1f; // Margin for background (1.1f = make it 10% larger to avoid items being drawn inside background)
+const GLfloat labelMargin = 0.05f;
+const GLfloat backgroundBottom = 1.0f;
+const GLfloat gridLineWidth = 0.005f;
+const GLfloat sliceZScale = 0.1f;
+const GLfloat surfaceGridYOffsetValue = 0.001f;
+const GLfloat sliceUnits = 2.5f;
+const int subViewDivider = 5;
+// The second offset to opposite direction is double because same matrix is translated twice
+const GLfloat surfaceGridYOffset[2] = {-surfaceGridYOffsetValue, 2.0f * surfaceGridYOffsetValue};
+
+Surface3DRenderer::Surface3DRenderer(Surface3DController *controller)
+ : Abstract3DRenderer(controller),
+ m_controller(controller),
+ m_labelStyle(QDataVis::LabelStyleFromTheme),
+ m_font(QFont(QStringLiteral("Arial"))),
+ m_isGridEnabled(true),
+ m_shader(0),
+ m_depthShader(0),
+ m_backgroundShader(0),
+ m_surfaceShader(0),
+ m_surfaceGridShader(0),
+ m_selectionShader(0),
+ m_labelShader(0),
+ m_heightNormalizer(0.0f),
+ m_scaleFactor(0.0f),
+ m_scaleX(0.0f),
+ m_scaleZ(0.0f),
+ m_scaleXWithBackground(0.0f),
+ m_scaleZWithBackground(0.0f),
+ m_surfaceScaleX(0.0f),
+ m_surfaceScaleZ(0.0f),
+ m_surfaceOffsetX(0.0f),
+ m_surfaceOffsetZ(0.0f),
+ m_minVisibleColumnValue(0.0f),
+ m_maxVisibleColumnValue(0.0f),
+ m_minVisibleRowValue(0.0f),
+ m_maxVisibleRowValue(0.0f),
+ m_visibleColumnRange(0.0f),
+ m_visibleRowRange(0.0f),
+ m_backgroundObj(0),
+ m_gridLineObj(0),
+ m_labelObj(0),
+ m_surfaceObj(0),
+ m_sliceSurfaceObj(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_flatSupported(true),
+ m_selectionPointer(0),
+ m_selectionActive(false),
+ m_xFlipped(false),
+ m_zFlipped(false),
+ m_yFlipped(false),
+ m_sampleSpace(QRect(0, 0, 0, 0)),
+ m_shadowQualityMultiplier(3),
+ m_cachedSelectionId(0),
+ m_selectionModeChanged(false),
+ m_hasHeightAdjustmentChanged(true)
+{
+#if !defined(QT_OPENGL_ES_2)
+ // Check if flat feature is supported
+ ShaderHelper tester(this, QStringLiteral(":/shaders/vertexSurfaceFlat"),
+ QStringLiteral(":/shaders/fragmentSurfaceFlat"));
+ if (!tester.testCompile()) {
+ m_flatSupported = false;
+ m_controller->setSmoothSurface(true);
+ }
+#endif
+
+ m_cachedSmoothSurface = m_controller->smoothSurface();
+ updateSurfaceGridStatus(m_controller->surfaceGrid());
+
+ // Shadows are disabled for Q3DSurface in Tech Preview
+ updateShadowQuality(QDataVis::ShadowQualityNone);
+
+ initializeOpenGLFunctions();
+ initializeOpenGL();
+}
+
+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_shader;
+ delete m_depthShader;
+ delete m_backgroundShader;
+ delete m_selectionShader;
+ delete m_surfaceShader;
+ delete m_surfaceGridShader;
+ delete m_labelShader;
+
+ delete m_backgroundObj;
+ delete m_surfaceObj;
+ delete m_sliceSurfaceObj;
+ delete m_gridLineObj;
+ delete m_labelObj;
+
+ delete m_selectionPointer;
+
+ for (int i = 0; i < m_dataArray.size(); i++)
+ delete m_dataArray.at(i);
+ m_dataArray.clear();
+
+ for (int i = 0; i < m_sliceDataArray.size(); i++)
+ delete m_sliceDataArray.at(i);
+ m_sliceDataArray.clear();
+}
+
+void Surface3DRenderer::initializeOpenGL()
+{
+ Abstract3DRenderer::initializeOpenGL();
+
+ // Initialize shaders
+ handleShadowQualityChange();
+
+ initSurfaceShaders();
+
+ 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
+ initSelectionShaders();
+
+ // Load grid line mesh
+ loadGridLineMesh();
+
+ // Load label mesh
+ loadLabelMesh();
+
+ // 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();
+}
+
+void Surface3DRenderer::updateDataModel(QSurfaceDataProxy *dataProxy)
+{
+ calculateSceneScalingFactors();
+
+ const QSurfaceDataArray &array = *dataProxy->array();
+
+ // Need minimum of 2x2 array to draw a surface
+ if (array.size() >= 2 && array.at(0)->size() >= 2) {
+ QRect sampleSpace = calculateSampleRect(array);
+
+ bool dimensionChanged = false;
+ if (m_sampleSpace != sampleSpace) {
+ dimensionChanged = true;
+ m_sampleSpace = sampleSpace;
+
+ for (int i = 0; i < m_dataArray.size(); i++)
+ delete m_dataArray.at(i);
+ m_dataArray.clear();
+ }
+
+ // TODO: Handle partial surface grids on the graph edges
+ if (sampleSpace.width() >= 2 && sampleSpace.height() >= 2) {
+ if (dimensionChanged) {
+ m_dataArray.reserve(sampleSpace.height());
+ for (int i = 0; i < sampleSpace.height(); i++)
+ m_dataArray << new QSurfaceDataRow(sampleSpace.width());
+ }
+ for (int i = 0; i < sampleSpace.height(); i++) {
+ for (int j = 0; j < sampleSpace.width(); j++)
+ (*(m_dataArray.at(i)))[j] = array.at(i + sampleSpace.y())->at(j + sampleSpace.x());
+ }
+
+ if (m_dataArray.size() > 0) {
+ if (!m_surfaceObj)
+ loadSurfaceObj();
+
+ // Note: Data setup can change samplespace (as min width/height is 1)
+ if (m_cachedSmoothSurface) {
+ m_surfaceObj->setUpSmoothData(m_dataArray, m_sampleSpace, m_heightNormalizer,
+ m_axisCacheY.min(), dimensionChanged);
+ } else {
+ m_surfaceObj->setUpData(m_dataArray, m_sampleSpace, m_heightNormalizer,
+ m_axisCacheY.min(), dimensionChanged);
+ }
+
+ if (dimensionChanged)
+ updateSelectionTexture();
+ }
+ }
+ }
+
+ m_selectionActive = false;
+ m_cachedSelectionId = 0;
+ for (int i = 0; i < m_sliceDataArray.size(); i++)
+ delete m_sliceDataArray.at(i);
+ m_sliceDataArray.clear();
+
+ Abstract3DRenderer::updateDataModel(dataProxy);
+}
+
+void Surface3DRenderer::updateSliceDataModel(int selectionId)
+{
+ int column = (selectionId - 1) % m_sampleSpace.width();
+ int row = (selectionId - 1) / m_sampleSpace.width();
+
+ for (int i = 0; i < m_sliceDataArray.size(); i++)
+ delete m_sliceDataArray.at(i);
+ m_sliceDataArray.clear();
+
+ m_sliceDataArray.reserve(2);
+ QSurfaceDataRow *sliceRow;
+
+ qreal adjust = (0.025 * m_heightNormalizer) / 2.0;
+ qreal stepDown = 2.0 * adjust;
+ if (m_cachedSelectionMode == QDataVis::SelectionModeSliceRow) {
+ QSurfaceDataRow *src = m_dataArray.at(row);
+ sliceRow = new QSurfaceDataRow(src->size());
+ for (int i = 0; i < sliceRow->size(); i++)
+ (*sliceRow)[i].setPosition(QVector3D(src->at(i).x(), src->at(i).y() + adjust, -1.0));
+ } else {
+ sliceRow = new QSurfaceDataRow(m_sampleSpace.height());
+ for (int i = 0; i < m_sampleSpace.height(); i++) {
+ (*sliceRow)[i].setPosition(QVector3D(m_dataArray.at(i)->at(column).z(),
+ m_dataArray.at(i)->at(column).y() + adjust,
+ -1.0));
+ }
+ }
+
+ m_sliceDataArray << sliceRow;
+
+ // Make a duplicate, so that we get a little bit depth
+ QSurfaceDataRow *duplicateRow = new QSurfaceDataRow(*sliceRow);
+ for (int i = 0; i < sliceRow->size(); i++)
+ (*sliceRow)[i].setPosition(QVector3D(sliceRow->at(i).x(), sliceRow->at(i).y() - stepDown, 1.0));
+
+ m_sliceDataArray << duplicateRow;
+
+ QRect sliceRect(0, 0, sliceRow->size(), 2);
+
+ if (sliceRow->size() > 0) {
+ if (!m_sliceSurfaceObj)
+ loadSliceSurfaceObj();
+
+ if (m_cachedSmoothSurface) {
+ m_sliceSurfaceObj->setUpSmoothData(m_sliceDataArray, sliceRect, m_heightNormalizer,
+ m_axisCacheY.min(), true);
+ } else {
+ m_sliceSurfaceObj->setUpData(m_sliceDataArray, sliceRect, m_heightNormalizer,
+ m_axisCacheY.min(), true);
+ }
+ }
+}
+
+QRect Surface3DRenderer::calculateSampleRect(const QSurfaceDataArray &array)
+{
+ QRect sampleSpace;
+
+ int rowCount = array.size();
+ int columnCount = array.at(0)->size();
+
+ int i;
+ bool found;
+ float axisMinX = float(m_axisCacheX.min());
+ float axisMaxX = float(m_axisCacheX.max());
+ float axisMinZ = float(m_axisCacheZ.min());
+ float axisMaxZ = float(m_axisCacheZ.max());
+
+ // Comparisons between float and double are not accurate, so fudge our comparison values
+ //a little to get all rows and columns into view that need to be visible.
+ const float fudgeFactor = 0.00001f;
+ float fudgedAxisXRange = (axisMaxX - axisMinX) * fudgeFactor;
+ float fudgedAxisZRange = (axisMaxZ - axisMinZ) * fudgeFactor;
+ axisMinX -= fudgedAxisXRange;
+ axisMinZ -= fudgedAxisZRange;
+ axisMaxX += fudgedAxisXRange;
+ axisMaxZ += fudgedAxisZRange;
+
+ // m_minVisibleColumnValue
+ for (i = 0, found = false; i < columnCount; i++) {
+ if (array.at(0)->at(i).x() >= axisMinX) {
+ found = true;
+ break;
+ }
+ }
+ if (found) {
+ m_minVisibleColumnValue = array.at(0)->at(i).x();
+ sampleSpace.setLeft(i);
+ } else {
+ sampleSpace.setWidth(-1); // to indicate nothing needs to be shown
+ return sampleSpace;
+ }
+
+ // m_maxVisibleColumnValue
+ for (i = columnCount - 1, found = false; i >= 0; i--) {
+ if (array.at(0)->at(i).x() <= axisMaxX) {
+ found = true;
+ break;
+ }
+ }
+ if (found) {
+ m_maxVisibleColumnValue = array.at(0)->at(i).x();
+ sampleSpace.setRight(i);
+ } else {
+ sampleSpace.setWidth(-1); // to indicate nothing needs to be shown
+ return sampleSpace;
+ }
+
+ // m_minVisibleRowValue
+ for (i = 0, found = false; i < rowCount; i++) {
+ if (array.at(i)->at(0).z() >= axisMinZ) {
+ found = true;
+ break;
+ }
+ }
+ if (found) {
+ m_minVisibleRowValue = array.at(i)->at(0).z();
+ sampleSpace.setTop(i);
+ } else {
+ sampleSpace.setWidth(-1); // to indicate nothing needs to be shown
+ return sampleSpace;
+ }
+
+ // m_maxVisibleRowValue
+ for (i = rowCount - 1, found = false; i >= 0; i--) {
+ if (array.at(i)->at(0).z() <= axisMaxZ) {
+ found = true;
+ break;
+ }
+ }
+ if (found) {
+ m_maxVisibleRowValue = array.at(i)->at(0).z();
+ sampleSpace.setBottom(i);
+ } else {
+ sampleSpace.setWidth(-1); // to indicate nothing needs to be shown
+ return sampleSpace;
+ }
+
+ m_visibleColumnRange = m_maxVisibleColumnValue - m_minVisibleColumnValue;
+ m_visibleRowRange = m_maxVisibleRowValue - m_minVisibleRowValue;
+ m_surfaceScaleX = m_scaleX * m_visibleColumnRange / m_areaSize.width();
+ m_surfaceScaleZ = m_scaleZ * m_visibleRowRange / m_areaSize.height();
+ GLfloat axis2XCenterX = axisMinX + axisMaxX;
+ GLfloat axis2XCenterZ = axisMinZ + axisMaxZ;
+ GLfloat data2XCenterX = GLfloat(m_minVisibleColumnValue + m_maxVisibleColumnValue);
+ GLfloat data2XCenterZ = GLfloat(m_minVisibleRowValue + m_maxVisibleRowValue);
+ m_surfaceOffsetX = m_scaleX * (data2XCenterX - axis2XCenterX) / m_areaSize.width();
+ m_surfaceOffsetZ = -m_scaleZ * (data2XCenterZ - axis2XCenterZ) / m_areaSize.height();
+
+ return sampleSpace;
+}
+
+void Surface3DRenderer::updateScene(Q3DScene *scene)
+{
+ // TODO: Move these to more suitable place e.g. controller should be controlling the viewports.
+ scene->setSecondarySubViewport(m_sliceViewPort);
+ scene->setPrimarySubViewport(m_mainViewPort);
+
+ // Set initial camera position
+ // X must be 0 for rotation to work - we can use "setCameraRotation" for setting it later
+ if (m_hasHeightAdjustmentChanged) {
+ scene->activeCamera()->setBaseOrientation(QVector3D(0.0f, 0.0f, cameraDistance + zComp),
+ QVector3D(0.0f, 0.0f, zComp),
+ QVector3D(0.0f, 1.0f, 0.0f));
+ // For now this is used just to make things once. Proper use will come
+ m_hasHeightAdjustmentChanged = false;
+ }
+
+ scene->activeCamera()->d_ptr->updateViewMatrix(m_autoScaleAdjustment);
+ scene->setLightPositionRelativeToCamera(defaultLightPos);
+
+ if (m_selectionPointer)
+ m_selectionPointer->updateScene(scene);
+
+ Abstract3DRenderer::updateScene(scene);
+}
+
+void Surface3DRenderer::render(GLuint defaultFboHandle)
+{
+ bool slicingActivated = m_cachedScene->isSlicingActive();
+ bool slicingChanged = m_cachedIsSlicingActivated != slicingActivated;
+
+ updateSlicingActive(slicingActivated);
+
+ // Handle GL state setup for FBO buffers and clearing of the render surface
+ Abstract3DRenderer::render(defaultFboHandle);
+
+ // In slice mode; draw slice and render selection ball
+ if (m_cachedIsSlicingActivated && m_selectionPointer && m_selectionActive) {
+ drawSlicedScene();
+ m_selectionPointer->render(defaultFboHandle);
+ }
+
+ // Draw the surface scene
+ drawScene(defaultFboHandle);
+
+ // Render selection ball if not in slice mode
+ if (!m_cachedIsSlicingActivated && m_selectionPointer && m_selectionActive)
+ m_selectionPointer->render(defaultFboHandle);
+
+ // If slicing has been activated by this render pass, we need another render
+ // Also trigger another render always when slicing changes in general to ensure
+ // final draw is correct.
+ if (slicingActivated != m_cachedScene->isSlicingActive() || slicingChanged)
+ emit needRender();
+}
+
+void Surface3DRenderer::drawSlicedScene()
+{
+ QVector3D lightPos;
+
+ // Specify viewport
+ glViewport(m_sliceViewPort.x(), m_sliceViewPort.y(),
+ m_sliceViewPort.width(), m_sliceViewPort.height());
+
+ // Set up projection matrix
+ QMatrix4x4 projectionMatrix;
+
+ GLfloat aspect = (GLfloat)m_mainViewPort.width() / (GLfloat)m_mainViewPort.height();
+ projectionMatrix.ortho(-sliceUnits * aspect, sliceUnits * aspect,
+ -sliceUnits, sliceUnits, -1.0f, 14.0f); // 14.0 because of zComp
+
+ // Set view matrix
+ QMatrix4x4 viewMatrix;
+ viewMatrix.lookAt(QVector3D(0.0f, 0.0f, zComp + 1.0f),
+ QVector3D(0.0f, 0.0f, zComp),
+ QVector3D(0.0f, 1.0f, 0.0f));
+
+ // Set light position
+ lightPos = m_cachedScene->activeLight()->position();
+
+ QMatrix4x4 projectionViewMatrix = projectionMatrix * viewMatrix;
+
+ GLfloat scaleX = 0.0f;
+ GLfloat scaleXBackground = 0.0f;
+ GLfloat offset = 0.0f;
+ if (m_cachedSelectionMode == QDataVis::SelectionModeSliceRow) {
+ scaleX = m_surfaceScaleX;
+ scaleXBackground = m_scaleXWithBackground;
+ offset = m_surfaceOffsetX;
+ } else if (m_cachedSelectionMode == QDataVis::SelectionModeSliceColumn) {
+ scaleX = m_surfaceScaleZ;
+ scaleXBackground = m_scaleZWithBackground;
+ offset = -m_surfaceOffsetZ;
+ }
+
+ if (m_surfaceObj) {
+ ShaderHelper *surfaceShader = m_shader;
+ surfaceShader->bind();
+
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+ QMatrix4x4 itModelMatrix;
+
+ modelMatrix.translate(offset, 0.0f, zComp);
+ QVector3D scaling(scaleX, 1.0f, sliceZScale);
+ modelMatrix.scale(scaling);
+ itModelMatrix.scale(scaling);
+
+ MVPMatrix = projectionViewMatrix * modelMatrix;
+
+ QVector3D color;
+ if (m_cachedSelectionMode == QDataVis::SelectionModeSliceRow)
+ color = Utils::vectorFromColor(m_cachedTheme.m_highlightRowColor);
+ else
+ color = Utils::vectorFromColor(m_cachedTheme.m_highlightColumnColor);
+
+ // Set shader bindings
+ surfaceShader->setUniformValue(surfaceShader->lightP(), lightPos);
+ surfaceShader->setUniformValue(surfaceShader->view(), viewMatrix);
+ surfaceShader->setUniformValue(surfaceShader->model(), modelMatrix);
+ surfaceShader->setUniformValue(surfaceShader->nModel(), itModelMatrix.inverted().transposed());
+ surfaceShader->setUniformValue(surfaceShader->MVP(), MVPMatrix);
+ surfaceShader->setUniformValue(surfaceShader->color(), color);
+ surfaceShader->setUniformValue(surfaceShader->lightS(), 0.25f);
+ surfaceShader->setUniformValue(surfaceShader->ambientS(),
+ m_cachedTheme.m_ambientStrength * 2.0f);
+
+ m_drawer->drawObject(surfaceShader, m_sliceSurfaceObj);
+
+ surfaceShader->release();
+
+ // Draw surface grid
+ if (m_cachedSurfaceGridOn) {
+ m_surfaceGridShader->bind();
+
+ m_surfaceGridShader->setUniformValue(m_surfaceGridShader->color(),
+ Utils::vectorFromColor(m_cachedTheme.m_gridLine));
+ // Draw the grid twice, with slight offset on Y axis to each direction
+ for (int i = 0; i < 2; i++) {
+ MVPMatrix.translate(0.0f, surfaceGridYOffset[i], 0.0f);
+
+ m_surfaceGridShader->setUniformValue(m_surfaceGridShader->MVP(), MVPMatrix);
+ m_drawer->drawSurfaceGrid(m_surfaceGridShader, m_sliceSurfaceObj);
+ }
+ m_surfaceGridShader->release();
+ }
+ }
+
+ // Disable textures
+ glDisable(GL_TEXTURE_2D);
+
+ // lines to the back
+ if (m_cachedIsGridEnabled && m_heightNormalizer) {
+ ShaderHelper *lineShader = m_backgroundShader;
+ // Bind line shader
+ lineShader->bind();
+
+ if (m_axisCacheY.segmentCount() > 0) {
+ QVector3D gridLineScaleX(scaleXBackground, gridLineWidth, gridLineWidth);
+
+ // Set unchanging shader bindings
+ QVector3D lineColor = Utils::vectorFromColor(m_cachedTheme.m_gridLine);
+ lineShader->setUniformValue(lineShader->lightP(), lightPos);
+ lineShader->setUniformValue(lineShader->view(), viewMatrix);
+ lineShader->setUniformValue(lineShader->color(), lineColor);
+ lineShader->setUniformValue(lineShader->ambientS(), m_cachedTheme.m_ambientStrength * 2.0f);
+ lineShader->setUniformValue(lineShader->lightS(), 0.25f);
+
+ // Back wall
+ GLfloat lineStep = 2.0f * m_axisCacheY.subSegmentStep() / m_heightNormalizer;
+ GLfloat linePos = -1.0f;
+ int lastSegment = m_axisCacheY.subSegmentCount() * m_axisCacheY.segmentCount();
+
+ for (int segment = 0; segment <= lastSegment; segment++) {
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+ QMatrix4x4 itModelMatrix;
+
+ modelMatrix.translate(0.0f, linePos, zComp - sliceZScale);
+
+ modelMatrix.scale(gridLineScaleX);
+ itModelMatrix.scale(gridLineScaleX);
+
+ MVPMatrix = projectionViewMatrix * modelMatrix;
+
+ // Set the rest of the shader bindings
+ lineShader->setUniformValue(lineShader->model(), modelMatrix);
+ lineShader->setUniformValue(lineShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ lineShader->setUniformValue(lineShader->MVP(), MVPMatrix);
+
+ // Draw the object
+ m_drawer->drawObject(lineShader, m_gridLineObj);
+
+ linePos += lineStep;
+ }
+ }
+
+ // Floor lines
+ QVector3D gridLineScaleZ(gridLineWidth, gridLineWidth, sliceZScale);
+ QVector3D gridLineScaleY(gridLineWidth, backgroundMargin, gridLineWidth);
+
+ int lastSegment;
+ GLfloat lineStep;
+ GLfloat linePos;
+ if (m_cachedSelectionMode == QDataVis::SelectionModeSliceRow) {
+ lineStep = -2.0f * aspectRatio * m_axisCacheX.subSegmentStep() / m_scaleFactor;
+ lastSegment = m_axisCacheX.subSegmentCount() * m_axisCacheX.segmentCount();
+ linePos = m_scaleX;
+ } else {
+ lineStep = -2.0f * aspectRatio * m_axisCacheZ.subSegmentStep() / m_scaleFactor;
+ lastSegment = m_axisCacheZ.subSegmentCount() * m_axisCacheZ.segmentCount();
+ linePos = m_scaleZ;
+ }
+
+ for (int segment = 0; segment <= lastSegment; segment++) {
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+ QMatrix4x4 itModelMatrix;
+
+ modelMatrix.translate(linePos, -backgroundMargin, zComp);
+
+ modelMatrix.scale(gridLineScaleZ);
+ itModelMatrix.scale(gridLineScaleZ);
+
+ MVPMatrix = projectionViewMatrix * modelMatrix;
+
+ // Set the rest of the shader bindings
+ lineShader->setUniformValue(lineShader->model(), modelMatrix);
+ lineShader->setUniformValue(lineShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ lineShader->setUniformValue(lineShader->MVP(), MVPMatrix);
+
+ // Draw the object
+ m_drawer->drawObject(lineShader, m_gridLineObj);
+
+ linePos += lineStep;
+ }
+
+ if (m_cachedSelectionMode == QDataVis::SelectionModeSliceRow)
+ linePos = m_scaleX;
+ else
+ linePos = m_scaleZ;
+
+ for (int segment = 0; segment <= lastSegment; segment++) {
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+ QMatrix4x4 itModelMatrix;
+
+ modelMatrix.translate(linePos, 0.0f, zComp - sliceZScale);
+ modelMatrix.scale(gridLineScaleY);
+ itModelMatrix.scale(gridLineScaleY);
+
+ MVPMatrix = projectionViewMatrix * modelMatrix;
+
+ // Set the rest of the shader bindings
+ lineShader->setUniformValue(lineShader->model(), modelMatrix);
+ lineShader->setUniformValue(lineShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ lineShader->setUniformValue(lineShader->MVP(), MVPMatrix);
+
+ // Draw the object
+ m_drawer->drawObject(lineShader, m_gridLineObj);
+
+ linePos += lineStep;
+ }
+
+ // Release line shader
+ lineShader->release();
+ }
+
+ // Draw axis labels
+ m_labelShader->bind();
+ glEnable(GL_TEXTURE_2D);
+ glDisable(GL_DEPTH_TEST);
+ glCullFace(GL_BACK);
+ if (m_cachedLabelStyle > QDataVis::LabelStyleOpaque) {
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ }
+
+ // Y Labels to back wall
+ GLfloat posStep = 2.0f * m_axisCacheY.segmentStep() / m_heightNormalizer;
+ GLfloat labelPos = -1.0f;
+ int labelNbr = 0;
+
+ QVector3D positionComp(0.0f, 0.0f, zComp);
+ QVector3D rotation(0.0f, 0.0f, 0.0f);
+ QVector3D labelTrans = QVector3D(scaleXBackground + labelMargin, labelPos, zComp);
+ for (int segment = 0; segment <= m_axisCacheY.segmentCount(); segment++) {
+ if (m_axisCacheY.labelItems().size() > labelNbr) {
+ labelTrans.setY(labelPos);
+ const LabelItem &axisLabelItem = *m_axisCacheY.labelItems().at(labelNbr);
+
+ // Draw the label here
+ m_dummyRenderItem.setTranslation(labelTrans);
+ m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix,
+ positionComp, rotation, 0, m_cachedSelectionMode, m_labelShader,
+ m_labelObj, m_cachedScene->activeCamera(),
+ true, true, Drawer::LabelMid, Qt::AlignRight);
+ }
+ labelNbr++;
+ labelPos += posStep;
+ }
+
+ // X Labels to ground
+ int countLabelItems;
+ int lastSegment;
+ if (m_cachedSelectionMode == QDataVis::SelectionModeSliceRow) {
+ posStep = 2.0f * aspectRatio * m_axisCacheX.segmentStep() / m_scaleFactor;
+ labelPos = -m_scaleX;
+ lastSegment = m_axisCacheX.segmentCount();
+ countLabelItems = m_axisCacheX.labelItems().size();
+ } else {
+ posStep = 2.0f * aspectRatio * m_axisCacheZ.segmentStep() / m_scaleFactor;
+ labelPos = -m_scaleZ;
+ lastSegment = m_axisCacheZ.segmentCount();
+ countLabelItems = m_axisCacheZ.labelItems().size();
+ }
+
+ labelNbr = 0;
+ positionComp.setY(backgroundMargin);
+ rotation.setZ(-45.0f);
+ labelTrans.setY(-backgroundMargin);
+ for (int segment = 0; segment <= lastSegment; segment++) {
+ if (countLabelItems > labelNbr) {
+ // Draw the label here
+ labelTrans.setX(labelPos);
+
+ m_dummyRenderItem.setTranslation(labelTrans);
+
+ LabelItem *axisLabelItem;
+ if (m_cachedSelectionMode == QDataVis::SelectionModeSliceRow)
+ axisLabelItem = m_axisCacheX.labelItems().at(labelNbr);
+ else
+ axisLabelItem = m_axisCacheZ.labelItems().at(labelNbr);
+
+ m_drawer->drawLabel(m_dummyRenderItem, *axisLabelItem, viewMatrix, projectionMatrix,
+ positionComp, rotation, 0, QDataVis::SelectionModeSliceRow,
+ m_labelShader, m_labelObj, m_cachedScene->activeCamera(),
+ false, false, Drawer::LabelBelow, Qt::AlignTop);
+ }
+ labelNbr++;
+ labelPos += posStep;
+ }
+
+ glDisable(GL_TEXTURE_2D);
+ glEnable(GL_DEPTH_TEST);
+ if (m_cachedLabelStyle > QDataVis::LabelStyleOpaque)
+ glDisable(GL_BLEND);
+
+ // Release label shader
+ m_labelShader->release();
+}
+
+void Surface3DRenderer::drawScene(GLuint defaultFboHandle)
+{
+ GLfloat backgroundRotation = 0;
+ uint selectionId = 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_cachedScene->activeCamera()->viewMatrix();
+
+ QMatrix4x4 projectionViewMatrix = projectionMatrix * viewMatrix;
+
+ // Calculate flipping indicators
+ 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;
+
+ // 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 = m_cachedScene->activeLight()->position();
+
+ QMatrix4x4 depthViewMatrix;
+ QMatrix4x4 depthProjectionMatrix;
+ QMatrix4x4 depthProjectionViewMatrix;
+
+ GLfloat adjustedLightStrength = m_cachedTheme.m_lightStrength / 10.0f;
+
+ QVector3D surfaceScaler(m_surfaceScaleX, 1.0f, m_surfaceScaleZ);
+ QVector3D surfaceOffset(m_surfaceOffsetX, 0.0f, m_surfaceOffsetZ + zComp);
+
+ // Draw depth buffer
+#if !defined(QT_OPENGL_ES_2)
+ if (m_cachedShadowQuality > QDataVis::ShadowQualityNone && m_surfaceObj) {
+ // 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_shadowQualityMultiplier,
+ m_mainViewPort.height() * m_shadowQualityMultiplier);
+
+ // 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_cachedScene->activeCamera()->calculatePositionRelativeToCamera(
+ QVector3D(0.0f, 0.0f, zComp), 0.0f, 1.5f / 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(10.0f, (GLfloat)m_mainViewPort.width()
+ / (GLfloat)m_mainViewPort.height(), 3.0f, 100.0f);
+#else
+ // Use these for orthographic shadows
+ depthProjectionMatrix.ortho(-2.0f * 2.0f, 2.0f * 2.0f,
+ -2.0f, 2.0f,
+ 0.0f, 100.0f);
+#endif
+ depthProjectionViewMatrix = depthProjectionMatrix * depthViewMatrix;
+
+ glCullFace(GL_FRONT);
+
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+
+ modelMatrix.translate(surfaceOffset);
+ modelMatrix.scale(surfaceScaler);
+
+ MVPMatrix = depthProjectionViewMatrix * modelMatrix;
+
+ m_depthShader->setUniformValue(m_depthShader->MVP(), MVPMatrix);
+
+ // 1st attribute buffer : vertices
+ glEnableVertexAttribArray(m_depthShader->posAtt());
+ glBindBuffer(GL_ARRAY_BUFFER, m_surfaceObj->vertexBuf());
+ glVertexAttribPointer(m_depthShader->posAtt(), 3, 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(), 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();
+
+ // Revert to original viewport
+ glViewport(m_mainViewPort.x(), m_mainViewPort.y(),
+ m_mainViewPort.width(), m_mainViewPort.height());
+
+ // Reset culling to normal
+ glCullFace(GL_BACK);
+
+#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
+
+ bool selectionDirty = false;
+
+ // Enable texturing
+ glEnable(GL_TEXTURE_2D);
+
+ // Draw selection buffer
+ if (!m_cachedIsSlicingActivated && m_controller->inputState() == QDataVis::InputStateOnScene
+ && m_surfaceObj && m_cachedSelectionMode > QDataVis::SelectionModeNone) {
+ 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(surfaceOffset);
+ modelMatrix.scale(surfaceScaler);
+
+ MVPMatrix = projectionViewMatrix * modelMatrix;
+
+ m_selectionShader->setUniformValue(m_selectionShader->MVP(), MVPMatrix);
+
+ m_drawer->drawObject(m_selectionShader, m_surfaceObj, m_selectionTexture);
+
+ glEnable(GL_DITHER);
+
+ QPoint point = m_controller->inputPosition();
+ GLubyte pixel[4] = {0};
+ glReadPixels(point.x(), m_cachedBoundingRect.height() - point.y(), 1, 1,
+ GL_RGBA, GL_UNSIGNED_BYTE, (void *)pixel);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, defaultFboHandle);
+
+ // Release selection shader
+ m_selectionShader->release();
+
+ // Put the RGBA value back to uint
+#if defined (Q_OS_ANDROID)
+ selectionId = pixel[0] + pixel[1] * 256 + pixel[2] * 65536;
+#else
+ selectionId = pixel[0] + pixel[1] * 256 + pixel[2] * 65536 + pixel[3] * 16777216;
+#endif
+
+ selectionDirty = true;
+ }
+
+ // Draw the surface
+ if (m_surfaceObj && m_sampleSpace.width() >= 2 && m_sampleSpace.height() >= 2) {
+ m_surfaceShader->bind();
+
+ // For surface we can see climpses from underneath
+ glDisable(GL_CULL_FACE);
+
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+ QMatrix4x4 depthMVPMatrix;
+ QMatrix4x4 itModelMatrix;
+
+ modelMatrix.translate(surfaceOffset);
+ modelMatrix.scale(surfaceScaler);
+ itModelMatrix.scale(surfaceScaler);
+
+#ifdef SHOW_DEPTH_TEXTURE_SCENE
+ MVPMatrix = depthProjectionViewMatrix * modelMatrix;
+#else
+ MVPMatrix = projectionViewMatrix * modelMatrix;
+#endif
+ depthMVPMatrix = depthProjectionViewMatrix * 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_surfaceShader->setUniformValue(m_surfaceShader->ambientS(),
+ m_cachedTheme.m_ambientStrength);
+
+#if !defined(QT_OPENGL_ES_2)
+ if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) {
+ // Set shadow shader bindings
+ m_surfaceShader->setUniformValue(m_surfaceShader->shadowQ(), m_shadowQualityToShader);
+ m_surfaceShader->setUniformValue(m_surfaceShader->depth(), depthMVPMatrix);
+ m_surfaceShader->setUniformValue(m_surfaceShader->lightS(), adjustedLightStrength);
+
+ // Draw the object
+ m_drawer->drawObject(m_surfaceShader, m_surfaceObj, m_gradientTexture, m_depthTexture);
+ } else
+#endif
+ {
+ // Set shadowless shader bindings
+ m_surfaceShader->setUniformValue(m_surfaceShader->lightS(),
+ m_cachedTheme.m_lightStrength);
+
+ // Draw the object
+ m_drawer->drawObject(m_surfaceShader, m_surfaceObj, m_gradientTexture);
+ }
+
+ m_surfaceShader->release();
+
+ glEnable(GL_CULL_FACE);
+
+ // Draw surface grid
+ if (m_cachedSurfaceGridOn) {
+ m_surfaceGridShader->bind();
+
+ m_surfaceGridShader->setUniformValue(m_surfaceGridShader->color(),
+ Utils::vectorFromColor(m_cachedTheme.m_gridLine));
+ // Draw the grid twice, with slight offset on Y axis to each direction
+ for (int i = 0; i < 2; i++) {
+ MVPMatrix.translate(0.0f, surfaceGridYOffset[i], 0.0f);
+
+ m_surfaceGridShader->setUniformValue(m_surfaceGridShader->MVP(), MVPMatrix);
+ m_drawer->drawSurfaceGrid(m_surfaceGridShader, m_surfaceObj);
+ }
+ m_surfaceGridShader->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);
+ QVector3D bgScale(m_scaleXWithBackground, backgroundMargin, m_scaleZWithBackground);
+ modelMatrix.scale(bgScale);
+ itModelMatrix.scale(bgScale);
+
+ // 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 = depthProjectionViewMatrix * modelMatrix;
+#else
+ MVPMatrix = projectionViewMatrix * modelMatrix;
+#endif
+ depthMVPMatrix = depthProjectionViewMatrix * 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::ShadowQualityNone) {
+ // 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(),
+ adjustedLightStrength);
+
+ // 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();
+
+ // Draw grid lines
+ QVector3D gridLineScaleX(m_scaleXWithBackground, gridLineWidth, gridLineWidth);
+ QVector3D gridLineScaleZ(gridLineWidth, gridLineWidth, m_scaleZWithBackground);
+ QVector3D gridLineScaleY(gridLineWidth, backgroundMargin, gridLineWidth);
+
+ if (m_cachedIsGridEnabled && m_heightNormalizer) {
+ ShaderHelper *lineShader = m_backgroundShader;
+ // Bind line shader
+ lineShader->bind();
+
+ // Set unchanging shader bindings
+ QVector3D lineColor = Utils::vectorFromColor(m_cachedTheme.m_gridLine);
+ lineShader->setUniformValue(lineShader->lightP(), lightPos);
+ lineShader->setUniformValue(lineShader->view(), viewMatrix);
+ lineShader->setUniformValue(lineShader->color(), lineColor);
+ lineShader->setUniformValue(lineShader->ambientS(), m_cachedTheme.m_ambientStrength);
+
+ // Rows (= Z)
+ if (m_axisCacheZ.segmentCount() > 0) {
+ // Floor lines
+ GLfloat lineStep = 2.0f * aspectRatio * m_axisCacheZ.subSegmentStep() / m_scaleFactor;
+ GLfloat linePos = m_scaleZ + zComp; // Start line
+ int lastSegment = m_axisCacheZ.subSegmentCount() * m_axisCacheZ.segmentCount();
+
+ for (int segment = 0; segment <= lastSegment; segment++) {
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+ QMatrix4x4 depthMVPMatrix;
+ QMatrix4x4 itModelMatrix;
+
+ if (m_yFlipped)
+ modelMatrix.translate(0.0f, backgroundMargin, linePos);
+ else
+ modelMatrix.translate(0.0f, -backgroundMargin, linePos);
+
+ modelMatrix.scale(gridLineScaleX);
+ itModelMatrix.scale(gridLineScaleX);
+
+ // 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 = projectionViewMatrix * modelMatrix;
+ depthMVPMatrix = depthProjectionViewMatrix * modelMatrix;
+
+ // Set the rest of the shader bindings
+ lineShader->setUniformValue(lineShader->model(), modelMatrix);
+ lineShader->setUniformValue(lineShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ lineShader->setUniformValue(lineShader->MVP(), MVPMatrix);
+
+#if !defined(QT_OPENGL_ES_2)
+ if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) {
+ // Set shadow shader bindings
+ lineShader->setUniformValue(lineShader->shadowQ(), m_shadowQualityToShader);
+ lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix);
+ lineShader->setUniformValue(lineShader->lightS(), adjustedLightStrength);
+
+ // Draw the object
+ m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture);
+ } else
+#endif
+ {
+ // Set shadowless shader bindings
+ lineShader->setUniformValue(lineShader->lightS(),
+ m_cachedTheme.m_lightStrength);
+
+ // Draw the object
+ m_drawer->drawObject(lineShader, m_gridLineObj);
+ }
+ linePos -= lineStep;
+ }
+
+ // Side wall lines
+ GLfloat lineXTrans = m_scaleXWithBackground;
+ linePos = m_scaleZ + zComp; // Start line
+
+ if (!m_xFlipped)
+ lineXTrans = -lineXTrans;
+
+ for (int segment = 0; segment <= lastSegment; segment++) {
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+ QMatrix4x4 depthMVPMatrix;
+ QMatrix4x4 itModelMatrix;
+
+ modelMatrix.translate(lineXTrans, 0.0f, linePos);
+ modelMatrix.scale(gridLineScaleY);
+ itModelMatrix.scale(gridLineScaleY);
+
+ MVPMatrix = projectionViewMatrix * modelMatrix;
+ depthMVPMatrix = depthProjectionViewMatrix * modelMatrix;
+
+ // Set the rest of the shader bindings
+ lineShader->setUniformValue(lineShader->model(), modelMatrix);
+ lineShader->setUniformValue(lineShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ lineShader->setUniformValue(lineShader->MVP(), MVPMatrix);
+
+#if !defined(QT_OPENGL_ES_2)
+ if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) {
+ // Set shadow shader bindings
+ lineShader->setUniformValue(lineShader->shadowQ(), m_shadowQualityToShader);
+ lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix);
+ lineShader->setUniformValue(lineShader->lightS(),
+ adjustedLightStrength);
+
+ // Draw the object
+ m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture);
+ } else
+#endif
+ {
+ // Set shadowless shader bindings
+ lineShader->setUniformValue(lineShader->lightS(),
+ m_cachedTheme.m_lightStrength);
+
+ // Draw the object
+ m_drawer->drawObject(lineShader, m_gridLineObj);
+ }
+ linePos -= lineStep;
+ }
+ }
+
+ // Columns (= X)
+ if (m_axisCacheX.segmentCount() > 0) {
+ // Floor lines
+ GLfloat lineStep = -2.0f * aspectRatio * m_axisCacheX.subSegmentStep() / m_scaleFactor;
+ GLfloat linePos = m_scaleX;
+ int lastSegment = m_axisCacheX.subSegmentCount() * m_axisCacheX.segmentCount();
+
+ for (int segment = 0; segment <= lastSegment; segment++) {
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+ QMatrix4x4 depthMVPMatrix;
+ QMatrix4x4 itModelMatrix;
+
+ if (m_yFlipped)
+ modelMatrix.translate(linePos, backgroundMargin, zComp);
+ else
+ modelMatrix.translate(linePos, -backgroundMargin, zComp);
+
+ modelMatrix.scale(gridLineScaleZ);
+ itModelMatrix.scale(gridLineScaleZ);
+
+ // 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 = projectionViewMatrix * modelMatrix;
+ depthMVPMatrix = depthProjectionViewMatrix * modelMatrix;
+
+ // Set the rest of the shader bindings
+ lineShader->setUniformValue(lineShader->model(), modelMatrix);
+ lineShader->setUniformValue(lineShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ lineShader->setUniformValue(lineShader->MVP(), MVPMatrix);
+
+#if !defined(QT_OPENGL_ES_2)
+ if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) {
+ // Set shadow shader bindings
+ lineShader->setUniformValue(lineShader->shadowQ(), m_shadowQualityToShader);
+ lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix);
+ lineShader->setUniformValue(lineShader->lightS(), adjustedLightStrength);
+
+ // Draw the object
+ m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture);
+ } else
+#endif
+ {
+ // Set shadowless shader bindings
+ lineShader->setUniformValue(lineShader->lightS(),
+ m_cachedTheme.m_lightStrength);
+
+ // Draw the object
+ m_drawer->drawObject(lineShader, m_gridLineObj);
+ }
+ linePos += lineStep;
+ }
+
+ // Back wall lines
+ GLfloat lineZTrans = m_scaleZWithBackground + zComp;
+ linePos = m_scaleX;
+
+ if (!m_zFlipped)
+ lineZTrans = -lineZTrans + zComp + zComp;
+
+ for (int segment = 0; segment <= lastSegment; segment++) {
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+ QMatrix4x4 depthMVPMatrix;
+ QMatrix4x4 itModelMatrix;
+
+ modelMatrix.translate(linePos, 0.0f, lineZTrans);
+ modelMatrix.scale(gridLineScaleY);
+ itModelMatrix.scale(gridLineScaleY);
+
+ MVPMatrix = projectionViewMatrix * modelMatrix;
+ depthMVPMatrix = depthProjectionViewMatrix * modelMatrix;
+
+ // Set the rest of the shader bindings
+ lineShader->setUniformValue(lineShader->model(), modelMatrix);
+ lineShader->setUniformValue(lineShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ lineShader->setUniformValue(lineShader->MVP(), MVPMatrix);
+
+#if !defined(QT_OPENGL_ES_2)
+ if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) {
+ // Set shadow shader bindings
+ lineShader->setUniformValue(lineShader->shadowQ(), m_shadowQualityToShader);
+ lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix);
+ lineShader->setUniformValue(lineShader->lightS(), adjustedLightStrength);
+
+ // Draw the object
+ m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture);
+ } else
+#endif
+ {
+ // Set shadowless shader bindings
+ lineShader->setUniformValue(lineShader->lightS(),
+ m_cachedTheme.m_lightStrength);
+
+ // Draw the object
+ m_drawer->drawObject(lineShader, m_gridLineObj);
+ }
+ linePos += lineStep;
+ }
+ }
+
+ // Horizontal wall lines
+ if (m_axisCacheY.segmentCount() > 0) {
+ // Back wall
+ GLfloat lineStep = 2.0f * m_axisCacheY.subSegmentStep() / m_heightNormalizer;
+ GLfloat linePos = -1.0f;
+ int lastSegment = m_axisCacheY.subSegmentCount() * m_axisCacheY.segmentCount();
+
+ GLfloat lineZTrans = m_scaleZWithBackground + zComp;
+
+ if (!m_zFlipped)
+ lineZTrans = -lineZTrans + zComp + zComp;
+
+ for (int segment = 0; segment <= lastSegment; segment++) {
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+ QMatrix4x4 depthMVPMatrix;
+ QMatrix4x4 itModelMatrix;
+
+ modelMatrix.translate(0.0f, linePos, lineZTrans);
+
+ modelMatrix.scale(gridLineScaleX);
+ itModelMatrix.scale(gridLineScaleX);
+
+ MVPMatrix = projectionViewMatrix * modelMatrix;
+ depthMVPMatrix = depthProjectionViewMatrix * modelMatrix;
+
+ // Set the rest of the shader bindings
+ lineShader->setUniformValue(lineShader->model(), modelMatrix);
+ lineShader->setUniformValue(lineShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ lineShader->setUniformValue(lineShader->MVP(), MVPMatrix);
+
+#if !defined(QT_OPENGL_ES_2)
+ if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) {
+ // Set shadow shader bindings
+ lineShader->setUniformValue(lineShader->shadowQ(), m_shadowQualityToShader);
+ lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix);
+ lineShader->setUniformValue(lineShader->lightS(), adjustedLightStrength);
+
+ // Draw the object
+ m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture);
+ } else
+#endif
+ {
+ // Set shadowless shader bindings
+ lineShader->setUniformValue(lineShader->lightS(),
+ m_cachedTheme.m_lightStrength);
+
+ // Draw the object
+ m_drawer->drawObject(lineShader, m_gridLineObj);
+ }
+ linePos += lineStep;
+ }
+
+ // Side wall
+ linePos = -1.0f;
+ lastSegment = m_axisCacheY.subSegmentCount() * m_axisCacheY.segmentCount();
+ GLfloat lineXTrans = m_scaleXWithBackground;
+
+ if (!m_xFlipped)
+ lineXTrans = -lineXTrans;
+
+ for (int segment = 0; segment <= lastSegment; segment++) {
+ QMatrix4x4 modelMatrix;
+ QMatrix4x4 MVPMatrix;
+ QMatrix4x4 depthMVPMatrix;
+ QMatrix4x4 itModelMatrix;
+
+ modelMatrix.translate(lineXTrans, linePos, zComp);
+
+ modelMatrix.scale(gridLineScaleZ);
+ itModelMatrix.scale(gridLineScaleZ);
+
+ MVPMatrix = projectionViewMatrix * modelMatrix;
+ depthMVPMatrix = depthProjectionViewMatrix * modelMatrix;
+
+ // Set the rest of the shader bindings
+ lineShader->setUniformValue(lineShader->model(), modelMatrix);
+ lineShader->setUniformValue(lineShader->nModel(),
+ itModelMatrix.inverted().transposed());
+ lineShader->setUniformValue(lineShader->MVP(), MVPMatrix);
+
+#if !defined(QT_OPENGL_ES_2)
+ if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) {
+ // Set shadow shader bindings
+ lineShader->setUniformValue(lineShader->shadowQ(), m_shadowQualityToShader);
+ lineShader->setUniformValue(lineShader->depth(), depthMVPMatrix);
+ lineShader->setUniformValue(lineShader->lightS(), adjustedLightStrength);
+
+ // Draw the object
+ m_drawer->drawObject(lineShader, m_gridLineObj, 0, m_depthTexture);
+ } else
+#endif
+ {
+ // Set shadowless shader bindings
+ lineShader->setUniformValue(lineShader->lightS(),
+ m_cachedTheme.m_lightStrength);
+
+ // Draw the object
+ m_drawer->drawObject(lineShader, m_gridLineObj);
+ }
+ linePos += lineStep;
+ }
+ }
+
+ // Release line shader
+ lineShader->release();
+ }
+
+ // Draw axis labels
+ m_labelShader->bind();
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ // Z Labels
+ QVector3D positionZComp(0.0f, 0.0f, zComp);
+ if (m_axisCacheZ.segmentCount() > 0) {
+ GLfloat posStep = 2.0f * aspectRatio * m_axisCacheZ.segmentStep() / m_scaleFactor;
+ GLfloat labelPos = m_scaleZ + zComp;
+ int lastSegment = m_axisCacheZ.segmentCount();
+ int labelNbr = 0;
+ GLfloat labelXTrans = m_scaleXWithBackground + labelMargin;
+ 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);
+ QVector3D rotation(rotLabelX, rotLabelY, rotLabelZ);
+
+ for (int segment = 0; segment <= lastSegment; segment++) {
+ if (m_axisCacheZ.labelItems().size() > labelNbr) {
+ labelTrans.setZ(labelPos);
+
+ // Draw the label here
+ m_dummyRenderItem.setTranslation(labelTrans);
+ const LabelItem &axisLabelItem = *m_axisCacheZ.labelItems().at(labelNbr);
+
+ m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix,
+ positionZComp, rotation, 0, m_cachedSelectionMode,
+ m_labelShader, m_labelObj, m_cachedScene->activeCamera(),
+ true, true, Drawer::LabelMid, alignment);
+ }
+ labelNbr++;
+ labelPos -= posStep;
+ }
+ }
+ // X Labels
+ if (m_axisCacheX.segmentCount() > 0) {
+ GLfloat posStep = 2.0f * aspectRatio * m_axisCacheX.segmentStep() / m_scaleFactor;
+ GLfloat labelPos = -m_scaleX;
+ int lastSegment = m_axisCacheX.segmentCount();
+
+ int labelNbr = 0;
+ GLfloat labelZTrans = m_scaleZWithBackground + labelMargin;
+ 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,
+ labelYTrans,
+ labelZTrans + zComp);
+ QVector3D rotation(rotLabelX, rotLabelY, rotLabelZ);
+
+ for (int segment = 0; segment <= lastSegment; segment++) {
+ if (m_axisCacheX.labelItems().size() > labelNbr) {
+ // Draw the label here
+ labelTrans.setX(labelPos);
+ m_dummyRenderItem.setTranslation(labelTrans);
+ const LabelItem &axisLabelItem = *m_axisCacheX.labelItems().at(labelNbr);
+
+ m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix,
+ positionZComp, rotation, 0, m_cachedSelectionMode,
+ m_labelShader, m_labelObj, m_cachedScene->activeCamera(),
+ true, true, Drawer::LabelMid, alignment);
+ }
+ labelNbr++;
+ labelPos += posStep;
+ }
+ }
+ // Y Labels
+ if (m_axisCacheY.segmentCount() > 0) {
+ GLfloat posStep = 2.0f * m_axisCacheY.segmentStep() / m_heightNormalizer;
+ GLfloat labelPos = -1.0f;
+ int labelNbr = 0;
+ GLfloat labelXTrans = m_scaleXWithBackground;
+ GLfloat labelZTrans = m_scaleZWithBackground;
+
+ GLfloat labelMarginXTrans = labelMargin;
+ GLfloat labelMarginZTrans = labelMargin;
+ GLfloat rotLabelX = 0.0f;
+ GLfloat rotLabelY = -90.0f;
+ GLfloat rotLabelZ = 0.0f;
+ Qt::AlignmentFlag alignment = Qt::AlignLeft;
+ if (!m_xFlipped) {
+ labelXTrans = -labelXTrans;
+ labelMarginXTrans = -labelMargin;
+ rotLabelY = 90.0f;
+ }
+ if (m_zFlipped) {
+ labelZTrans = -labelZTrans;
+ labelMarginZTrans = -labelMargin;
+ alignment = Qt::AlignRight;
+ }
+
+ // Back wall
+ QVector3D rotation(rotLabelX, rotLabelY, rotLabelZ);
+
+ for (int segment = 0; segment <= m_axisCacheY.segmentCount(); segment++) {
+ if (m_axisCacheY.labelItems().size() > labelNbr) {
+ const LabelItem &axisLabelItem = *m_axisCacheY.labelItems().at(labelNbr);
+
+ // Side wall
+ QVector3D labelTrans = QVector3D(labelXTrans, labelPos,
+ labelZTrans + labelMarginZTrans + zComp);
+ if (m_xFlipped)
+ rotation.setY(-90.0f);
+ else
+ rotation.setY(90.0f);
+ if (m_zFlipped)
+ alignment = Qt::AlignRight;
+ else
+ alignment = Qt::AlignLeft;
+
+ // Draw the label here
+ m_dummyRenderItem.setTranslation(labelTrans);
+ m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix,
+ positionZComp, rotation, 0, m_cachedSelectionMode,
+ m_labelShader, m_labelObj, m_cachedScene->activeCamera(),
+ true, true, Drawer::LabelMid, alignment);
+
+ // Back wall
+ if (m_xFlipped)
+ alignment = Qt::AlignLeft;
+ else
+ alignment = Qt::AlignRight;
+ if (m_zFlipped)
+ rotation.setY(180.0f);
+ else
+ rotation.setY(0.0f);
+
+ labelTrans = QVector3D(-labelXTrans - labelMarginXTrans, labelPos,
+ -labelZTrans + zComp);
+
+ // Draw the label here
+ m_dummyRenderItem.setTranslation(labelTrans);
+ m_drawer->drawLabel(m_dummyRenderItem, axisLabelItem, viewMatrix, projectionMatrix,
+ positionZComp, rotation, 0, m_cachedSelectionMode,
+ m_labelShader, m_labelObj, m_cachedScene->activeCamera(),
+ true, true, Drawer::LabelMid, alignment);
+ }
+ labelNbr++;
+ labelPos += posStep;
+ }
+ }
+
+ glDisable(GL_TEXTURE_2D);
+
+ glDisable(GL_BLEND);
+
+ // Release label shader
+ m_labelShader->release();
+
+ // Selection handling
+ if (m_selectionModeChanged || selectionDirty) {
+ if (selectionDirty)
+ m_cachedSelectionId = selectionId;
+ if (m_cachedSelectionMode == QDataVis::SelectionModeNone) {
+ m_cachedSelectionId = 0;
+ m_selectionActive = false;
+ }
+ if (m_cachedSelectionMode == QDataVis::SelectionModeItem) {
+ if (m_cachedSelectionId)
+ surfacePointSelected(m_cachedSelectionId);
+ else
+ m_selectionActive = false;
+ }
+ if (m_cachedSelectionMode == QDataVis::SelectionModeSliceRow
+ || m_cachedSelectionMode == QDataVis::SelectionModeSliceColumn) {
+ if (m_cachedSelectionId) {
+ updateSliceDataModel(m_cachedSelectionId);
+ m_cachedScene->setSlicingActive(true);
+
+ surfacePointSelected(m_cachedSelectionId);
+
+ emit needRender();
+ }
+ }
+
+ m_selectionModeChanged = false;
+ }
+ if (m_controller->inputState() == QDataVis::InputStateOnOverview) {
+ if (m_cachedIsSlicingActivated) {
+ m_cachedScene->setSlicingActive(false);
+ m_selectionActive = false;
+ m_cachedSelectionId = 0;
+ }
+ }
+}
+
+void Surface3DRenderer::updateSurfaceGradient(const QLinearGradient &gradient)
+{
+ QImage image(QSize(1, 1000), QImage::Format_RGB32);
+ QPainter pmp(&image);
+ pmp.setBrush(QBrush(gradient));
+ pmp.setPen(Qt::NoPen);
+ pmp.drawRect(0, 0, 1, 1000);
+
+ if (m_gradientTexture) {
+ m_textureHelper->deleteTexture(&m_gradientTexture);
+ m_gradientTexture = 0;
+ }
+
+ m_gradientTexture = m_textureHelper->create2DTexture(image, false, true);
+}
+
+// This one needs to be called when the data size changes
+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
+ int idImageWidth = (m_sampleSpace.width() - 1) * 4;
+ int idImageHeight = (m_sampleSpace.height() - 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_sampleSpace.width(), &r, &g, &b, &a);
+ fillIdCorner(&bits[p + 2 * stride], r, g, b, a, stride);
+
+ idToRGBA(id + m_sampleSpace.width() + 1, &r, &g, &b, &a);
+ fillIdCorner(&bits[p + 2 * stride + 8], r, g, b, a, stride);
+
+ id++;
+ }
+ id++;
+ }
+
+ // 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
+ QImage image = QImage(bits, idImageWidth, idImageHeight, QImage::Format_RGB32);
+ m_selectionTexture = m_textureHelper->create2DTexture(image, false, false, false);
+
+ // Release the temp bits allocation
+ delete[] bits;
+}
+
+void Surface3DRenderer::initSelectionBuffer()
+{
+ // 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::updateTextures()
+{
+ updateSurfaceGradient(m_cachedTheme.m_surfaceGradient);
+}
+
+void Surface3DRenderer::calculateSceneScalingFactors()
+{
+ // Calculate scene scaling and translation factors
+ m_heightNormalizer = GLfloat(m_axisCacheY.max() - m_axisCacheY.min());
+ m_areaSize.setHeight(m_axisCacheZ.max() - m_axisCacheZ.min());
+ m_areaSize.setWidth(m_axisCacheX.max() - m_axisCacheX.min());
+ m_scaleFactor = qMax(m_areaSize.width(), m_areaSize.height());
+#ifndef USE_UNIFORM_SCALING // Use this if we want to use autoscaling for x and z
+ m_scaleX = aspectRatio * m_areaSize.width() / m_scaleFactor;
+ m_scaleZ = aspectRatio * m_areaSize.height() / m_scaleFactor;
+ m_scaleXWithBackground = m_scaleX * backgroundMargin;
+ m_scaleZWithBackground = m_scaleZ * backgroundMargin;
+#else // ..and this if we want uniform scaling based on largest dimension
+ m_scaleX = aspectRatio / m_scaleFactor;
+ m_scaleZ = aspectRatio / m_scaleFactor;
+ m_scaleXWithBackground = aspectRatio * backgroundMargin;
+ m_scaleZWithBackground = aspectRatio * backgroundMargin;
+#endif
+}
+
+bool Surface3DRenderer::updateSmoothStatus(bool enable)
+{
+ if (!enable && !m_flatSupported) {
+ qWarning() << "Warning: Flat qualifier not supported on your platform's GLSL language."
+ " Requires at least GLSL version 1.5.";
+ enable = true;
+ }
+
+ bool changed = false;
+ if (enable != m_cachedSmoothSurface) {
+ m_cachedSmoothSurface = enable;
+ changed = true;
+ initSurfaceShaders();
+ }
+
+ // If no surface object created yet, don't try to update the object
+ if (m_surfaceObj && changed && m_sampleSpace.width() >= 2 && m_sampleSpace.height() >= 2) {
+ if (m_cachedSmoothSurface) {
+ m_surfaceObj->setUpSmoothData(m_dataArray, m_sampleSpace, m_heightNormalizer,
+ m_axisCacheY.min(), true);
+ } else {
+ m_surfaceObj->setUpData(m_dataArray, m_sampleSpace, m_heightNormalizer,
+ m_axisCacheY.min(), true);
+ }
+ }
+
+ return m_cachedSmoothSurface;
+}
+
+void Surface3DRenderer::updateSelectionMode(QDataVis::SelectionMode mode)
+{
+ if (mode != m_cachedSelectionMode)
+ m_selectionModeChanged = true;
+
+ Abstract3DRenderer::updateSelectionMode(mode);
+}
+
+void Surface3DRenderer::updateSurfaceGridStatus(bool enable)
+{
+ m_cachedSurfaceGridOn = enable;
+}
+
+void Surface3DRenderer::loadBackgroundMesh()
+{
+ if (m_backgroundObj)
+ delete m_backgroundObj;
+ m_backgroundObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/background"));
+ m_backgroundObj->load();
+}
+
+void Surface3DRenderer::loadSurfaceObj()
+{
+ if (m_surfaceObj)
+ delete m_surfaceObj;
+ m_surfaceObj = new SurfaceObject();
+}
+
+void Surface3DRenderer::loadSliceSurfaceObj()
+{
+ if (m_sliceSurfaceObj)
+ delete m_sliceSurfaceObj;
+ m_sliceSurfaceObj = new SurfaceObject();
+}
+
+void Surface3DRenderer::loadGridLineMesh()
+{
+ if (m_gridLineObj)
+ delete m_gridLineObj;
+ m_gridLineObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/bar"));
+ m_gridLineObj->load();
+}
+
+void Surface3DRenderer::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() / subViewDivider,
+ m_cachedBoundingRect.width() / subViewDivider,
+ m_cachedBoundingRect.height() / subViewDivider);
+ } else {
+ m_mainViewPort = QRect(0, 0, m_cachedBoundingRect.width(), m_cachedBoundingRect.height());
+ }
+ m_sliceViewPort = QRect(0, 0, m_cachedBoundingRect.width(), m_cachedBoundingRect.height());
+
+ if (m_selectionPointer) {
+ if (m_cachedIsSlicingActivated)
+ m_selectionPointer->updateBoundingRect(m_sliceViewPort);
+ else
+ m_selectionPointer->updateBoundingRect(m_mainViewPort);
+ }
+
+ Abstract3DRenderer::handleResize();
+}
+
+void Surface3DRenderer::surfacePointSelected(int id)
+{
+ int column = (id - 1) % m_sampleSpace.width();
+ int row = (id - 1) / m_sampleSpace.width();
+
+ if (row < 0 || column < 0 || m_dataArray.size() < row || m_dataArray.at(row)->size() < column)
+ return;
+
+ qreal value = qreal(m_dataArray.at(row)->at(column).y());
+
+ if (!m_selectionPointer)
+ m_selectionPointer = new SelectionPointer(m_drawer);
+
+ QVector3D pos;
+ if (m_cachedSelectionMode == QDataVis::SelectionModeSliceRow) {
+ pos = m_sliceSurfaceObj->vertexAt(column, 0);
+ pos *= QVector3D(m_surfaceScaleX, 1.0f, 0.0f);
+ pos += QVector3D(m_surfaceOffsetX, 0.0f, 0.0f);
+ m_selectionPointer->updateBoundingRect(m_sliceViewPort);
+ m_selectionPointer->updateSliceData(true, m_autoScaleAdjustment);
+ } else if (m_cachedSelectionMode == QDataVis::SelectionModeSliceColumn) {
+ pos = m_sliceSurfaceObj->vertexAt(row, 0);
+ pos *= QVector3D(m_surfaceScaleZ, 1.0f, 0.0f);
+ pos += QVector3D(-m_surfaceOffsetZ, 0.0f, 0.0f);
+ m_selectionPointer->updateBoundingRect(m_sliceViewPort);
+ m_selectionPointer->updateSliceData(true, m_autoScaleAdjustment);
+ } else {
+ pos = m_surfaceObj->vertexAt(column, row);
+ pos *= QVector3D(m_surfaceScaleX, 1.0f, m_surfaceScaleZ);;
+ pos += QVector3D(m_surfaceOffsetX, 0.0f, m_surfaceOffsetZ);
+ m_selectionPointer->updateBoundingRect(m_mainViewPort);
+ m_selectionPointer->updateSliceData(false, m_autoScaleAdjustment);
+ }
+
+ m_selectionPointer->setPosition(pos);
+ m_selectionPointer->setLabel(createSelectionLabel(value, column, row));
+ m_selectionPointer->updateScene(m_cachedScene);
+
+ //Put the selection pointer flag active
+ m_selectionActive = true;
+}
+
+QString Surface3DRenderer::createSelectionLabel(qreal value, int column, int row)
+{
+ QString labelText = itemLabelFormat();
+ static const QString xTitleTag(QStringLiteral("@xTitle"));
+ static const QString yTitleTag(QStringLiteral("@yTitle"));
+ static const QString zTitleTag(QStringLiteral("@zTitle"));
+ static const QString xLabelTag(QStringLiteral("@xLabel"));
+ static const QString yLabelTag(QStringLiteral("@yLabel"));
+ static const QString zLabelTag(QStringLiteral("@zLabel"));
+
+ labelText.replace(xTitleTag, m_axisCacheX.title());
+ labelText.replace(yTitleTag, m_axisCacheY.title());
+ labelText.replace(zTitleTag, m_axisCacheZ.title());
+
+ if (labelText.contains(xLabelTag)) {
+ QString labelFormat = m_axisCacheX.labelFormat();
+ if (labelFormat.isEmpty())
+ labelFormat = Utils::defaultLabelFormat();
+ QString valueLabelText = generateValueLabel(labelFormat,
+ m_dataArray.at(row)->at(column).x());
+ labelText.replace(xLabelTag, valueLabelText);
+ }
+ if (labelText.contains(yLabelTag)) {
+ QString labelFormat = m_axisCacheY.labelFormat();
+ if (labelFormat.isEmpty())
+ labelFormat = Utils::defaultLabelFormat();
+ QString valueLabelText = generateValueLabel(labelFormat, value);
+ labelText.replace(yLabelTag, valueLabelText);
+ }
+ if (labelText.contains(zLabelTag)) {
+ QString labelFormat = m_axisCacheZ.labelFormat();
+ if (labelFormat.isEmpty())
+ labelFormat = Utils::defaultLabelFormat();
+ QString valueLabelText = generateValueLabel(labelFormat,
+ m_dataArray.at(row)->at(column).z());
+ labelText.replace(zLabelTag, valueLabelText);
+ }
+
+ return labelText;
+}
+
+void Surface3DRenderer::loadMeshFile()
+{
+ qDebug() << __FUNCTION__ << "should we do something";
+}
+
+void Surface3DRenderer::updateShadowQuality(QDataVis::ShadowQuality quality)
+{
+ qWarning() << "Shadows have been disabled for Q3DSurface in technology preview";
+ m_cachedShadowQuality = QDataVis::ShadowQualityNone; //quality;
+ switch (quality) {
+ case QDataVis::ShadowQualityLow:
+ m_shadowQualityToShader = 33.3f;
+ m_shadowQualityMultiplier = 1;
+ break;
+ case QDataVis::ShadowQualityMedium:
+ m_shadowQualityToShader = 100.0f;
+ m_shadowQualityMultiplier = 3;
+ break;
+ case QDataVis::ShadowQualityHigh:
+ m_shadowQualityToShader = 200.0f;
+ m_shadowQualityMultiplier = 5;
+ break;
+ case QDataVis::ShadowQualitySoftLow:
+ m_shadowQualityToShader = 5.0f;
+ m_shadowQualityMultiplier = 1;
+ break;
+ case QDataVis::ShadowQualitySoftMedium:
+ m_shadowQualityToShader = 10.0f;
+ m_shadowQualityMultiplier = 3;
+ break;
+ case QDataVis::ShadowQualitySoftHigh:
+ m_shadowQualityToShader = 15.0f;
+ m_shadowQualityMultiplier = 4;
+ break;
+ default:
+ m_shadowQualityToShader = 0.0f;
+ m_shadowQualityMultiplier = 1;
+ break;
+ }
+
+#if !defined(QT_OPENGL_ES_2)
+ updateDepthBuffer();
+#endif
+}
+
+void Surface3DRenderer::updateSlicingActive(bool isSlicing)
+{
+ if (isSlicing == m_cachedIsSlicingActivated)
+ return;
+
+ m_cachedIsSlicingActivated = isSlicing;
+ if (isSlicing) {
+ m_mainViewPort = QRect(0, m_cachedBoundingRect.height() - m_cachedBoundingRect.height() / subViewDivider,
+ m_cachedBoundingRect.width() / subViewDivider, m_cachedBoundingRect.height() / subViewDivider);
+ if (m_depthTexture) {
+ m_textureHelper->deleteTexture(&m_depthTexture);
+ m_depthTexture = 0;
+ }
+ } else {
+ m_mainViewPort = QRect(0, 0, this->m_cachedBoundingRect.width(),
+ this->m_cachedBoundingRect.height());
+ initSelectionBuffer(); // We need to re-init selection buffer in case there has been a resize
+#if !defined(QT_OPENGL_ES_2)
+ updateDepthBuffer(); // Re-init depth buffer as well
+#endif
+ }
+}
+
+void Surface3DRenderer::loadLabelMesh()
+{
+ if (m_labelObj)
+ delete m_labelObj;
+ m_labelObj = new ObjectHelper(QStringLiteral(":/defaultMeshes/label"));
+ m_labelObj->load();
+}
+
+void Surface3DRenderer::initShaders(const QString &vertexShader, const QString &fragmentShader)
+{
+ if (m_shader)
+ delete m_shader;
+ m_shader = new ShaderHelper(this, vertexShader, fragmentShader);
+ m_shader->initialize();
+}
+
+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 !defined(QT_OPENGL_ES_2)
+ 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"));
+ }
+#else
+ m_surfaceShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexSurface"),
+ QStringLiteral(":/shaders/fragmentSurfaceES2"));
+#endif
+ m_surfaceShader->initialize();
+
+ if (m_surfaceGridShader)
+ delete m_surfaceGridShader;
+
+ m_surfaceGridShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexSurfaceGrid"),
+ QStringLiteral(":/shaders/fragmentSurfaceGrid"));
+
+ m_surfaceGridShader->initialize();
+}
+
+void Surface3DRenderer::initLabelShaders(const QString &vertexShader, const QString &fragmentShader)
+{
+ if (m_labelShader)
+ delete m_labelShader;
+ m_labelShader = new ShaderHelper(this, vertexShader, fragmentShader);
+ m_labelShader->initialize();
+}
+
+#if !defined(QT_OPENGL_ES_2)
+void Surface3DRenderer::initDepthShader()
+{
+ // TODO: Implement a depth shader for surface after technology preview
+ if (m_depthShader)
+ delete m_depthShader;
+ m_depthShader = new ShaderHelper(this, QStringLiteral(":/shaders/vertexDepth"),
+ QStringLiteral(":/shaders/fragmentDepth"));
+ m_depthShader->initialize();
+}
+
+void Surface3DRenderer::updateDepthBuffer()
+{
+ if (m_depthTexture) {
+ m_textureHelper->deleteTexture(&m_depthTexture);
+ m_depthTexture = 0;
+ }
+
+ if (m_cachedShadowQuality > QDataVis::ShadowQualityNone) {
+ m_depthTexture = m_textureHelper->createDepthTexture(m_mainViewPort.size(),
+ m_depthFrameBuffer,
+ m_shadowQualityMultiplier);
+ if (!m_depthTexture) {
+ switch (m_cachedShadowQuality) {
+ case QDataVis::ShadowQualityHigh:
+ qWarning("Creating high quality shadows failed. Changing to medium quality.");
+ (void)m_controller->setShadowQuality(QDataVis::ShadowQualityMedium);
+ updateShadowQuality(QDataVis::ShadowQualityMedium);
+ break;
+ case QDataVis::ShadowQualityMedium:
+ qWarning("Creating medium quality shadows failed. Changing to low quality.");
+ (void)m_controller->setShadowQuality(QDataVis::ShadowQualityLow);
+ updateShadowQuality(QDataVis::ShadowQualityLow);
+ break;
+ case QDataVis::ShadowQualityLow:
+ qWarning("Creating low quality shadows failed. Switching shadows off.");
+ (void)m_controller->setShadowQuality(QDataVis::ShadowQualityNone);
+ updateShadowQuality(QDataVis::ShadowQualityNone);
+ break;
+ case QDataVis::ShadowQualitySoftHigh:
+ qWarning("Creating soft high quality shadows failed. Changing to soft medium quality.");
+ (void)m_controller->setShadowQuality(QDataVis::ShadowQualitySoftMedium);
+ updateShadowQuality(QDataVis::ShadowQualitySoftMedium);
+ break;
+ case QDataVis::ShadowQualitySoftMedium:
+ qWarning("Creating soft medium quality shadows failed. Changing to soft low quality.");
+ (void)m_controller->setShadowQuality(QDataVis::ShadowQualitySoftLow);
+ updateShadowQuality(QDataVis::ShadowQualitySoftLow);
+ break;
+ case QDataVis::ShadowQualitySoftLow:
+ qWarning("Creating soft low quality shadows failed. Switching shadows off.");
+ (void)m_controller->setShadowQuality(QDataVis::ShadowQualityNone);
+ updateShadowQuality(QDataVis::ShadowQualityNone);
+ break;
+ default:
+ // You'll never get here
+ break;
+ }
+ }
+ }
+}
+#endif
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavis3d/engine/surface3drenderer_p.h b/src/datavisualization/engine/surface3drenderer_p.h
index f2fb120a..e42e820a 100644
--- a/src/datavis3d/engine/surface3drenderer_p.h
+++ b/src/datavisualization/engine/surface3drenderer_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -36,12 +36,15 @@
#include <QLinearGradient>
#include <QWindow>
-#include "datavis3dglobal_p.h"
+#include "datavisualizationglobal_p.h"
#include "surface3dcontroller_p.h"
+#include "abstract3drenderer_p.h"
+#include "scatterrenderitem_p.h"
+#include "qsurfacedataproxy.h"
class QOpenGLShaderProgram;
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
class ShaderHelper;
class ObjectHelper;
@@ -49,68 +52,56 @@ class SurfaceObject;
class TextureHelper;
class Theme;
class Drawer;
-class CameraHelper;
+class Q3DScene;
+class SelectionPointer;
-class QT_DATAVIS3D_EXPORT Surface3dRenderer : public QObject, protected QOpenGLFunctions
+class QT_DATAVISUALIZATION_EXPORT Surface3DRenderer : public Abstract3DRenderer
{
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;
+ Surface3DController *m_controller;
// Visual parameters
QRect m_boundingRect;
- Theme m_cachedTheme;
- QDataVis::LabelTransparency m_labelTransparency;
+ QDataVis::LabelStyle m_labelStyle;
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;
+ bool m_cachedIsSlicingActivated;
// Internal attributes purely related to how the scene is drawn with GL.
QRect m_mainViewPort;
QRect m_sliceViewPort;
+ ShaderHelper *m_shader;
+ ShaderHelper *m_depthShader;
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;
+ ShaderHelper *m_labelShader;
+ GLfloat m_heightNormalizer;
GLfloat m_scaleFactor;
GLfloat m_scaleX;
GLfloat m_scaleZ;
- GLfloat m_maxSceneSize;
+ GLfloat m_scaleXWithBackground;
+ GLfloat m_scaleZWithBackground;
+ GLfloat m_surfaceScaleX;
+ GLfloat m_surfaceScaleZ;
+ GLfloat m_surfaceOffsetX;
+ GLfloat m_surfaceOffsetZ;
+ GLfloat m_minVisibleColumnValue;
+ GLfloat m_maxVisibleColumnValue;
+ GLfloat m_minVisibleRowValue;
+ GLfloat m_maxVisibleRowValue;
+ GLfloat m_visibleColumnRange;
+ GLfloat m_visibleRowRange;
ObjectHelper *m_backgroundObj;
ObjectHelper *m_gridLineObj;
+ ObjectHelper *m_labelObj;
SurfaceObject *m_surfaceObj;
+ SurfaceObject *m_sliceSurfaceObj;
GLuint m_depthTexture;
GLuint m_depthFrameBuffer;
GLuint m_selectionFrameBuffer;
@@ -119,71 +110,76 @@ private:
GLuint m_selectionTexture;
GLuint m_selectionResultTexture;
GLfloat m_shadowQualityToShader;
- bool m_querySelection;
bool m_cachedSmoothSurface;
+ bool m_flatSupported;
bool m_cachedSurfaceGridOn;
-
- Drawer *m_drawer;
+ SelectionPointer *m_selectionPointer;
+ bool m_selectionActive;
+ bool m_xFlipped;
+ bool m_zFlipped;
+ bool m_yFlipped;
+ AbstractRenderItem m_dummyRenderItem;
+ QSurfaceDataArray m_dataArray;
+ QSurfaceDataArray m_sliceDataArray;
+ QRect m_sampleSpace;
+ GLint m_shadowQualityMultiplier;
+ QSizeF m_areaSize;
+ uint m_cachedSelectionId;
+ bool m_selectionModeChanged;
+ bool m_hasHeightAdjustmentChanged;
public:
- explicit Surface3dRenderer(Surface3dController *controller);
- ~Surface3dRenderer();
+ explicit Surface3DRenderer(Surface3DController *controller);
+ ~Surface3DRenderer();
- void initializeOpenGL();
- void render(CameraHelper *camera, const GLuint defaultFboHandle = 0);
+ void updateDataModel(QSurfaceDataProxy *dataProxy);
+ void updateScene(Q3DScene *scene);
+ void drawSlicedScene();
+ void render(GLuint defaultFboHandle = 0);
- // TODO: Not thread-safe, needs rethinking how axes create labels
- Drawer *drawer() { return m_drawer; }
+protected:
+ void initializeOpenGL();
+ virtual void loadMeshFile();
public slots:
- void updateTheme(Theme theme);
- void updateSmoothStatus(bool enable);
+ bool 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();
+ void updateSurfaceGradient(const QLinearGradient &gradient);
+ void updateSlicingActive(bool isSlicing);
+ void updateSelectionMode(QDataVis::SelectionMode mode);
-#if !defined(QT_OPENGL_ES_2)
- void updateDepthBuffer();
-#endif
+private:
+ void updateSliceDataModel(int selectionId);
+ virtual void updateShadowQuality(QDataVis::ShadowQuality quality);
+ virtual void updateTextures();
+ virtual void initShaders(const QString &vertexShader, const QString &fragmentShader);
+ QRect calculateSampleRect(const QSurfaceDataArray &array);
void loadBackgroundMesh();
void loadGridLineMesh();
+ void loadLabelMesh();
void loadSurfaceObj();
-
- // TODO: temp
- void setXZStuff(GLint segmentXCount, GLint segmentZCount);
- void setSeries(QList<qreal> series);
-
-private:
- void drawScene(CameraHelper *camera, const GLuint defaultFboHandle);
+ void loadSliceSurfaceObj();
+ void drawScene(GLuint defaultFboHandle);
+ void handleResize();
void calculateSceneScalingFactors();
void initBackgroundShaders(const QString &vertexShader, const QString &fragmentShader);
+ void initLabelShaders(const QString &vertexShader, const QString &fragmentShader);
void initSelectionShaders();
void initSurfaceShaders();
+ void initSelectionBuffer();
+ void initDepthShader();
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);
+ void surfacePointSelected(int id);
+ QString createSelectionLabel(qreal value, int column, int row);
+#if !defined(QT_OPENGL_ES_2)
+ void updateDepthBuffer();
+#endif
- Q_DISABLE_COPY(Surface3dRenderer)
+ Q_DISABLE_COPY(Surface3DRenderer)
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif // SURFACE3DRENDERER_P_H
diff --git a/src/datavisualization/engine/theme.cpp b/src/datavisualization/engine/theme.cpp
new file mode 100644
index 00000000..d9f2974a
--- /dev/null
+++ b/src/datavisualization/engine/theme.cpp
@@ -0,0 +1,250 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 "theme_p.h"
+
+#ifdef Q_OS_WIN
+#include <windows.h>
+#include <stdio.h>
+#endif
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+Theme::Theme()
+ : m_baseColor(QColor(Qt::gray)),
+ m_heightColor(QColor(Qt::black)),
+ m_depthColor(QColor(Qt::black)),
+ m_backgroundColor(QColor(Qt::gray)),
+ m_windowColor(QColor(Qt::gray)),
+ m_textColor(QColor(Qt::white)),
+ m_textBackgroundColor(QColor(0x00, 0x00, 0x00, 0xa0)),
+ m_gridLine(QColor(Qt::black)),
+ m_highlightBarColor(QColor(Qt::red)),
+ m_highlightRowColor(QColor(Qt::darkRed)),
+ m_highlightColumnColor(QColor(Qt::darkMagenta)),
+ m_surfaceGradient(QLinearGradient(1, 1000, 0, 0)),
+ m_lightStrength(4.0f),
+ m_ambientStrength(0.3f),
+ m_highlightLightStrength(8.0f),
+ m_uniformColor(true),
+ m_labelBorders(false)
+{
+ // Default values for surface gradient
+}
+
+Theme::~Theme()
+{
+}
+
+QDataVis::Theme Theme::theme()
+{
+ return m_theme;
+}
+
+void Theme::useTheme(QDataVis::Theme theme)
+{
+ m_theme = theme;
+ switch (theme) {
+ case QDataVis::ThemeQt: {
+ m_baseColor = QColor(QRgb(0x80c342));
+ //m_heightColor = QColor(QRgb(0x));
+ //m_depthColor = QColor(QRgb(0x));
+ m_backgroundColor = QColor(QRgb(0xffffff));
+ m_windowColor = QColor(QRgb(0xffffff));
+ m_textColor = QColor(QRgb(0x35322f));
+ m_textBackgroundColor = QColor(0xff, 0xff, 0xff, 0x99);
+ m_gridLine = QColor(QRgb(0xd7d6d5));
+ m_highlightBarColor = QColor(QRgb(0x14aaff));
+ m_highlightRowColor = QColor(QRgb(0x6400aa));
+ m_highlightColumnColor = QColor(QRgb(0x6400aa));
+ m_lightStrength = 5.0f;
+ m_ambientStrength = 0.5f;
+ m_highlightLightStrength = 5.0f;
+ m_uniformColor = true;
+ m_labelBorders = true;
+ break;
+ }
+ case QDataVis::ThemePrimaryColors: {
+ m_baseColor = QColor(QRgb(0xffe400));
+ //m_heightColor = QColor(QRgb(0x));
+ //m_depthColor = QColor(QRgb(0x));
+ m_backgroundColor = QColor(QRgb(0xffffff));
+ m_windowColor = QColor(QRgb(0xffffff));
+ m_textColor = QColor(QRgb(0x000000));
+ m_textBackgroundColor = QColor(0xff, 0xff, 0xff, 0x99);
+ m_gridLine = QColor(QRgb(0xd7d6d5));
+ m_highlightBarColor = QColor(QRgb(0x27beee));
+ m_highlightRowColor = QColor(QRgb(0xee1414));
+ m_highlightColumnColor = QColor(QRgb(0xee1414));
+ m_lightStrength = 5.0f;
+ m_ambientStrength = 0.5f;
+ m_highlightLightStrength = 5.0f;
+ m_uniformColor = true;
+ m_labelBorders = false;
+ break;
+ }
+ case QDataVis::ThemeDigia: {
+ m_baseColor = QColor(QRgb(0xcccccc));
+ //m_heightColor = QColor(QRgb(0x));
+ //m_depthColor = QColor(QRgb(0x));
+ m_backgroundColor = QColor(QRgb(0xffffff));
+ m_windowColor = QColor(QRgb(0xffffff));
+ m_textColor = QColor(QRgb(0x000000));
+ m_textBackgroundColor = QColor(0xff, 0xff, 0xff, 0x80);
+ m_gridLine = QColor(QRgb(0xd7d6d5));
+ m_highlightBarColor = QColor(QRgb(0xfa0000));
+ m_highlightRowColor = QColor(QRgb(0x555555));
+ m_highlightColumnColor = QColor(QRgb(0x555555));
+ m_lightStrength = 5.0f;
+ m_ambientStrength = 0.5f;
+ m_highlightLightStrength = 5.0f;
+ m_uniformColor = false;
+ m_labelBorders = false;
+ break;
+ }
+ case QDataVis::ThemeStoneMoss: {
+ m_baseColor = QColor(QRgb(0xbeb32b));
+ //m_heightColor = QColor(QRgb(0x));
+ //m_depthColor = QColor(QRgb(0x));
+ m_backgroundColor = QColor(QRgb(0x4d4d4f));
+ m_windowColor = QColor(QRgb(0x4d4d4f));
+ m_textColor = QColor(QRgb(0xffffff));
+ m_textBackgroundColor = QColor(0x4d, 0x4d, 0x4f, 0xcd);
+ m_gridLine = QColor(QRgb(0x3e3e40));
+ m_highlightBarColor = QColor(QRgb(0xfbf6d6));
+ m_highlightRowColor = QColor(QRgb(0x442f20));
+ m_highlightColumnColor = QColor(QRgb(0x442f20));
+ m_lightStrength = 5.0f;
+ m_ambientStrength = 0.5f;
+ m_highlightLightStrength = 5.0f;
+ m_uniformColor = true;
+ m_labelBorders = true;
+ break;
+ }
+ case QDataVis::ThemeArmyBlue: {
+ m_baseColor = QColor(QRgb(0x495f76));
+ //m_heightColor = QColor(QRgb(0x));
+ //m_depthColor = QColor(QRgb(0x));
+ m_backgroundColor = QColor(QRgb(0xd5d6d7));
+ m_windowColor = QColor(QRgb(0xd5d6d7));
+ m_textColor = QColor(QRgb(0x000000));
+ m_textBackgroundColor = QColor(0xd5, 0xd6, 0xd7, 0xcd);
+ m_gridLine = QColor(QRgb(0xaeadac));
+ m_highlightBarColor = QColor(QRgb(0x2aa2f9));
+ m_highlightRowColor = QColor(QRgb(0x103753));
+ m_highlightColumnColor = QColor(QRgb(0x103753));
+ m_lightStrength = 5.0f;
+ m_ambientStrength = 0.5f;
+ m_highlightLightStrength = 5.0f;
+ m_uniformColor = false;
+ m_labelBorders = false;
+ break;
+ }
+ case QDataVis::ThemeRetro: {
+ m_baseColor = QColor(QRgb(0x533b23));
+ //m_heightColor = QColor(QRgb(0x));
+ //m_depthColor = QColor(QRgb(0x));
+ m_backgroundColor = QColor(QRgb(0xe9e2ce));
+ m_windowColor = QColor(QRgb(0xe9e2ce));
+ m_textColor = QColor(QRgb(0x000000));
+ m_textBackgroundColor = QColor(0xe9, 0xe2, 0xce, 0xc0);
+ m_gridLine = QColor(QRgb(0xd0c0b0));
+ m_highlightBarColor = QColor(QRgb(0x8ea317));
+ m_highlightRowColor = QColor(QRgb(0xc25708));
+ m_highlightColumnColor = QColor(QRgb(0xc25708));
+ m_lightStrength = 5.0f;
+ m_ambientStrength = 0.5f;
+ m_highlightLightStrength = 5.0f;
+ m_uniformColor = false;
+ m_labelBorders = false;
+ break;
+ }
+ case QDataVis::ThemeEbony: {
+ m_baseColor = QColor(QRgb(0xffffff));
+ //m_heightColor = QColor(QRgb(0x));
+ //m_depthColor = QColor(QRgb(0x));
+ m_backgroundColor = QColor(QRgb(0x000000));
+ m_windowColor = QColor(QRgb(0x000000));
+ m_textColor = QColor(QRgb(0xaeadac));
+ m_textBackgroundColor = QColor(0x00, 0x00, 0x00, 0xcd);
+ m_gridLine = QColor(QRgb(0x35322f));
+ m_highlightBarColor = QColor(QRgb(0xf5dc0d));
+ m_highlightRowColor = QColor(QRgb(0xd72222));
+ m_highlightColumnColor = QColor(QRgb(0xd72222));
+ m_lightStrength = 5.0f;
+ m_ambientStrength = 0.5f;
+ m_highlightLightStrength = 5.0f;
+ m_uniformColor = true;
+ m_labelBorders = false;
+ break;
+ }
+ case QDataVis::ThemeIsabelle: {
+ m_baseColor = QColor(QRgb(0xf9d900));
+ //m_heightColor = QColor(QRgb(0x));
+ //m_depthColor = QColor(QRgb(0x));
+ m_backgroundColor = QColor(QRgb(0x000000));
+ m_windowColor = QColor(QRgb(0x000000));
+ m_textColor = QColor(QRgb(0xaeadac));
+ m_textBackgroundColor = QColor(0x00, 0x00, 0x00, 0xc0);
+ m_gridLine = QColor(QRgb(0x35322f));
+ m_highlightBarColor = QColor(QRgb(0xfff7cc));
+ m_highlightRowColor = QColor(QRgb(0xde0a0a));
+ m_highlightColumnColor = QColor(QRgb(0xde0a0a));
+ m_lightStrength = 5.0f;
+ m_ambientStrength = 0.5f;
+ m_highlightLightStrength = 5.0f;
+ m_uniformColor = true;
+ m_labelBorders = false;
+ break;
+ }
+ default:
+ break;
+ }
+ if (m_uniformColor) {
+ m_surfaceGradient.setColorAt(0.0, m_baseColor);
+ } else {
+ m_surfaceGradient.setColorAt(0.0, QColor(m_baseColor.redF() * 0.7,
+ m_baseColor.greenF() * 0.7,
+ m_baseColor.blueF() * 0.7));
+ }
+ m_surfaceGradient.setColorAt(1.0, m_baseColor);
+}
+
+void Theme::setFromTheme(Theme &theme)
+{
+ m_theme = theme.m_theme;
+ 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;
+ m_labelBorders = theme.m_labelBorders;
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavis3d/engine/theme_p.h b/src/datavisualization/engine/theme_p.h
index 31c47941..ec689f63 100644
--- a/src/datavis3d/engine/theme_p.h
+++ b/src/datavisualization/engine/theme_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -29,35 +29,35 @@
#ifndef THEME_P_H
#define THEME_P_H
-#include "datavis3dglobal_p.h"
+#include "datavisualizationglobal_p.h"
#include "q3dbars.h"
#include <QLinearGradient>
class QColor;
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
-class Theme
+class QT_DATAVISUALIZATION_EXPORT Theme
{
public:
explicit Theme();
~Theme();
- void useColorTheme(QDataVis::ColorTheme theme);
- QDataVis::ColorTheme colorTheme();
+ void useTheme(QDataVis::Theme theme);
+ QDataVis::Theme theme();
void setFromTheme(Theme &theme);
private:
friend class Abstract3DController;
friend class Abstract3DRenderer;
- friend class Bars3dRenderer;
- friend class Maps3DController;
- friend class Surface3dRenderer;
- friend class Surface3dController;
+ friend class Bars3DRenderer;
+ friend class Surface3DRenderer;
+ friend class Surface3DController;
friend class Scatter3DRenderer;
+ friend class SelectionPointer;
friend class Drawer;
- QDataVis::ColorTheme m_colorTheme;
+ QDataVis::Theme m_theme;
QColor m_baseColor;
QColor m_heightColor;
QColor m_depthColor;
@@ -74,8 +74,9 @@ private:
float m_ambientStrength;
float m_highlightLightStrength;
bool m_uniformColor;
+ bool m_labelBorders;
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif
diff --git a/src/datavis3d/global/datavis3dglobal_p.h b/src/datavisualization/global/datavisualizationglobal_p.h
index d556c5e1..4da1023c 100644
--- a/src/datavis3d/global/datavis3dglobal_p.h
+++ b/src/datavisualization/global/datavisualizationglobal_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,33 +20,35 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization 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
+#ifndef DATAVISUALIZATIONGLOBAL_P_H
+#define DATAVISUALIZATIONGLOBAL_P_H
-#include "qdatavis3dglobal.h"
-#include "qdatavis3denums.h"
+#include "qdatavisualizationglobal.h"
+#include "qdatavisualizationenums.h"
#include <QOpenGLFunctions>
#include <QVector3D>
#include <QDebug>
-//#define ROTATE_ZOOM_SELECTION
-
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_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;
+// Distance from camera to origin
+const GLfloat cameraDistance = 6.0f;
+// Size of font to be used in label texture rendering. Doesn't affect the actual font size.
+const int textureFontSize = 50;
// 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
+QT_DATAVISUALIZATION_END_NAMESPACE
-#endif // DATAVIS3DGLOBAL_P_H
+#endif // DATAVISUALIZATIONGLOBAL_P_H
diff --git a/src/datavisualization/global/global.pri b/src/datavisualization/global/global.pri
new file mode 100644
index 00000000..0fd7c576
--- /dev/null
+++ b/src/datavisualization/global/global.pri
@@ -0,0 +1,4 @@
+HEADERS += \
+ $$PWD/qdatavisualizationglobal.h \
+ $$PWD/qdatavisualizationenums.h \
+ $$PWD/datavisualizationglobal_p.h
diff --git a/src/datavisualization/global/qdatavisualizationenums.h b/src/datavisualization/global/qdatavisualizationenums.h
new file mode 100644
index 00000000..3d765ff2
--- /dev/null
+++ b/src/datavisualization/global/qdatavisualizationenums.h
@@ -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 QtDataVisualization 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 QDATAVISUALIZATIONENUMS_H
+#define QDATAVISUALIZATIONENUMS_H
+
+#include <QtDataVisualization/qdatavisualizationglobal.h>
+#include <QObject>
+
+// namespace must be declared without using macros for qdoc
+namespace QtDataVisualization {
+
+class QT_DATAVISUALIZATION_EXPORT QDataVis : public QObject
+{
+ Q_OBJECT
+ Q_ENUMS(MeshStyle)
+ Q_ENUMS(CameraPreset)
+ Q_ENUMS(Theme)
+ Q_ENUMS(SelectionMode)
+ Q_ENUMS(ShadowQuality)
+ Q_ENUMS(LabelStyle)
+
+public:
+ enum InputState {
+ InputStateNone = 0,
+ InputStateOnScene,
+ InputStateOnOverview,
+ InputStateOnSlice,
+ InputStateRotating,
+ InputStateOnPinch
+ };
+
+ enum MeshStyle {
+ MeshStyleBars = 0,
+ MeshStylePyramids,
+ MeshStyleCones,
+ MeshStyleCylinders,
+ MeshStyleBevelBars,
+ MeshStyleSpheres,
+ MeshStyleDots
+ };
+
+ enum CameraPreset {
+ CameraPresetNone = -1,
+ CameraPresetFrontLow = 0,
+ CameraPresetFront,
+ CameraPresetFrontHigh,
+ CameraPresetLeftLow,
+ CameraPresetLeft,
+ CameraPresetLeftHigh,
+ CameraPresetRightLow,
+ CameraPresetRight,
+ CameraPresetRightHigh,
+ CameraPresetBehindLow,
+ CameraPresetBehind,
+ CameraPresetBehindHigh,
+ CameraPresetIsometricLeft,
+ CameraPresetIsometricLeftHigh,
+ CameraPresetIsometricRight,
+ CameraPresetIsometricRightHigh,
+ CameraPresetDirectlyAbove,
+ CameraPresetDirectlyAboveCW45,
+ CameraPresetDirectlyAboveCCW45,
+ CameraPresetFrontBelow,
+ CameraPresetLeftBelow,
+ CameraPresetRightBelow,
+ CameraPresetBehindBelow,
+ CameraPresetDirectlyBelow
+ };
+
+ enum Theme {
+ ThemeDefault = -1,
+ ThemeQt,
+ ThemePrimaryColors,
+ ThemeDigia,
+ ThemeStoneMoss,
+ ThemeArmyBlue,
+ ThemeRetro,
+ ThemeEbony,
+ ThemeIsabelle
+ };
+
+ enum SelectionMode {
+ SelectionModeNone = 0,
+ SelectionModeItem,
+ SelectionModeItemAndRow,
+ SelectionModeItemAndColumn,
+ SelectionModeItemRowAndColumn,
+ SelectionModeSliceRow,
+ SelectionModeSliceColumn
+ };
+
+ enum ShadowQuality {
+ ShadowQualityNone = 0,
+ ShadowQualityLow,
+ ShadowQualityMedium,
+ ShadowQualityHigh,
+ ShadowQualitySoftLow,
+ ShadowQualitySoftMedium,
+ ShadowQualitySoftHigh
+ };
+
+ enum LabelStyle {
+ LabelStyleOpaque = 0,
+ LabelStyleFromTheme,
+ LabelStyleTransparent
+ };
+};
+}
+
+#endif
diff --git a/src/datavisualization/global/qdatavisualizationglobal.h b/src/datavisualization/global/qdatavisualizationglobal.h
new file mode 100644
index 00000000..ac734960
--- /dev/null
+++ b/src/datavisualization/global/qdatavisualizationglobal.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 QtDataVisualization 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 QDATAVISUALIZATIONGLOBAL_H
+#define QDATAVISUALIZATIONGLOBAL_H
+
+#include <qglobal.h>
+
+#define QT_DATAVISUALIZATION_VERSION_STR "0.0.1"
+/*
+ QT_DATAVISUALIZATION_VERSION is (major << 16) + (minor << 8) + patch.
+*/
+#define QT_DATAVISUALIZATION_VERSION 0x000001
+/*
+ can be used like #if (QT_DATAVISUALIZATION_VERSION >= QT_DATAVISUALIZATION_VERSION_CHECK(1, 1, 0))
+*/
+#define QT_DATAVISUALIZATION_VERSION_CHECK(major, minor, patch) ((major<<16)|(minor<<8)|(patch))
+
+#if defined(QT_DATAVISUALIZATION_LIBRARY)
+# define QT_DATAVISUALIZATION_EXPORT Q_DECL_EXPORT
+#else
+# define QT_DATAVISUALIZATION_EXPORT Q_DECL_IMPORT
+#endif
+
+#if defined(BUILD_PRIVATE_UNIT_TESTS) && defined(QT_DATAVISUALIZATION_LIBRARY)
+# define QT_DATAVISUALIZATION_AUTOTEST_EXPORT Q_DECL_EXPORT
+#elif defined(BUILD_PRIVATE_UNIT_TESTS) && !defined(QT_DATAVISUALIZATION_LIBRARY)
+# define QT_DATAVISUALIZATION_AUTOTEST_EXPORT Q_DECL_IMPORT
+#else
+# define QT_DATAVISUALIZATION_AUTOTEST_EXPORT
+#endif
+
+#ifdef QT_DATAVISUALIZATION_STATICLIB
+# undef QT_DATAVISUALIZATION_EXPORT
+# undef QT_DATAVISUALIZATION_AUTOTEST_EXPORT
+# define QT_DATAVISUALIZATION_EXPORT
+# define QT_DATAVISUALIZATION_AUTOTEST_EXPORT
+#endif
+
+#define QT_DATAVISUALIZATION_NAMESPACE QtDataVisualization
+
+#ifdef QT_DATAVISUALIZATION_NAMESPACE
+# define QT_DATAVISUALIZATION_BEGIN_NAMESPACE namespace QT_DATAVISUALIZATION_NAMESPACE {
+# define QT_DATAVISUALIZATION_END_NAMESPACE }
+# define QT_DATAVISUALIZATION_USE_NAMESPACE using namespace QT_DATAVISUALIZATION_NAMESPACE;
+#else
+# define QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+# define QT_DATAVISUALIZATION_END_NAMESPACE
+# define QT_DATAVISUALIZATION_USE_NAMESPACE
+#endif
+
+#endif // QVIS3DGLOBAL_H
diff --git a/src/datavisualization/global/qtdatavisualizationenums.qdoc b/src/datavisualization/global/qtdatavisualizationenums.qdoc
new file mode 100644
index 00000000..fde6a258
--- /dev/null
+++ b/src/datavisualization/global/qtdatavisualizationenums.qdoc
@@ -0,0 +1,176 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 QtDataVisualization
+ \inmodule QtDataVisualization
+ \target QtDataVisualization Enums
+*/
+
+/*!
+ \enum QtDataVisualization::QDataVis::InputState
+
+ Predefined input states for mouse and touch based input handlers. All states are not valid with all input handlers.
+
+ \value InputStateNone
+ Default "no input received" state.
+ \value InputStateOnScene
+ Mouse or touch input received on the 3D scene.
+ \value InputStateOnOverview
+ Mouse or touch input received on the overview area.
+ \value InputStateOnSlice
+ Mouse or touch input received on the slice view area.
+ \value InputStateRotating
+ Rotation of the 3D geometry ongoing.
+ \value InputStateOnPinch
+ Pinch/punch multitouch input received.
+*/
+
+/*!
+ \enum QtDataVisualization::QDataVis::MeshStyle
+
+ Predefined mesh types. All styles are not usable with all visualization types.
+
+ \value MeshStyleBars
+ Basic cubic bar.
+ \value MeshStylePyramids
+ Four-sided pyramid.
+ \value MeshStyleCones
+ Basic cone.
+ \value MeshStyleCylinders
+ Basic cylinder.
+ \value MeshStyleBevelBars
+ Slightly beveled (rounded) cubic bar.
+ \value MeshStyleSpheres
+ Sphere. Not usable in Q3DBars.
+ \value MeshStyleDots
+ Triangular pyramid. Usable only with Q3DScatter.
+*/
+
+/*!
+ \enum QtDataVisualization::QDataVis::CameraPreset
+
+ Predefined positions for camera.
+
+ \value CameraPresetNone
+ Used to indicate a preset has not been set, or the scene has been rotated freely.
+ \value CameraPresetFrontLow
+ \value CameraPresetFront
+ \value CameraPresetFrontHigh
+ \value CameraPresetLeftLow
+ \value CameraPresetLeft
+ \value CameraPresetLeftHigh
+ \value CameraPresetRightLow
+ \value CameraPresetRight
+ \value CameraPresetRightHigh
+ \value CameraPresetBehindLow
+ \value CameraPresetBehind
+ \value CameraPresetBehindHigh
+ \value CameraPresetIsometricLeft
+ \value CameraPresetIsometricLeftHigh
+ \value CameraPresetIsometricRight
+ \value CameraPresetIsometricRightHigh
+ \value CameraPresetDirectlyAbove
+ \value CameraPresetDirectlyAboveCW45
+ \value CameraPresetDirectlyAboveCCW45
+ \value CameraPresetFrontBelow
+ In Q3DBars from CameraPresetFrontBelow onward these only work for graphs including negative
+ values. They act as Preset...Low for positive-only values.
+ \value CameraPresetLeftBelow
+ \value CameraPresetRightBelow
+ \value CameraPresetBehindBelow
+ \value CameraPresetDirectlyBelow
+ Acts as CameraPresetFrontLow for positive -only bars.
+*/
+
+/*!
+ \enum QtDataVisualization::QDataVis::Theme
+
+ Predefined themes.
+
+ \value ThemeDefault
+ Used only in QML to indicate a theme has not been set.
+ \value ThemeQt
+ \value ThemePrimaryColors
+ \value ThemeDigia
+ \value ThemeStoneMoss
+ \value ThemeArmyBlue
+ \value ThemeRetro
+ \value ThemeEbony
+ \value ThemeIsabelle
+*/
+
+/*!
+ \enum QtDataVisualization::QDataVis::SelectionMode
+
+ Item selection modes.
+
+ \value SelectionModeNone
+ Selection mode disabled.
+ \value SelectionModeItem
+ Selection selects a single item.
+ \value SelectionModeItemAndRow
+ Selection selects a single item and highlights the row it is on. In Q3DBars only.
+ \value SelectionModeItemAndColumn
+ Selection selects a single item and highlights the column it is on. In Q3DBars only.
+ \value SelectionModeItemRowAndColumn
+ Selection selects a single item and highlights the row and the column it is on. In
+ Q3DBars only.
+ \value SelectionModeSliceRow
+ Selection selects a single item 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. In Q3DBars only.
+ \value SelectionModeSliceColumn
+ Selection selects a single item 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. In Q3DBars only.
+*/
+
+/*!
+ \enum QtDataVisualization::QDataVis::ShadowQuality
+
+ Quality of shadows.
+
+ \value ShadowQualityNone
+ Shadows are disabled.
+ \value ShadowQualityLow
+ Shadows are rendered in low quality.
+ \value ShadowQualityMedium
+ Shadows are rendered in medium quality.
+ \value ShadowQualityHigh
+ Shadows are rendered in high quality.
+ \value ShadowQualitySoftLow
+ Shadows are rendered in low quality with softened edges.
+ \value ShadowQualitySoftMedium
+ Shadows are rendered in medium quality with softened edges.
+ \value ShadowQualitySoftHigh
+ Shadows are rendered in high quality with softened edges.
+*/
+
+/*!
+ \enum QtDataVisualization::QDataVis::LabelStyle
+
+ Label styles.
+
+ \value LabelStyleOpaque
+ Fully opaque background, using colors and borders from theme.
+ \value LabelStyleFromTheme
+ Use transparencies, colors and borders from theme.
+ \value LabelStyleTransparent
+ Fully transparent background, using text color from theme.
+*/
diff --git a/src/datavisualization/input/input.pri b/src/datavisualization/input/input.pri
new file mode 100644
index 00000000..5a4c4a76
--- /dev/null
+++ b/src/datavisualization/input/input.pri
@@ -0,0 +1,12 @@
+HEADERS += \
+ $$PWD/qabstract3dinputhandler.h \
+ $$PWD/q3dinputhandler.h \
+ $$PWD/qtouch3dinputhandler.h \
+ $$PWD/qabstract3dinputhandler_p.h \
+ $$PWD/q3dinputhandler_p.h \
+ $$PWD/qtouch3dinputhandler_p.h
+
+SOURCES += \
+ $$PWD/qabstract3dinputhandler.cpp \
+ $$PWD/q3dinputhandler.cpp \
+ $$PWD/qtouch3dinputhandler.cpp
diff --git a/src/datavisualization/input/q3dinputhandler.cpp b/src/datavisualization/input/q3dinputhandler.cpp
new file mode 100644
index 00000000..5267568c
--- /dev/null
+++ b/src/datavisualization/input/q3dinputhandler.cpp
@@ -0,0 +1,190 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 "datavisualizationglobal_p.h"
+#include "q3dinputhandler.h"
+#include "q3dcamera_p.h"
+#include "q3dlight.h"
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+const int minZoomLevel = 10;
+const int halfSizeZoomLevel = 50;
+const int oneToOneZoomLevel = 100;
+const int maxZoomLevel = 500;
+
+const int nearZoomRangeDivider = 12;
+const int midZoomRangeDivider = 60;
+const int farZoomRangeDivider = 120;
+
+const float rotationSpeed = 100.0f;
+
+/*!
+ * \class Q3DInputHandler
+ * \inmodule QtDataVisualization
+ * \brief Basic wheel mouse based input handler.
+ * \since 1.0.0
+ *
+ * Q3DInputHandler is the basic input handler for wheel mouse type of input devices.
+ *
+ * Default input handler has the following functionalty:
+ * \table
+ * \header
+ * \li Mouse action \li Action
+ * \row
+ * \li Right button pressed \li Rotate graph within limits set for Q3DCamera
+ * \row
+ * \li Left click \li Select item under cursor or remove selection if none
+ * \row
+ * \li Mouse wheel \li Zoom in/out within default range (10...500%)
+ * \row
+ * \li Left click on secodanry view \li Return to primary view when in slice mode
+ * \note Slice mode is available in Q3DBars and Q3DSurface only
+ * \endtable
+ */
+
+/*!
+ * Constructs the basic mouse input handler. An optional \a parent parameter can be given
+ * and is then passed to QObject constructor.
+ */
+Q3DInputHandler::Q3DInputHandler(QObject *parent) :
+ QAbstract3DInputHandler(parent)
+{
+}
+
+/*!
+ * Destroys the input handler.
+ */
+Q3DInputHandler::~Q3DInputHandler()
+{
+}
+
+// Input event listeners
+/*!
+ * Override this to change handling of mouse press events.
+ * Mouse press event is given in the \a event and the mouse position in \a mousePos.
+ */
+void Q3DInputHandler::mousePressEvent(QMouseEvent *event, const QPoint &mousePos)
+{
+#if defined(Q_OS_ANDROID)
+ Q_UNUSED(event);
+ Q_UNUSED(mousePos);
+#else
+ if (Qt::LeftButton == event->button()) {
+ if (scene()->isSlicingActive()) {
+ if (scene()->isPointInPrimarySubView(mousePos)) {
+ setInputState(QDataVis::InputStateOnOverview);
+ } else if (scene()->isPointInSecondarySubView(mousePos)) {
+ setInputState(QDataVis::InputStateOnSlice);
+ } else {
+ setInputState(QDataVis::InputStateNone);
+ }
+ } else {
+ setInputState(QDataVis::InputStateOnScene);
+ // update mouse positions to prevent jumping when releasing or repressing a button
+ setInputPosition(mousePos);
+ }
+ } else if (Qt::MiddleButton == event->button()) {
+ // reset rotations
+ setInputPosition(QPoint(0, 0));
+ } else if (Qt::RightButton == event->button()) {
+ // disable rotating when in slice view
+ if (!scene()->isSlicingActive())
+ setInputState(QDataVis::InputStateRotating);
+ // update mouse positions to prevent jumping when releasing or repressing a button
+ setInputPosition(mousePos);
+ }
+#endif
+}
+
+/*!
+ * Override this to change handling of mouse release events.
+ * Mouse release event is given in the \a event and the mouse position in \a mousePos.
+ */
+void Q3DInputHandler::mouseReleaseEvent(QMouseEvent *event, const QPoint &mousePos)
+{
+ Q_UNUSED(event);
+#if defined (Q_OS_ANDROID)
+ Q_UNUSED(mousePos);
+#else
+ if (QDataVis::InputStateRotating == inputState()) {
+ // update mouse positions to prevent jumping when releasing or repressing a button
+ setInputPosition(mousePos);
+ }
+ setInputState(QDataVis::InputStateNone);
+#endif
+}
+
+/*!
+ * Override this to change handling of mouse move events.
+ * Mouse move event is given in the \a event and the mouse position in \a mousePos.
+ */
+void Q3DInputHandler::mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos)
+{
+ Q_UNUSED(event);
+#if defined (Q_OS_ANDROID)
+ Q_UNUSED(mousePos);
+#else
+ if (QDataVis::InputStateRotating == inputState()) {
+ // Calculate mouse movement since last frame
+ qreal xRotation = scene()->activeCamera()->xRotation();
+ qreal yRotation = scene()->activeCamera()->yRotation();
+ float mouseMoveX = float(inputPosition().x() - mousePos.x())
+ / (scene()->viewport().width() / rotationSpeed);
+ float mouseMoveY = float(inputPosition().y() - mousePos.y())
+ / (scene()->viewport().height() / rotationSpeed);
+ // Apply to rotations
+ xRotation -= mouseMoveX;
+ yRotation -= mouseMoveY;
+ scene()->activeCamera()->setXRotation(xRotation);
+ scene()->activeCamera()->setYRotation(yRotation);
+ scene()->activeCamera()->d_ptr->updateViewMatrix(1.0f);
+
+ setPreviousInputPos(inputPosition());
+ setInputPosition(mousePos);
+ }
+#endif
+}
+
+/*!
+ * Override this to change handling of wheel events.
+ * The wheel event is given in the \a event.
+ */
+void Q3DInputHandler::wheelEvent(QWheelEvent *event)
+{
+ // disable zooming if in slice view
+ if (scene()->isSlicingActive())
+ return;
+
+ // Adjust zoom level based on what zoom range we're in.
+ int zoomLevel = scene()->activeCamera()->zoomLevel();
+ if (zoomLevel > oneToOneZoomLevel)
+ zoomLevel += event->angleDelta().y() / nearZoomRangeDivider;
+ else if (zoomLevel > halfSizeZoomLevel)
+ zoomLevel += event->angleDelta().y() / midZoomRangeDivider;
+ else
+ zoomLevel += event->angleDelta().y() / farZoomRangeDivider;
+ if (zoomLevel > maxZoomLevel)
+ zoomLevel = maxZoomLevel;
+ else if (zoomLevel < minZoomLevel)
+ zoomLevel = minZoomLevel;
+
+ scene()->activeCamera()->setZoomLevel(zoomLevel);
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualization/input/q3dinputhandler.h b/src/datavisualization/input/q3dinputhandler.h
new file mode 100644
index 00000000..a7fa0573
--- /dev/null
+++ b/src/datavisualization/input/q3dinputhandler.h
@@ -0,0 +1,48 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 QDEFAULT3DINPUTHANDLER_H
+#define QDEFAULT3DINPUTHANDLER_H
+
+#include <QtDataVisualization/qabstract3dinputhandler.h>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class Q3DInputHandler; // Workaround for qdoc bug, removing this will cause qdoc compiler to not find the class.
+
+class QT_DATAVISUALIZATION_EXPORT Q3DInputHandler : public QAbstract3DInputHandler
+{
+ Q_OBJECT
+
+public:
+ explicit Q3DInputHandler(QObject *parent = 0);
+ virtual ~Q3DInputHandler();
+
+ // Input event listeners
+ virtual void mousePressEvent(QMouseEvent *event, const QPoint &mousePos);
+ virtual void mouseReleaseEvent(QMouseEvent *event, const QPoint &mousePos);
+ virtual void mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos);
+ virtual void wheelEvent(QWheelEvent *event);
+
+private:
+ Q_DISABLE_COPY(Q3DInputHandler)
+};
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
+#endif // QDEFAULT3DINPUTHANDLER_H
diff --git a/src/datavis3d/engine/q3dmaps_p.h b/src/datavisualization/input/q3dinputhandler_p.h
index 166ed8f7..af8bef5f 100644
--- a/src/datavis3d/engine/q3dmaps_p.h
+++ b/src/datavisualization/input/q3dinputhandler_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,32 +20,32 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization 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 Q3DMAPS_P_H
-#define Q3DMAPS_P_H
+#ifndef Q3DINPUTHANDLER_P_H
+#define Q3DINPUTHANDLER_P_H
-#include "maps3dcontroller_p.h"
-#include "qdatavis3denums.h"
+#include "datavisualizationglobal_p.h"
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
-class Q3DMaps;
+class Q3DInputHandler;
-class Q3DMapsPrivate : public QObject
+class Q3DInputHandlerPrivate
{
public:
- Q3DMapsPrivate(Q3DMaps *q, const QRect &rect);
- ~Q3DMapsPrivate();
+ Q3DInputHandlerPrivate(Q3DInputHandler *q);
+ ~Q3DInputHandlerPrivate();
+
+public:
+ Q3DInputHandler *q_ptr;
- Q3DMaps *q_ptr;
- Maps3DController *m_shared;
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
-#endif
+#endif // Q3DINPUTHANDLER_P_H
diff --git a/src/datavisualization/input/qabstract3dinputhandler.cpp b/src/datavisualization/input/qabstract3dinputhandler.cpp
new file mode 100644
index 00000000..e111ff42
--- /dev/null
+++ b/src/datavisualization/input/qabstract3dinputhandler.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 QtDataVisualization 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 "qabstract3dinputhandler_p.h"
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+/*!
+ \class QAbstract3DInputHandler
+ \inmodule QtDataVisualization
+ \brief Baseclass for implementations of input handlers.
+ \since 1.0.0
+
+ QAbstract3DInputHandler is a baseclass that is subclassed by different input handling implementations
+ that take input events and translate those to camera and light movements. Input handlers also translate
+ raw input events to slicing and selection events in the scene.
+*/
+
+/*!
+ * Constructs the baseclass. An optional \a parent parameter can be given
+ * and is then passed to QObject constructor.
+ */
+QAbstract3DInputHandler::QAbstract3DInputHandler(QObject *parent) :
+ QObject(parent),
+ d_ptr(new QAbstract3DInputHandlerPrivate(this))
+{
+}
+
+/*!
+ * Destroys the baseclass.
+ */
+QAbstract3DInputHandler::~QAbstract3DInputHandler()
+{
+}
+
+// Input event listeners
+/*!
+ * Override this to handle mouse double click events.
+ * Mouse double click event is given in the \a event.
+ */
+void QAbstract3DInputHandler::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ Q_UNUSED(event);
+}
+
+/*!
+ * Override this to handle touch input events.
+ * Touch event is given in the \a event.
+ */
+void QAbstract3DInputHandler::touchEvent(QTouchEvent *event)
+{
+ Q_UNUSED(event);
+}
+
+/*!
+ * Override this to handle mouse press events.
+ * Mouse press event is given in the \a event and the mouse position in \a mousePos.
+ */
+void QAbstract3DInputHandler::mousePressEvent(QMouseEvent *event, const QPoint &mousePos)
+{
+ Q_UNUSED(event);
+ Q_UNUSED(mousePos);
+}
+
+/*!
+ * Override this to handle mouse release events.
+ * Mouse release event is given in the \a event and the mouse position in \a mousePos.
+ */
+void QAbstract3DInputHandler::mouseReleaseEvent(QMouseEvent *event, const QPoint &mousePos)
+{
+ Q_UNUSED(event);
+ Q_UNUSED(mousePos);
+}
+
+/*!
+ * Override this to handle mouse move events.
+ * Mouse move event is given in the \a event and the mouse position in \a mousePos.
+ */
+void QAbstract3DInputHandler::mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos)
+{
+ Q_UNUSED(event);
+ Q_UNUSED(mousePos);
+}
+
+/*!
+ * Override this to handle wheel events.
+ * Wheel event is given in the \a event.
+ */
+void QAbstract3DInputHandler::wheelEvent(QWheelEvent *event)
+{
+ Q_UNUSED(event);
+}
+
+// Property get/set
+/*!
+ * \property QAbstract3DInputHandler::inputState
+ *
+ * Current enumerated input state based on the processed input events.
+ * When the state changes inputStateChanged() is emitted.
+ */
+QDataVis::InputState QAbstract3DInputHandler::inputState()
+{
+ return d_ptr->m_inputState;
+}
+
+void QAbstract3DInputHandler::setInputState(QDataVis::InputState inputState)
+{
+ if (inputState != d_ptr->m_inputState) {
+ d_ptr->m_inputState = inputState;
+ emit inputStateChanged(inputState);
+ }
+}
+
+/*!
+ * \property QAbstract3DInputHandler::inputPosition
+ *
+ * Last input position based on the processed input events.
+ */
+QPoint QAbstract3DInputHandler::inputPosition() const
+{
+ return d_ptr->m_inputPosition;
+}
+
+void QAbstract3DInputHandler::setInputPosition(const QPoint &position)
+{
+ if (position != d_ptr->m_inputPosition) {
+ d_ptr->m_inputPosition = position;
+ emit positionChanged(position);
+ }
+}
+
+/*!
+ * \return the manhattan length between last two input positions.
+ */
+int QAbstract3DInputHandler::prevDistance() const
+{
+ return d_ptr->m_prevDistance;
+}
+
+/*!
+ * Sets the \a distance (manhattan length) between last two input positions.
+ */
+void QAbstract3DInputHandler::setPrevDistance(int distance)
+{
+ d_ptr->m_prevDistance = distance;
+}
+
+/*!
+ * \property QAbstract3DInputHandler::scene
+ *
+ * The 3D scene this abstract inputhandler is controlling. Only one scene can be controlled by one input handler.
+ */
+Q3DScene *QAbstract3DInputHandler::scene() const
+{
+ return d_ptr->m_scene;
+}
+
+void QAbstract3DInputHandler::setScene(Q3DScene *scene)
+{
+ d_ptr->m_scene = scene;
+}
+
+/*!
+ * Sets the previous input position to the point given by \a position.
+ */
+void QAbstract3DInputHandler::setPreviousInputPos(const QPoint &position)
+{
+ d_ptr->m_previousInputPos = position;
+}
+
+/*!
+ * Returns the previous input position.
+ * \return Previous input position.
+ */
+QPoint QAbstract3DInputHandler::previousInputPos() const
+{
+ return d_ptr->m_previousInputPos;
+}
+
+
+QAbstract3DInputHandlerPrivate::QAbstract3DInputHandlerPrivate(QAbstract3DInputHandler *q) :
+ q_ptr(q),
+ m_prevDistance(0),
+ m_previousInputPos(QPoint(0,0)),
+ m_inputState(QDataVis::InputStateNone),
+ m_inputPosition(QPoint(0,0)),
+ m_scene(0)
+{
+}
+
+QAbstract3DInputHandlerPrivate::~QAbstract3DInputHandlerPrivate()
+{
+
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualization/input/qabstract3dinputhandler.h b/src/datavisualization/input/qabstract3dinputhandler.h
new file mode 100644
index 00000000..d7bf3aee
--- /dev/null
+++ b/src/datavisualization/input/qabstract3dinputhandler.h
@@ -0,0 +1,82 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 QABSTRACT3DINPUTHANDLER_H
+#define QABSTRACT3DINPUTHANDLER_H
+
+#include <QtDataVisualization/qdatavisualizationenums.h>
+#include <QtDataVisualization/q3dscene.h>
+#include <QMouseEvent>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class QAbstract3DInputHandlerPrivate;
+
+class QT_DATAVISUALIZATION_EXPORT QAbstract3DInputHandler : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QtDataVisualization::QDataVis::InputState inputState READ inputState WRITE setInputState NOTIFY inputStateChanged)
+ Q_PROPERTY(QPoint inputPosition READ inputPosition WRITE setInputPosition NOTIFY positionChanged)
+ Q_PROPERTY(Q3DScene *scene READ scene WRITE setScene NOTIFY sceneChanged)
+
+public:
+ explicit QAbstract3DInputHandler(QObject *parent = 0);
+ virtual ~QAbstract3DInputHandler();
+
+ // Input event listeners
+ virtual void mouseDoubleClickEvent(QMouseEvent *event);
+ virtual void touchEvent(QTouchEvent *event);
+ virtual void mousePressEvent(QMouseEvent *event, const QPoint &mousePos);
+ virtual void mouseReleaseEvent(QMouseEvent *event, const QPoint &mousePos);
+ virtual void mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos);
+ virtual void wheelEvent(QWheelEvent *event);
+
+public:
+ // TODO: Check if the inputState needs to be visible outside of subclasses in the final architecture
+ QDataVis::InputState inputState();
+ void setInputState(QDataVis::InputState inputState);
+
+ QPoint inputPosition() const;
+ void setInputPosition(const QPoint &position);
+
+ Q3DScene *scene() const;
+ void setScene(Q3DScene *scene);
+
+signals:
+ void positionChanged(const QPoint &position);
+ void inputStateChanged(QDataVis::InputState state);
+ void sceneChanged(const Q3DScene *scene);
+
+protected:
+ void setPrevDistance(int distance);
+ int prevDistance() const;
+ void setPreviousInputPos(const QPoint &position);
+ QPoint previousInputPos() const;
+
+private:
+ Q_DISABLE_COPY(QAbstract3DInputHandler)
+
+ QScopedPointer<QAbstract3DInputHandlerPrivate> d_ptr;
+
+ friend class Abstract3DController;
+ friend class QTouch3DInputHandlerPrivate;
+};
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
+#endif // QABSTRACT3DINPUTHANDLER_H
diff --git a/src/datavisualization/input/qabstract3dinputhandler_p.h b/src/datavisualization/input/qabstract3dinputhandler_p.h
new file mode 100644
index 00000000..cad1c667
--- /dev/null
+++ b/src/datavisualization/input/qabstract3dinputhandler_p.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 QtDataVisualization 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 QtDataVisualization 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 QABSTRACT3DINPUTHANDLER_P_H
+#define QABSTRACT3DINPUTHANDLER_P_H
+
+#include "datavisualizationglobal_p.h"
+#include "qabstract3dinputhandler.h"
+#include <QRect>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class QAbstract3DInputHandler;
+class Q3DScene;
+
+class QAbstract3DInputHandlerPrivate
+{
+public:
+ QAbstract3DInputHandlerPrivate(QAbstract3DInputHandler *q);
+ ~QAbstract3DInputHandlerPrivate();
+
+public:
+ QAbstract3DInputHandler *q_ptr;
+ int m_prevDistance;
+ QPoint m_previousInputPos;
+
+ GLfloat m_defaultXRotation;
+ GLfloat m_defaultYRotation;
+
+private:
+ QDataVis::InputState m_inputState;
+ QPoint m_inputPosition;
+ QRect m_mainViewPort;
+
+ // TODO: Check if this could be avoided with signals/slots or some other way.
+ Q3DScene *m_scene;
+ bool m_isDefaultHandler;
+
+ friend class QAbstract3DInputHandler;
+ friend class Abstract3DController;
+};
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
+#endif // QABSTRACT3DINPUTHANDLER_P_H
diff --git a/src/datavisualization/input/qtouch3dinputhandler.cpp b/src/datavisualization/input/qtouch3dinputhandler.cpp
new file mode 100644
index 00000000..fd079e88
--- /dev/null
+++ b/src/datavisualization/input/qtouch3dinputhandler.cpp
@@ -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 QtDataVisualization 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 "qtouch3dinputhandler_p.h"
+#include "q3dcamera_p.h"
+#include <QTimer>
+#include <qmath.h>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+const qreal maxTapAndHoldJitter = 20;
+const int maxPinchJitter = 10;
+#if defined (Q_OS_ANDROID)
+const int maxSelectionJitter = 10;
+#else
+const int maxSelectionJitter = 5;
+#endif
+const int tapAndHoldTime = 250;
+const float rotationSpeed = 200.0f;
+const int minZoomLevel = 10;
+const int maxZoomLevel = 500;
+
+/*!
+ * \class QTouch3DInputHandler
+ * \inmodule QtDataVisualization
+ * \brief Basic touch display based input handler.
+ * \since 1.0.0
+ *
+ * QTouch3DInputHandler is the basic input handler for touch screen devices.
+ *
+ * Default touch input handler has the following functionalty:
+ * \table
+ * \header
+ * \li Gesture \li Action
+ * \row
+ * \li Touch-And-Move \li Rotate graph within limits set for Q3DCamera
+ * \row
+ * \li Tap \li Select item under pointer or remove selection if none
+ * \row
+ * \li Tap-And-Hold \li Select item under pointer or remove selection if none
+ * \row
+ * \li Pinch \li Zoom in/out within default range (10...500%)
+ * \row
+ * \li Tap on secondary view \li Return to primary view when in slice mode
+ * \note Slice mode is available in Q3DBars and Q3DSurface only
+ * \endtable
+ */
+
+/*!
+ * Constructs the basic touch display input handler. An optional \a parent parameter can be given
+ * and is then passed to QObject constructor.
+ */
+QTouch3DInputHandler::QTouch3DInputHandler(QObject *parent)
+ : Q3DInputHandler(parent),
+ d_ptr(new QTouch3DInputHandlerPrivate(this))
+{
+}
+
+/*!
+ * Destroys the input handler.
+ */
+QTouch3DInputHandler::~QTouch3DInputHandler()
+{
+}
+
+/*!
+ * Override this to change handling of touch events.
+ * Touch event is given in the \a event.
+ */
+void QTouch3DInputHandler::touchEvent(QTouchEvent *event)
+{
+ QList<QTouchEvent::TouchPoint> points;
+ points = event->touchPoints();
+
+ if (!scene()->isSlicingActive() && points.count() == 2) {
+ d_ptr->m_holdTimer->stop();
+ QPointF distance = points.at(0).pos() - points.at(1).pos();
+ d_ptr->handlePinchZoom(distance.manhattanLength());
+ } else if (points.count() == 1) {
+ QPointF pointerPos = points.at(0).pos();
+ if (event->type() == QEvent::TouchBegin) {
+ if (scene()->isSlicingActive()) {
+ if (scene()->isPointInPrimarySubView(pointerPos.toPoint()))
+ setInputState(QDataVis::InputStateOnOverview);
+ else if (scene()->isPointInSecondarySubView(pointerPos.toPoint()))
+ setInputState(QDataVis::InputStateOnSlice);
+ else
+ setInputState(QDataVis::InputStateNone);
+ } else {
+ // Handle possible tap-and-hold selection
+ d_ptr->m_startHoldPos = pointerPos;
+ d_ptr->m_touchHoldPos = d_ptr->m_startHoldPos;
+ d_ptr->m_holdTimer->start();
+ // Start rotating
+ setInputState(QDataVis::InputStateRotating);
+ setInputPosition(pointerPos.toPoint());
+ }
+ } else if (event->type() == QEvent::TouchEnd) {
+ d_ptr->m_holdTimer->stop();
+ // Handle possible selection
+ d_ptr->handleSelection(pointerPos);
+ } else if (event->type() == QEvent::TouchUpdate) {
+ if (!scene()->isSlicingActive()) {
+ d_ptr->m_touchHoldPos = pointerPos;
+ // Handle rotation
+ d_ptr->handleRotation(pointerPos);
+ }
+ }
+ } else {
+ d_ptr->m_holdTimer->stop();
+ }
+}
+
+QTouch3DInputHandlerPrivate::QTouch3DInputHandlerPrivate(QTouch3DInputHandler *q)
+ : q_ptr(q),
+ m_holdTimer(0)
+{
+ m_holdTimer = new QTimer();
+ m_holdTimer->setSingleShot(true);
+ m_holdTimer->setInterval(tapAndHoldTime);
+ connect(m_holdTimer, &QTimer::timeout, this, &QTouch3DInputHandlerPrivate::handleTapAndHold);
+}
+
+QTouch3DInputHandlerPrivate::~QTouch3DInputHandlerPrivate()
+{
+ m_holdTimer->stop();
+ delete m_holdTimer;
+}
+
+void QTouch3DInputHandlerPrivate::handlePinchZoom(qreal distance)
+{
+ int newDistance = distance;
+ int prevDist = q_ptr->prevDistance();
+ if (prevDist > 0 && qAbs(prevDist - newDistance) < maxPinchJitter)
+ return;
+ q_ptr->setInputState(QDataVis::InputStateOnPinch);
+ Q3DCamera *camera = q_ptr->scene()->activeCamera();
+ int zoomLevel = camera->zoomLevel();
+ qreal zoomRate = qSqrt(qSqrt(zoomLevel));
+ if (newDistance > prevDist)
+ zoomLevel += zoomRate;
+ else
+ zoomLevel -= zoomRate;
+ if (zoomLevel > maxZoomLevel)
+ zoomLevel = maxZoomLevel;
+ else if (zoomLevel < minZoomLevel)
+ zoomLevel = minZoomLevel;
+ camera->setZoomLevel(zoomLevel);
+ q_ptr->setPrevDistance(newDistance);
+}
+
+void QTouch3DInputHandlerPrivate::handleTapAndHold()
+{
+ QPointF distance = m_startHoldPos - m_touchHoldPos;
+ if (distance.manhattanLength() < maxTapAndHoldJitter) {
+ q_ptr->setInputPosition(m_touchHoldPos.toPoint());
+ q_ptr->setInputState(QDataVis::InputStateOnScene);
+ }
+}
+
+void QTouch3DInputHandlerPrivate::handleSelection(const QPointF &position)
+{
+ QPointF distance = m_startHoldPos - position;
+ if (distance.manhattanLength() < maxSelectionJitter)
+ q_ptr->setInputState(QDataVis::InputStateOnScene);
+ else
+ q_ptr->setInputState(QDataVis::InputStateNone);
+ q_ptr->setPreviousInputPos(position.toPoint());
+}
+
+void QTouch3DInputHandlerPrivate::handleRotation(const QPointF &position)
+{
+ if (QDataVis::InputStateRotating == q_ptr->inputState()) {
+ Q3DScene *scene = q_ptr->scene();
+ Q3DCamera *camera = scene->activeCamera();
+ float xRotation = camera->xRotation();
+ float yRotation = camera->yRotation();
+ QPointF inputPos = q_ptr->inputPosition();
+ float mouseMoveX = float(inputPos.x() - position.x())
+ / (scene->viewport().width() / rotationSpeed);
+ float mouseMoveY = float(inputPos.y() - position.y())
+ / (scene->viewport().height() / rotationSpeed);
+ xRotation -= mouseMoveX;
+ yRotation -= mouseMoveY;
+ camera->setXRotation(xRotation);
+ camera->setYRotation(yRotation);
+ camera->d_ptr->updateViewMatrix(1.0f);
+
+ q_ptr->setPreviousInputPos(inputPos.toPoint());
+ q_ptr->setInputPosition(position.toPoint());
+ }
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualization/input/qtouch3dinputhandler.h b/src/datavisualization/input/qtouch3dinputhandler.h
new file mode 100644
index 00000000..1c366926
--- /dev/null
+++ b/src/datavisualization/input/qtouch3dinputhandler.h
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 QTOUCH3DINPUTHANDLER_H
+#define QTOUCH3DINPUTHANDLER_H
+
+#include <QtDataVisualization/q3dinputhandler.h>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class QTouch3DInputHandlerPrivate;
+
+class QT_DATAVISUALIZATION_EXPORT QTouch3DInputHandler : public Q3DInputHandler
+{
+ Q_OBJECT
+
+public:
+ explicit QTouch3DInputHandler(QObject *parent = 0);
+ virtual ~QTouch3DInputHandler();
+
+ // Input event listeners
+ virtual void touchEvent(QTouchEvent *event);
+
+private:
+ Q_DISABLE_COPY(QTouch3DInputHandler)
+
+ QScopedPointer<QTouch3DInputHandlerPrivate> d_ptr;
+};
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
+#endif // QTOUCH3DINPUTHANDLER_H
diff --git a/src/datavisualization/input/qtouch3dinputhandler_p.h b/src/datavisualization/input/qtouch3dinputhandler_p.h
new file mode 100644
index 00000000..1c5b81c7
--- /dev/null
+++ b/src/datavisualization/input/qtouch3dinputhandler_p.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 QTOUCH3DINPUTHANDLER_P_H
+#define QTOUCH3DINPUTHANDLER_P_H
+
+#include "qtouch3dinputhandler.h"
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class QAbstract3DInputHandler;
+
+class QTouch3DInputHandlerPrivate : public QObject
+{
+ Q_OBJECT
+
+public:
+ QTouch3DInputHandlerPrivate(QTouch3DInputHandler *q);
+ ~QTouch3DInputHandlerPrivate();
+
+ void handlePinchZoom(qreal distance);
+ void handleTapAndHold();
+ void handleSelection(const QPointF &position);
+ void handleRotation(const QPointF &position);
+
+public:
+ QTouch3DInputHandler *q_ptr;
+ QTimer *m_holdTimer;
+ QPointF m_startHoldPos;
+ QPointF m_touchHoldPos;
+};
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
+#endif // QTOUCH3DINPUTHANDLER_H
diff --git a/src/datavis3d/utils/abstractobjecthelper.cpp b/src/datavisualization/utils/abstractobjecthelper.cpp
index d54a50c7..d47f2fe6 100644
--- a/src/datavis3d/utils/abstractobjecthelper.cpp
+++ b/src/datavisualization/utils/abstractobjecthelper.cpp
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,7 +20,7 @@
#include <QDebug>
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
AbstractObjectHelper::AbstractObjectHelper()
: m_vertexbuffer(0),
@@ -78,4 +78,4 @@ GLuint AbstractObjectHelper::indicesType()
return m_indicesType;
}
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavis3d/utils/abstractobjecthelper_p.h b/src/datavisualization/utils/abstractobjecthelper_p.h
index a4d701fa..a6de6941 100644
--- a/src/datavis3d/utils/abstractobjecthelper_p.h
+++ b/src/datavisualization/utils/abstractobjecthelper_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -29,10 +29,10 @@
#ifndef ABSTRACTOBJECTHELPER_H
#define ABSTRACTOBJECTHELPER_H
-#include "datavis3dglobal_p.h"
+#include "datavisualizationglobal_p.h"
#include <QOpenGLFunctions>
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
class AbstractObjectHelper: protected QOpenGLFunctions
{
@@ -60,6 +60,6 @@ public:
GLuint m_indicesType;
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif // ABSTRACTOBJECTHELPER_H
diff --git a/src/datavis3d/utils/camerahelper.cpp b/src/datavisualization/utils/camerahelper.cpp
index 5ae91adb..29ed4d57 100644
--- a/src/datavis3d/utils/camerahelper.cpp
+++ b/src/datavisualization/utils/camerahelper.cpp
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -22,7 +22,7 @@
#include <QMatrix4x4>
#include <QVector3D>
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
CameraHelper::CameraHelper(QObject *parent) :
QObject(parent),
@@ -158,123 +158,123 @@ QPointF CameraHelper::getCameraRotations()
void CameraHelper::setCameraPreset(QDataVis::CameraPreset preset)
{
switch (preset) {
- case QDataVis::PresetFrontLow: {
- qDebug("PresetFrontLow");
+ case QDataVis::CameraPresetFrontLow: {
+ qDebug("CameraPresetFrontLow");
CameraHelper::setCameraRotation(QPointF(0.0f, 0.0f));
break;
}
- case QDataVis::PresetFront: {
- qDebug("PresetFront");
+ case QDataVis::CameraPresetFront: {
+ qDebug("CameraPresetFront");
CameraHelper::setCameraRotation(QPointF(0.0f, 22.5f));
break;
}
- case QDataVis::PresetFrontHigh: {
- qDebug("PresetFrontHigh");
+ case QDataVis::CameraPresetFrontHigh: {
+ qDebug("CameraPresetFrontHigh");
CameraHelper::setCameraRotation(QPointF(0.0f, 45.0f));
break;
}
- case QDataVis::PresetLeftLow: {
- qDebug("PresetLeftLow");
+ case QDataVis::CameraPresetLeftLow: {
+ qDebug("CameraPresetLeftLow");
CameraHelper::setCameraRotation(QPointF(90.0f, 0.0f));
break;
}
- case QDataVis::PresetLeft: {
- qDebug("PresetLeft");
+ case QDataVis::CameraPresetLeft: {
+ qDebug("CameraPresetLeft");
CameraHelper::setCameraRotation(QPointF(90.0f, 22.5f));
break;
}
- case QDataVis::PresetLeftHigh: {
- qDebug("PresetLeftHigh");
+ case QDataVis::CameraPresetLeftHigh: {
+ qDebug("CameraPresetLeftHigh");
CameraHelper::setCameraRotation(QPointF(90.0f, 45.0f));
break;
}
- case QDataVis::PresetRightLow: {
- qDebug("PresetRightLow");
+ case QDataVis::CameraPresetRightLow: {
+ qDebug("CameraPresetRightLow");
CameraHelper::setCameraRotation(QPointF(-90.0f, 0.0f));
break;
}
- case QDataVis::PresetRight: {
- qDebug("PresetRight");
+ case QDataVis::CameraPresetRight: {
+ qDebug("CameraPresetRight");
CameraHelper::setCameraRotation(QPointF(-90.0f, 22.5f));
break;
}
- case QDataVis::PresetRightHigh: {
- qDebug("PresetRightHigh");
+ case QDataVis::CameraPresetRightHigh: {
+ qDebug("CameraPresetRightHigh");
CameraHelper::setCameraRotation(QPointF(-90.0f, 45.0f));
break;
}
- case QDataVis::PresetBehindLow: {
- qDebug("PresetBehindLow");
+ case QDataVis::CameraPresetBehindLow: {
+ qDebug("CameraPresetBehindLow");
CameraHelper::setCameraRotation(QPointF(180.0f, 0.0f));
break;
}
- case QDataVis::PresetBehind: {
- qDebug("PresetBehind");
+ case QDataVis::CameraPresetBehind: {
+ qDebug("CameraPresetBehind");
CameraHelper::setCameraRotation(QPointF(180.0f, 22.5f));
break;
}
- case QDataVis::PresetBehindHigh: {
- qDebug("PresetBehindHigh");
+ case QDataVis::CameraPresetBehindHigh: {
+ qDebug("CameraPresetBehindHigh");
CameraHelper::setCameraRotation(QPointF(180.0f, 45.0f));
break;
}
- case QDataVis::PresetIsometricLeft: {
- qDebug("PresetIsometricLeft");
+ case QDataVis::CameraPresetIsometricLeft: {
+ qDebug("CameraPresetIsometricLeft");
CameraHelper::setCameraRotation(QPointF(45.0f, 22.5f));
break;
}
- case QDataVis::PresetIsometricLeftHigh: {
- qDebug("PresetIsometricLeftHigh");
+ case QDataVis::CameraPresetIsometricLeftHigh: {
+ qDebug("CameraPresetIsometricLeftHigh");
CameraHelper::setCameraRotation(QPointF(45.0f, 45.0f));
break;
}
- case QDataVis::PresetIsometricRight: {
- qDebug("PresetIsometricRight");
+ case QDataVis::CameraPresetIsometricRight: {
+ qDebug("CameraPresetIsometricRight");
CameraHelper::setCameraRotation(QPointF(-45.0f, 22.5f));
break;
}
- case QDataVis::PresetIsometricRightHigh: {
- qDebug("PresetIsometricRightHigh");
+ case QDataVis::CameraPresetIsometricRightHigh: {
+ qDebug("CameraPresetIsometricRightHigh");
CameraHelper::setCameraRotation(QPointF(-45.0f, 45.0f));
break;
}
- case QDataVis::PresetDirectlyAbove: {
- qDebug("PresetDirectlyAbove");
+ case QDataVis::CameraPresetDirectlyAbove: {
+ qDebug("CameraPresetDirectlyAbove");
CameraHelper::setCameraRotation(QPointF(0.0f, 90.0f));
break;
}
- case QDataVis::PresetDirectlyAboveCW45: {
- qDebug("PresetDirectlyAboveCW45");
+ case QDataVis::CameraPresetDirectlyAboveCW45: {
+ qDebug("CameraPresetDirectlyAboveCW45");
CameraHelper::setCameraRotation(QPointF(-45.0f, 90.0f));
break;
}
- case QDataVis::PresetDirectlyAboveCCW45: {
- qDebug("PresetDirectlyAboveCCW45");
+ case QDataVis::CameraPresetDirectlyAboveCCW45: {
+ qDebug("CameraPresetDirectlyAboveCCW45");
CameraHelper::setCameraRotation(QPointF(45.0f, 90.0f));
break;
}
- case QDataVis::PresetFrontBelow: {
- qDebug("PresetFrontBelow");
+ case QDataVis::CameraPresetFrontBelow: {
+ qDebug("CameraPresetFrontBelow");
CameraHelper::setCameraRotation(QPointF(0.0f, -45.0f));
break;
}
- case QDataVis::PresetLeftBelow: {
- qDebug("PresetLeftBelow");
+ case QDataVis::CameraPresetLeftBelow: {
+ qDebug("CameraPresetLeftBelow");
CameraHelper::setCameraRotation(QPointF(90.0f, -45.0f));
break;
}
- case QDataVis::PresetRightBelow: {
- qDebug("PresetRightBelow");
+ case QDataVis::CameraPresetRightBelow: {
+ qDebug("CameraPresetRightBelow");
CameraHelper::setCameraRotation(QPointF(-90.0f, -45.0f));
break;
}
- case QDataVis::PresetBehindBelow: {
- qDebug("PresetBehindBelow");
+ case QDataVis::CameraPresetBehindBelow: {
+ qDebug("CameraPresetBehindBelow");
CameraHelper::setCameraRotation(QPointF(180.0f, -45.0f));
break;
}
- case QDataVis::PresetDirectlyBelow: {
- qDebug("PresetDirectlyBelow");
+ case QDataVis::CameraPresetDirectlyBelow: {
+ qDebug("CameraPresetDirectlyBelow");
CameraHelper::setCameraRotation(QPointF(0.0f, -90.0f));
break;
}
@@ -283,4 +283,4 @@ void CameraHelper::setCameraPreset(QDataVis::CameraPreset preset)
}
}
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavis3d/utils/camerahelper_p.h b/src/datavisualization/utils/camerahelper_p.h
index 3b8c0c9c..1ef4d257 100644
--- a/src/datavis3d/utils/camerahelper_p.h
+++ b/src/datavisualization/utils/camerahelper_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -29,7 +29,7 @@
#ifndef CAMERAPOSITIONER_P_H
#define CAMERAPOSITIONER_P_H
-#include "datavis3dglobal_p.h"
+#include "datavisualizationglobal_p.h"
#include "q3dbars.h"
#include <QObject>
@@ -38,7 +38,7 @@ class QVector3D;
class QPoint;
class QPointF;
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
class CameraHelper : public QObject
{
@@ -85,6 +85,6 @@ public:
void setCameraPreset(QDataVis::CameraPreset preset);
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif
diff --git a/src/datavis3d/utils/meshloader.cpp b/src/datavisualization/utils/meshloader.cpp
index ee2f12a6..119cde3a 100644
--- a/src/datavis3d/utils/meshloader.cpp
+++ b/src/datavisualization/utils/meshloader.cpp
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -26,7 +26,7 @@
#include <QDebug>
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
QString slashTag = QStringLiteral("/");
@@ -122,4 +122,4 @@ bool MeshLoader::loadOBJ(const QString &path,
return true;
}
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavis3d/utils/meshloader_p.h b/src/datavisualization/utils/meshloader_p.h
index acbfb037..48551fff 100644
--- a/src/datavis3d/utils/meshloader_p.h
+++ b/src/datavisualization/utils/meshloader_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -29,12 +29,12 @@
#ifndef MESHLOADER_P_H
#define MESHLOADER_P_H
-#include "datavis3dglobal_p.h"
+#include "datavisualizationglobal_p.h"
class QVector2D;
class QVector3D;
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
class MeshLoader
{
@@ -46,6 +46,6 @@ class MeshLoader
// TODO: add loaders for other formats?
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif
diff --git a/src/datavis3d/utils/objecthelper.cpp b/src/datavisualization/utils/objecthelper.cpp
index cbd1e960..9660c215 100644
--- a/src/datavis3d/utils/objecthelper.cpp
+++ b/src/datavisualization/utils/objecthelper.cpp
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -23,7 +23,7 @@
#include <QDebug>
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
ObjectHelper::ObjectHelper(const QString &objectFile)
: m_objectFile(objectFile)
@@ -98,4 +98,4 @@ void ObjectHelper::load()
m_meshDataLoaded = true;
}
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavis3d/utils/objecthelper_p.h b/src/datavisualization/utils/objecthelper_p.h
index ba9fc2f3..9d643fdd 100644
--- a/src/datavis3d/utils/objecthelper_p.h
+++ b/src/datavisualization/utils/objecthelper_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -29,11 +29,11 @@
#ifndef OBJECTHELPER_P_H
#define OBJECTHELPER_P_H
-#include "datavis3dglobal_p.h"
+#include "datavisualizationglobal_p.h"
#include "abstractobjecthelper_p.h"
#include <QOpenGLFunctions>
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
class ObjectHelper : public AbstractObjectHelper
{
@@ -49,6 +49,6 @@ private:
QString m_objectFile;
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif
diff --git a/src/datavis3d/utils/shaderhelper.cpp b/src/datavisualization/utils/shaderhelper.cpp
index c8716910..7df1736c 100644
--- a/src/datavis3d/utils/shaderhelper.cpp
+++ b/src/datavisualization/utils/shaderhelper.cpp
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,7 +20,7 @@
#include <QOpenGLShader>
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
ShaderHelper::ShaderHelper(QObject *parent,
const QString &vertexShader,
@@ -86,6 +86,18 @@ void ShaderHelper::initialize()
m_initialized = true;
}
+bool ShaderHelper::testCompile()
+{
+ if (m_program)
+ delete m_program;
+ m_program = new QOpenGLShaderProgram(m_caller);
+ if (!m_program->addShaderFromSourceFile(QOpenGLShader::Vertex, m_vertexShaderFile))
+ return false;
+ if (!m_program->addShaderFromSourceFile(QOpenGLShader::Fragment, m_fragmentShaderFile))
+ return false;
+ return true;
+}
+
void ShaderHelper::bind()
{
m_program->bind();
@@ -226,4 +238,4 @@ GLuint ShaderHelper::normalAtt()
return m_normalAttr;
}
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavis3d/utils/shaderhelper_p.h b/src/datavisualization/utils/shaderhelper_p.h
index 97fcf8a0..73e5b9ee 100644
--- a/src/datavis3d/utils/shaderhelper_p.h
+++ b/src/datavisualization/utils/shaderhelper_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -29,12 +29,12 @@
#ifndef SHADERHELPER_P_H
#define SHADERHELPER_P_H
-#include "datavis3dglobal_p.h"
+#include "datavisualizationglobal_p.h"
#include <QOpenGLFunctions>
class QOpenGLShaderProgram;
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
class ShaderHelper
{
@@ -50,6 +50,7 @@ class ShaderHelper
void setTextures(const QString &texture, const QString &depthTexture);
void initialize();
+ bool testCompile();
void bind();
void release();
void setUniformValue(GLuint uniform, const QVector3D &value);
@@ -105,6 +106,6 @@ class ShaderHelper
GLboolean m_initialized;
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif
diff --git a/src/datavisualization/utils/surfaceobject.cpp b/src/datavisualization/utils/surfaceobject.cpp
new file mode 100644
index 00000000..f78fcec3
--- /dev/null
+++ b/src/datavisualization/utils/surfaceobject.cpp
@@ -0,0 +1,346 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+SurfaceObject::SurfaceObject()
+{
+ m_indicesType = GL_UNSIGNED_INT;
+ initializeOpenGLFunctions();
+ glGenBuffers(1, &m_vertexbuffer);
+ glGenBuffers(1, &m_normalbuffer);
+ glGenBuffers(1, &m_uvbuffer);
+ glGenBuffers(1, &m_elementbuffer);
+ glGenBuffers(1, &m_gridElementbuffer);
+}
+
+SurfaceObject::~SurfaceObject()
+{
+ glDeleteBuffers(1, &m_gridElementbuffer);
+}
+
+void SurfaceObject::setUpSmoothData(const QSurfaceDataArray &dataArray, const QRect &space,
+ GLfloat yRange, GLfloat yMin, bool changeGeometry)
+{
+ m_columns = space.width();
+ m_rows = space.height();
+ int totalSize = m_rows * m_columns;
+ GLfloat xMin = dataArray.at(0)->at(0).x();
+ GLfloat zMin = dataArray.at(0)->at(0).z();
+ GLfloat xNormalizer = (dataArray.at(0)->last().x() - xMin) / 2.0f;
+ GLfloat yNormalizer = yRange / 2.0f;
+ GLfloat zNormalizer = (dataArray.last()->at(0).z() - zMin) / -2.0f;
+ GLfloat uvX = 1.0 / GLfloat(m_columns - 1);
+ GLfloat uvY = 1.0 / GLfloat(m_rows - 1);
+
+ m_surfaceType = SurfaceSmooth;
+
+ // Create/populate vertice table
+ if (changeGeometry)
+ m_vertices.resize(totalSize);
+
+ QVector<QVector2D> uvs;
+ if (changeGeometry)
+ uvs.resize(totalSize);
+ int totalIndex = 0;
+ for (int i = 0; i < m_rows; i++) {
+ const QSurfaceDataRow &p = *dataArray.at(i);
+ for (int j = 0; j < m_columns; j++) {
+ const QSurfaceDataItem &data = p.at(j);
+ float normalizedX = ((data.x() - xMin) / xNormalizer);
+ float normalizedY = ((data.y() - yMin) / yNormalizer);
+ float normalizedZ = ((data.z() - zMin) / zNormalizer);
+ m_vertices[totalIndex] = QVector3D(normalizedX - 1.0f, normalizedY - 1.0f, normalizedZ + 1.0f);
+ if (changeGeometry)
+ uvs[totalIndex] = QVector2D(GLfloat(j) * uvX, GLfloat(i) * uvY);
+ totalIndex++;
+ }
+ }
+
+ // Create normals
+ int rowLimit = m_rows - 1;
+ int colLimit = m_columns - 1;
+ int rowColLimit = rowLimit * m_columns;
+ int totalLimit = totalSize - 1;
+ if (changeGeometry)
+ m_normals.resize(totalSize);
+
+ totalIndex = 0;
+ for (int row = 0; row < rowColLimit; row += m_columns) {
+ for (int j = 0; j < colLimit; j++) {
+ m_normals[totalIndex++] = normal(m_vertices.at(row + j),
+ m_vertices.at(row + j + 1),
+ m_vertices.at(row + m_columns + j));
+ }
+ int p = row + colLimit;
+ m_normals[totalIndex++] = normal(m_vertices.at(p),
+ m_vertices.at(p + m_columns),
+ m_vertices.at(p - 1));
+ }
+ for (int j = rowColLimit; j < totalLimit; j++) {
+ m_normals[totalIndex++] = normal(m_vertices.at(j),
+ m_vertices.at(j - m_columns),
+ m_vertices.at(j + 1));
+ }
+ int p = m_rows * colLimit;
+ m_normals[totalIndex++] = normal(m_vertices.at(p),
+ m_vertices.at(p - 1),
+ m_vertices.at(p - m_columns - 1));
+
+ // Create indices table
+ GLint *indices = 0;
+ if (changeGeometry) {
+ m_indexCount = 6 * colLimit * rowLimit;
+ indices = new GLint[m_indexCount];
+ p = 0;
+ for (int row = 0; row < rowLimit * m_columns; row += m_columns) {
+ for (int j = 0; j < colLimit; j++) {
+ // Left triangle
+ indices[p++] = row + j + 1;
+ indices[p++] = row + m_columns + j;
+ indices[p++] = row + j;
+
+ // Right triangle
+ indices[p++] = row + m_columns + j + 1;
+ indices[p++] = row + m_columns + j;
+ indices[p++] = row + j + 1;
+ }
+ }
+ }
+
+ // Create line element indices
+ GLint *gridIndices = 0;
+ if (changeGeometry) {
+ m_gridIndexCount = 2 * m_columns * rowLimit + 2 * m_rows * colLimit;
+ gridIndices = new GLint[m_gridIndexCount];
+ p = 0;
+ for (int i = 0, row = 0; i < m_rows; i++, row += m_columns) {
+ for (int j = 0; j < colLimit; j++) {
+ gridIndices[p++] = row + j;
+ gridIndices[p++] = row + j + 1;
+ }
+ }
+ for (int i = 0, row = 0; i < rowLimit; i++, row += m_columns) {
+ for (int j = 0; j < m_columns; j++) {
+ gridIndices[p++] = row + j;
+ gridIndices[p++] = row + j + m_columns;
+ }
+ }
+ }
+
+ createBuffers(m_vertices, uvs, m_normals, indices, gridIndices, changeGeometry);
+
+ delete[] indices;
+ delete[] gridIndices;
+}
+
+
+void SurfaceObject::setUpData(const QSurfaceDataArray &dataArray, const QRect &space,
+ GLfloat yRange, GLfloat yMin, bool changeGeometry)
+{
+ m_columns = space.width();
+ m_rows = space.height();
+ int totalSize = m_rows * m_columns * 2;
+ GLfloat xMin = dataArray.at(0)->at(0).x();
+ GLfloat zMin = dataArray.at(0)->at(0).z();
+ GLfloat xNormalizer = (dataArray.at(0)->last().x() - xMin) / 2.0f;
+ GLfloat yNormalizer = yRange / 2.0f;
+ GLfloat zNormalizer = (dataArray.last()->at(0).z() - zMin) / -2.0f;
+ GLfloat uvX = 1.0 / GLfloat(m_columns - 1);
+ GLfloat uvY = 1.0 / GLfloat(m_rows - 1);
+
+ m_surfaceType = SurfaceFlat;
+
+ // Create vertice table
+ if (changeGeometry)
+ m_vertices.resize(totalSize);
+
+ QVector<QVector2D> uvs;
+ if (changeGeometry)
+ uvs.resize(totalSize);
+
+ int totalIndex = 0;
+ int rowLimit = m_rows - 1;
+ int colLimit = m_columns - 1;
+ int doubleColumns = m_columns * 2 - 2;
+ int rowColLimit = rowLimit * doubleColumns;
+
+ for (int i = 0; i < m_rows; i++) {
+ const QSurfaceDataRow &row = *dataArray.at(i);
+ for (int j = 0; j < m_columns; j++) {
+ const QSurfaceDataItem &data = row.at(j);
+ float normalizedX = ((data.x() - xMin) / xNormalizer);
+ float normalizedY = ((data.y() - yMin) / yNormalizer);
+ float normalizedZ = ((data.z() - zMin) / zNormalizer);
+ m_vertices[totalIndex] = QVector3D(normalizedX - 1.0f, normalizedY - 1.0f, normalizedZ + 1.0f);
+ if (changeGeometry)
+ uvs[totalIndex] = QVector2D(GLfloat(j) * uvX, GLfloat(i) * uvY);
+
+ totalIndex++;
+
+ if (j > 0 && j < colLimit) {
+ m_vertices[totalIndex] = m_vertices[totalIndex - 1];
+ if (changeGeometry)
+ uvs[totalIndex] = uvs[totalIndex - 1];
+ totalIndex++;
+ }
+ }
+ }
+
+ // Create normals & indices table
+ GLint *indices = 0;
+ int p = 0;
+ if (changeGeometry) {
+ int normalCount = 2 * colLimit * rowLimit;
+ m_indexCount = 3 * normalCount;
+ indices = new GLint[m_indexCount];
+ m_normals.resize(normalCount);
+ }
+
+ totalIndex = 0;
+ for (int row = 0, upperRow = doubleColumns;
+ row < rowColLimit;
+ row += doubleColumns, upperRow += doubleColumns) {
+ for (int j = 0; j < doubleColumns; j += 2) {
+ // Normal for the left triangle
+ m_normals[totalIndex++] = normal(m_vertices.at(row + j),
+ m_vertices.at(row + j + 1),
+ m_vertices.at(upperRow + j));
+
+ // Normal for the right triangle
+ m_normals[totalIndex++] = normal(m_vertices.at(row + j + 1),
+ m_vertices.at(upperRow + j + 1),
+ m_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
+ GLint *gridIndices = 0;
+ if (changeGeometry) {
+ m_gridIndexCount = 2 * m_columns * rowLimit + 2 * m_rows * colLimit;
+ gridIndices = new GLint[m_gridIndexCount];
+ p = 0;
+ int fullRowLimit = m_rows * doubleColumns;
+ for (int row = 0; row < fullRowLimit; row += doubleColumns) {
+ for (int j = 0; j < doubleColumns; j += 2) {
+ gridIndices[p++] = row + j;
+ gridIndices[p++] = row + j + 1;
+
+ if (row < rowColLimit) {
+ gridIndices[p++] = row + j;
+ gridIndices[p++] = row + j + doubleColumns;
+ }
+ }
+ }
+ for (int i = doubleColumns - 1; i < rowColLimit; i += doubleColumns) {
+ gridIndices[p++] = i;
+ gridIndices[p++] = i + doubleColumns;
+ }
+ }
+
+ createBuffers(m_vertices, uvs, m_normals, indices, gridIndices, changeGeometry);
+
+ delete[] indices;
+ 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)
+{
+ // Move to buffers
+ glBindBuffer(GL_ARRAY_BUFFER, m_vertexbuffer);
+ glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(QVector3D),
+ &vertices.at(0), GL_DYNAMIC_DRAW);
+
+ glBindBuffer(GL_ARRAY_BUFFER, m_normalbuffer);
+ glBufferData(GL_ARRAY_BUFFER, normals.size() * sizeof(QVector3D),
+ &normals.at(0), GL_DYNAMIC_DRAW);
+
+ if (changeGeometry) {
+ if (uvs.size()) {
+ glBindBuffer(GL_ARRAY_BUFFER, m_uvbuffer);
+ glBufferData(GL_ARRAY_BUFFER, uvs.size() * sizeof(QVector2D),
+ &uvs.at(0), GL_STATIC_DRAW);
+ }
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_elementbuffer);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_indexCount * sizeof(GLint),
+ indices, GL_STATIC_DRAW);
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_gridElementbuffer);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_gridIndexCount * sizeof(GLint),
+ gridIndices, GL_STATIC_DRAW);
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ }
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+
+ m_meshDataLoaded = true;
+}
+
+GLuint SurfaceObject::gridElementBuf()
+{
+ if (!m_meshDataLoaded)
+ qFatal("No loaded object");
+ return m_gridElementbuffer;
+}
+
+GLuint SurfaceObject::gridIndexCount()
+{
+ return m_gridIndexCount;
+}
+
+QVector3D SurfaceObject::vertexAt(int column, int row)
+{
+ int pos = 0;
+ if (m_surfaceType == SurfaceFlat)
+ pos = row * (m_columns * 2 - 2) + column * 2 - (column > 0);
+ else
+ pos = row * m_columns + column;
+ return m_vertices.at(pos);
+}
+
+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_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavis3d/utils/surfaceobject_p.h b/src/datavisualization/utils/surfaceobject_p.h
index 729757c4..4f30f7c0 100644
--- a/src/datavis3d/utils/surfaceobject_p.h
+++ b/src/datavisualization/utils/surfaceobject_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -29,11 +29,14 @@
#ifndef SURFACEOBJECT_P_H
#define SURFACEOBJECT_P_H
-#include "datavis3dglobal_p.h"
+#include "datavisualizationglobal_p.h"
#include "abstractobjecthelper_p.h"
+#include "qsurfacedataproxy.h"
+
#include <QOpenGLFunctions>
+#include <QRect>
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
class SurfaceObject : public AbstractObjectHelper
{
@@ -41,10 +44,13 @@ 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);
+ void setUpData(const QSurfaceDataArray &dataArray, const QRect &space, GLfloat yRange,
+ GLfloat yMin, bool changeGeometry);
+ void setUpSmoothData(const QSurfaceDataArray &dataArray, const QRect &space, GLfloat yRange,
+ GLfloat yMin, bool changeGeometry);
GLuint gridElementBuf();
GLuint gridIndexCount();
+ QVector3D vertexAt(int column, int row);
private:
QVector3D normal(const QVector3D &a, const QVector3D &b, const QVector3D &c);
@@ -53,13 +59,18 @@ private:
const GLint *gridIndices, bool changeGeometry);
private:
- QList<qreal> m_series;
- int m_dataWidth;
- int m_dataDepth;
- GLfloat m_yRange;
+ enum SurfaceType {
+ SurfaceSmooth,
+ SurfaceFlat
+ };
+ int m_surfaceType;
+ int m_columns;
+ int m_rows;
GLuint m_gridElementbuffer;
GLuint m_gridIndexCount;
+ QVector<QVector3D> m_vertices;
+ QVector<QVector3D> m_normals;
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif // SURFACEOBJECT_P_H
diff --git a/src/datavis3d/utils/texturehelper.cpp b/src/datavisualization/utils/texturehelper.cpp
index 1773c0f8..25fe17ac 100644
--- a/src/datavis3d/utils/texturehelper.cpp
+++ b/src/datavisualization/utils/texturehelper.cpp
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -23,7 +23,7 @@
#include <QDebug>
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
TextureHelper::TextureHelper()
{
@@ -34,66 +34,49 @@ TextureHelper::~TextureHelper()
{
}
-GLuint TextureHelper::create2DTexture(const QImage &image, bool useTrilinearFiltering, bool convert)
+GLuint TextureHelper::create2DTexture(const QImage &image, bool useTrilinearFiltering,
+ bool convert, bool smoothScale)
{
if (image.isNull())
return 0;
- QImage texImage;
+ QImage texImage = image;
#if defined(Q_OS_ANDROID)
GLuint temp;
//qDebug() << "old size" << image.size();
GLuint imageWidth = Utils::getNearestPowerOfTwo(image.width(), temp);
- //qDebug() << "new width" << imageWidth << "padding" << temp;
GLuint imageHeight = Utils::getNearestPowerOfTwo(image.height(), temp);
- //qDebug() << "new height" << imageHeight << "padding" << temp;
- texImage = image.scaled(imageWidth, imageHeight, Qt::IgnoreAspectRatio,
- Qt::SmoothTransformation);
+ if (smoothScale) {
+ texImage = image.scaled(imageWidth, imageHeight, Qt::IgnoreAspectRatio,
+ Qt::SmoothTransformation);
+ } else {
+ texImage = image.scaled(imageWidth, imageHeight, Qt::IgnoreAspectRatio);
+ }
//qDebug() << "new size" << texImage.size();
-#else
- texImage = image;
#endif
GLuint textureId;
glGenTextures(1, &textureId);
glBindTexture(GL_TEXTURE_2D, textureId);
- if (convert) {
- QImage glTexture = convertToGLFormat(texImage);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, glTexture.width(), glTexture.height(),
- 0, GL_RGBA, GL_UNSIGNED_BYTE, glTexture.bits());
- } else {
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texImage.width(), texImage.height(),
- 0, GL_RGBA, GL_UNSIGNED_BYTE, texImage.bits());
- }
- if (useTrilinearFiltering) {
+ if (convert)
+ texImage = convertToGLFormat(texImage);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texImage.width(), texImage.height(),
+ 0, GL_RGBA, GL_UNSIGNED_BYTE, texImage.bits());
+ if (smoothScale)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ else
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ if (useTrilinearFiltering) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glGenerateMipmap(GL_TEXTURE_2D);
} else {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
glBindTexture(GL_TEXTURE_2D, 0);
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())
@@ -105,13 +88,12 @@ GLuint TextureHelper::createCubeMapTexture(const QImage &image, bool useTrilinea
QImage glTexture = convertToGLFormat(image);
glTexImage2D(GL_TEXTURE_CUBE_MAP, 0, GL_RGBA, glTexture.width(), glTexture.height(),
0, GL_RGBA, GL_UNSIGNED_BYTE, glTexture.bits());
+ glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
if (useTrilinearFiltering) {
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
} else {
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
glBindTexture(GL_TEXTURE_2D, 0);
return textureId;
@@ -391,4 +373,4 @@ QRgb TextureHelper::qt_gl_convertToGLFormatHelper(QRgb src_pixel, GLenum texture
}
}
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavis3d/utils/texturehelper_p.h b/src/datavisualization/utils/texturehelper_p.h
index e8f17d33..f7779b59 100644
--- a/src/datavis3d/utils/texturehelper_p.h
+++ b/src/datavisualization/utils/texturehelper_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -29,11 +29,11 @@
#ifndef TEXTUREHELPER_P_H
#define TEXTUREHELPER_P_H
-#include "datavis3dglobal_p.h"
+#include "datavisualizationglobal_p.h"
#include <QOpenGLFunctions>
#include <QRgb>
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
class TextureHelper : protected QOpenGLFunctions
{
@@ -43,8 +43,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);
+ bool convert = true, bool smoothScale = true);
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);
@@ -61,12 +60,11 @@ 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 Bars3dRenderer;
- friend class Maps3DController;
- friend class Surface3dRenderer;
+ friend class Bars3DRenderer;
+ friend class Surface3DRenderer;
friend class Scatter3DRenderer;
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif
diff --git a/src/datavisualization/utils/utils.cpp b/src/datavisualization/utils/utils.cpp
new file mode 100644
index 00000000..947dbfba
--- /dev/null
+++ b/src/datavisualization/utils/utils.cpp
@@ -0,0 +1,263 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 "utils_p.h"
+
+#include <QVector3D>
+#include <QColor>
+#include <QPainter>
+#include <QPoint>
+#include <QImage>
+#include <QRegExp>
+#include <qmath.h>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+#define NUM_IN_POWER(y, x) for (;y<x;y<<=1)
+#define MIN_POWER 32
+
+GLuint Utils::getNearestPowerOfTwo(GLuint value, GLuint &padding)
+{
+ GLuint powOfTwoValue = MIN_POWER;
+ NUM_IN_POWER(powOfTwoValue, value);
+ padding = powOfTwoValue - value;
+ return powOfTwoValue;
+}
+
+QVector3D Utils::vectorFromColor(const QColor &color)
+{
+ return QVector3D(color.redF(), color.greenF(), color.blueF());
+}
+
+QImage Utils::printTextToImage(const QFont &font, const QString &text, const QColor &bgrColor,
+ const QColor &txtColor, QDataVis::LabelStyle style,
+ bool borders, int maxLabelWidth)
+{
+ GLuint paddingWidth = 20;
+ GLuint paddingHeight = 20;
+ // Calculate text dimensions
+ QFont valueFont = font;
+ valueFont.setPointSize(textureFontSize);
+ QFontMetrics valueFM(valueFont);
+ int valueStrWidth = valueFM.width(text);
+ if (maxLabelWidth && QDataVis::LabelStyleTransparent != style)
+ valueStrWidth = maxLabelWidth;
+ int valueStrHeight = valueFM.height();
+ valueStrWidth += paddingWidth / 2; // Fix clipping problem with skewed fonts (italic or italic-style)
+ QSize labelSize;
+
+#if defined(Q_OS_ANDROID)
+ // Android can't handle textures with dimensions not in power of 2. Resize labels accordingly.
+ // Add some padding before converting to power of two to avoid too tight fit
+ GLuint prePadding = 5;
+ // Android needs to use this always (when given) because of the power of 2 -issue.
+ if (maxLabelWidth)
+ valueStrWidth = maxLabelWidth + paddingWidth / 2;
+ labelSize = QSize(valueStrWidth + prePadding, valueStrHeight + prePadding);
+ //qDebug() << "label size before padding" << text << labelSize;
+ labelSize.setWidth(getNearestPowerOfTwo(labelSize.width(), paddingWidth));
+ labelSize.setHeight(getNearestPowerOfTwo(labelSize.height(), paddingHeight));
+ //qDebug() << "label size after padding" << labelSize << paddingWidth << paddingHeight;
+#else
+ if (QDataVis::LabelStyleTransparent == style)
+ labelSize = QSize(valueStrWidth, valueStrHeight);
+ else
+ labelSize = QSize(valueStrWidth + paddingWidth * 2, valueStrHeight + paddingHeight * 2);
+#endif
+
+ // Create image
+ QImage image = QImage(labelSize, QImage::Format_ARGB32);
+ image.fill(Qt::transparent);
+
+ // Init painter
+ QPainter painter(&image);
+ // Paint text
+ painter.setRenderHint(QPainter::Antialiasing, true);
+ painter.setCompositionMode(QPainter::CompositionMode_Source);
+ painter.setFont(valueFont);
+ switch (style) {
+ case QDataVis::LabelStyleTransparent: {
+ painter.setPen(txtColor);
+#if defined(Q_OS_ANDROID)
+ painter.drawText((labelSize.width() - valueStrWidth) / 2.0f,
+ (labelSize.height() - valueStrHeight) / 2.0f,
+ valueStrWidth, valueStrHeight,
+ Qt::AlignCenter | Qt::AlignVCenter,
+ text);
+#else
+ painter.drawText(0, 0,
+ valueStrWidth, valueStrHeight,
+ Qt::AlignCenter | Qt::AlignVCenter,
+ text);
+#endif
+ break;
+ }
+ case QDataVis::LabelStyleFromTheme: {
+ painter.setBrush(QBrush(bgrColor));
+ if (borders) {
+ painter.setPen(QPen(QBrush(txtColor), 5, Qt::SolidLine, Qt::SquareCap, Qt::RoundJoin));
+ painter.drawRoundedRect(5, 5, labelSize.width() - 10, labelSize.height() - 10,
+ 10.0, 10.0);
+ } else {
+ painter.setPen(bgrColor);
+ painter.drawRoundedRect(0, 0, labelSize.width(), labelSize.height(), 10.0, 10.0);
+ }
+ painter.setPen(txtColor);
+ painter.drawText((labelSize.width() - valueStrWidth) / 2.0f,
+ (labelSize.height() - valueStrHeight) / 2.0f,
+ valueStrWidth, valueStrHeight,
+ Qt::AlignCenter | Qt::AlignVCenter,
+ text);
+ break;
+ }
+ case QDataVis::LabelStyleOpaque: {
+ QColor labelColor = QColor(bgrColor);
+ labelColor.setAlphaF(1.0);
+ painter.setBrush(QBrush(labelColor));
+ if (borders) {
+ painter.setPen(QPen(QBrush(txtColor), 7, Qt::SolidLine, Qt::SquareCap, Qt::MiterJoin));
+ painter.drawRect(7, 7, labelSize.width() - 14, labelSize.height() - 14);
+ } else {
+ painter.setPen(labelColor);
+ painter.drawRect(0, 0, labelSize.width(), labelSize.height());
+ }
+ painter.setPen(txtColor);
+ painter.drawText((labelSize.width() - valueStrWidth) / 2.0f,
+ (labelSize.height() - valueStrHeight) / 2.0f,
+ valueStrWidth, valueStrHeight,
+ Qt::AlignCenter | Qt::AlignVCenter,
+ text);
+ break;
+ }
+ }
+ return image;
+}
+
+QVector3D Utils::getSelection(QPoint mousepos, int height)
+{
+ QVector3D selectedColor;
+
+ //#if defined(QT_OPENGL_ES_2)
+ // This is the only one that works with ANGLE (ES 2.0)
+ // Item count will be limited to 256*256*256
+ GLubyte pixel[4];
+ glReadPixels(mousepos.x(), height - mousepos.y(), 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
+ (void *)pixel);
+
+ //qDebug() << "rgba" << pixel[0] << pixel[1] << pixel[2] << pixel[3] << "mousepos:" << mousepos << "height:" << height;
+
+ //#else
+ // These work with desktop OpenGL
+ // They offer a lot higher possible object count and a possibility to use object ids
+ //GLuint pixel[3];
+ //glReadPixels(mousepos.x(), height - mousepos.y(), 1, 1,
+ // GL_RGB, GL_UNSIGNED_INT, (void *)pixel);
+ //qDebug() << "rgba" << pixel[0] << pixel[1] << pixel[2];// << pixel[3];
+
+ //GLfloat pixel3[3];
+ //glReadPixels(mousepos.x(), height - mousepos.y(), 1, 1,
+ // GL_RGB, GL_FLOAT, (void *)pixel3);
+ //qDebug() << "rgba" << pixel3[0] << pixel3[1] << pixel3[2];// << pixel[3];
+ //#endif
+ selectedColor = QVector3D(pixel[0], pixel[1], pixel[2]);
+ //qDebug() << selectedColor;
+
+ return selectedColor;
+}
+
+Utils::ParamType Utils::mapFormatCharToParamType(const QChar &formatChar)
+{
+ ParamType retVal = ParamTypeUnknown;
+ if (formatChar == QLatin1Char('d')
+ || formatChar == QLatin1Char('i')
+ || formatChar == QLatin1Char('c')) {
+ retVal = ParamTypeInt;
+ } else if (formatChar == QLatin1Char('u')
+ || formatChar == QLatin1Char('o')
+ || formatChar == QLatin1Char('x')
+ || formatChar == QLatin1Char('X')) {
+ retVal = ParamTypeUInt;
+ } else if (formatChar == QLatin1Char('f')
+ || formatChar == QLatin1Char('F')
+ || formatChar == QLatin1Char('e')
+ || formatChar == QLatin1Char('E')
+ || formatChar == QLatin1Char('g')
+ || formatChar == QLatin1Char('G')) {
+ retVal = ParamTypeReal;
+ }
+
+ return retVal;
+}
+
+Utils::ParamType Utils::findFormatParamType(const QString &format)
+{
+ static QRegExp formatMatcher(QStringLiteral("%[\\-\\+#\\s\\d\\.lhjztL]*([dicuoxfegXFEG])"));
+
+ if (formatMatcher.indexIn(format, 0) != -1) {
+ QString capStr = formatMatcher.cap(1);
+ if (capStr.isEmpty())
+ return ParamTypeUnknown;
+ else
+ return mapFormatCharToParamType(capStr.at(0));
+ }
+
+ return ParamTypeUnknown;
+}
+
+QString Utils::formatLabel(const QByteArray &format, ParamType paramType, qreal value)
+{
+ switch (paramType) {
+ case ParamTypeInt:
+ return QString().sprintf(format, (qint64)value);
+ case ParamTypeUInt:
+ return QString().sprintf(format, (quint64)value);
+ case ParamTypeReal:
+ return QString().sprintf(format, value);
+ default:
+ return QString::fromUtf8(format); // To detect errors
+ }
+}
+
+QString Utils::defaultLabelFormat()
+{
+ static const QString defaultFormat(QStringLiteral("%.2f"));
+ return defaultFormat;
+}
+
+qreal Utils::wrapValue(qreal value, qreal min, qreal max)
+{
+ if (value > max) {
+ value = min + (value - max);
+
+ // In case single wrap fails, jump to opposite end.
+ if (value > max)
+ value = min;
+ }
+
+ if (value < min) {
+ value = max + (value - min);
+
+ // In case single wrap fails, jump to opposite end.
+ if (value < min)
+ value = max;
+ }
+
+ return value;
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavis3d/utils/utils.pri b/src/datavisualization/utils/utils.pri
index cef5ebf0..cef5ebf0 100644
--- a/src/datavis3d/utils/utils.pri
+++ b/src/datavisualization/utils/utils.pri
diff --git a/src/datavis3d/utils/utils_p.h b/src/datavisualization/utils/utils_p.h
index fe7d6081..e74b590d 100644
--- a/src/datavis3d/utils/utils_p.h
+++ b/src/datavisualization/utils/utils_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -29,7 +29,7 @@
#ifndef UTILS_P_H
#define UTILS_P_H
-#include "datavis3dglobal_p.h"
+#include "datavisualizationglobal_p.h"
#include "q3dbars.h"
class QVector3D;
@@ -39,11 +39,18 @@ class QString;
class QPoint;
class QImage;
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
class Utils
{
- public:
+public:
+ enum ParamType {
+ ParamTypeUnknown = 0,
+ ParamTypeInt,
+ ParamTypeUInt,
+ ParamTypeReal
+ };
+
static GLuint getNearestPowerOfTwo(GLuint value, GLuint &padding);
static QVector3D vectorFromColor(const QColor &color);
static void printText(QPainter *painter, const QString &text, const QSize &position,
@@ -52,10 +59,21 @@ class Utils
const QString &text,
const QColor &bgrColor,
const QColor &txtColor,
- QDataVis::LabelTransparency transparency);
+ QDataVis::LabelStyle style,
+ bool borders = false,
+ int maxLabelWidth = 0);
static QVector3D getSelection(QPoint mousepos, int height);
+
+ static ParamType findFormatParamType(const QString &format);
+ static QString formatLabel(const QByteArray &format, ParamType paramType, qreal value);
+ static QString defaultLabelFormat();
+
+ static qreal wrapValue(qreal value, qreal min, qreal max);
+
+private:
+ static ParamType mapFormatCharToParamType(const QChar &formatChar);
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif
diff --git a/src/datavis3d/utils/vertexindexer.cpp b/src/datavisualization/utils/vertexindexer.cpp
index 6efba116..63b9faaf 100644
--- a/src/datavis3d/utils/vertexindexer.cpp
+++ b/src/datavisualization/utils/vertexindexer.cpp
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -23,7 +23,7 @@
#include <QDebug>
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
int unique_vertices = 0;
@@ -150,4 +150,4 @@ void VertexIndexer::indexVBO_TBN(const QVector<QVector3D> &in_vertices,
//qDebug() << "unique vertices" << unique_vertices;
}
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavis3d/utils/vertexindexer_p.h b/src/datavisualization/utils/vertexindexer_p.h
index 3ca62236..0cf1857b 100644
--- a/src/datavis3d/utils/vertexindexer_p.h
+++ b/src/datavisualization/utils/vertexindexer_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -29,13 +29,13 @@
#ifndef VERTEXINDEXER_P_H
#define VERTEXINDEXER_P_H
-#include "datavis3dglobal_p.h"
+#include "datavisualizationglobal_p.h"
#include <QVector>
#include <QVector2D>
#include <QVector3D>
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
class VertexIndexer
{
@@ -83,6 +83,6 @@ class VertexIndexer
unsigned short &result);
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif
diff --git a/src/datavisualizationqml2/abstractdeclarative.cpp b/src/datavisualizationqml2/abstractdeclarative.cpp
new file mode 100644
index 00000000..e853ff9c
--- /dev/null
+++ b/src/datavisualizationqml2/abstractdeclarative.cpp
@@ -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 QtDataVisualization 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 "abstractdeclarative_p.h"
+#include "q3dvalueaxis.h"
+#include "theme_p.h"
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+AbstractDeclarative::AbstractDeclarative(QQuickItem *parent) :
+ QQuickItem(parent)
+{
+}
+
+AbstractDeclarative::~AbstractDeclarative()
+{
+}
+
+Q3DScene* AbstractDeclarative::scene() const
+{
+ return m_controller->scene();
+}
+
+void AbstractDeclarative::setTheme(QDataVis::Theme theme)
+{
+ // TODO: Implement correctly once "user-modifiable themes" (QTRD-2120) is implemented
+ m_controller->setTheme(theme);
+}
+
+QDataVis::Theme AbstractDeclarative::theme() const
+{
+ return m_controller->theme().theme();
+}
+
+void AbstractDeclarative::setSelectionMode(QDataVis::SelectionMode mode)
+{
+ m_controller->setSelectionMode(mode);
+}
+
+QDataVis::SelectionMode AbstractDeclarative::selectionMode() const
+{
+ return m_controller->selectionMode();
+}
+
+void AbstractDeclarative::setFont(const QFont &font)
+{
+ m_controller->setFont(font);
+}
+
+QFont AbstractDeclarative::font() const
+{
+ return m_controller->font();
+}
+
+void AbstractDeclarative::setLabelStyle(QDataVis::LabelStyle style)
+{
+ m_controller->setLabelStyle(style);
+}
+
+QDataVis::LabelStyle AbstractDeclarative::labelStyle() const
+{
+ return m_controller->labelStyle();
+}
+
+void AbstractDeclarative::setGridVisible(bool visible)
+{
+ m_controller->setGridEnabled(visible);
+}
+
+bool AbstractDeclarative::isGridVisible() const
+{
+ return m_controller->gridEnabled();
+}
+
+void AbstractDeclarative::setBackgroundVisible(bool visible)
+{
+ m_controller->setBackgroundEnabled(visible);
+}
+
+bool AbstractDeclarative::isBackgroundVisible() const
+{
+ return m_controller->backgroundEnabled();
+}
+
+void AbstractDeclarative::setShadowQuality(QDataVis::ShadowQuality quality)
+{
+ m_controller->setShadowQuality(quality);
+}
+
+QDataVis::ShadowQuality AbstractDeclarative::shadowQuality() const
+{
+ return m_controller->shadowQuality();
+}
+
+void AbstractDeclarative::setItemLabelFormat(const QString &format)
+{
+ m_controller->activeDataProxy()->setItemLabelFormat(format);
+}
+
+QString AbstractDeclarative::itemLabelFormat() const
+{
+ return m_controller->activeDataProxy()->itemLabelFormat();
+}
+
+void AbstractDeclarative::setSharedController(Abstract3DController *controller)
+{
+ Q_ASSERT(controller);
+ m_controller = controller;
+ QObject::connect(m_controller, &Abstract3DController::shadowQualityChanged, this,
+ &AbstractDeclarative::handleShadowQualityUpdate);
+ emit sceneChanged(m_controller->scene());
+ QObject::connect(m_controller, &Abstract3DController::activeInputHandlerChanged, this,
+ &AbstractDeclarative::handleInputHandlerUpdate);
+ emit inputHandlerChanged(m_controller->activeInputHandler());
+}
+
+QAbstract3DInputHandler* AbstractDeclarative::inputHandler() const
+{
+ return m_controller->activeInputHandler();
+}
+
+void AbstractDeclarative::setInputHandler(QAbstract3DInputHandler *inputHandler)
+{
+ m_controller->setActiveInputHandler(inputHandler);
+}
+
+void AbstractDeclarative::mouseDoubleClickEvent(QMouseEvent *event)
+{
+ m_controller->mouseDoubleClickEvent(event);
+}
+
+void AbstractDeclarative::touchEvent(QTouchEvent *event)
+{
+ m_controller->touchEvent(event);
+ update();
+}
+
+void AbstractDeclarative::mousePressEvent(QMouseEvent *event)
+{
+ QPoint mousePos = event->pos();
+ //mousePos.setY(height() - mousePos.y());
+ m_controller->mousePressEvent(event, mousePos);
+}
+
+void AbstractDeclarative::mouseReleaseEvent(QMouseEvent *event)
+{
+ QPoint mousePos = event->pos();
+ //mousePos.setY(height() - mousePos.y());
+ m_controller->mouseReleaseEvent(event, mousePos);
+}
+
+void AbstractDeclarative::mouseMoveEvent(QMouseEvent *event)
+{
+ QPoint mousePos = event->pos();
+ //mousePos.setY(height() - mousePos.y());
+ m_controller->mouseMoveEvent(event, mousePos);
+}
+
+void AbstractDeclarative::wheelEvent(QWheelEvent *event)
+{
+ m_controller->wheelEvent(event);
+}
+
+void AbstractDeclarative::handleShadowQualityUpdate(QDataVis::ShadowQuality quality)
+{
+ emit shadowQualityChanged(quality);
+}
+
+void AbstractDeclarative::handleInputHandlerUpdate(QAbstract3DInputHandler *inputHandler)
+{
+ emit inputHandlerChanged(inputHandler);
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualizationqml2/abstractdeclarative_p.h b/src/datavisualizationqml2/abstractdeclarative_p.h
new file mode 100644
index 00000000..41d4a4da
--- /dev/null
+++ b/src/datavisualizationqml2/abstractdeclarative_p.h
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 QtDataVisualization 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 ABSTRACTDECLARATIVE_P_H
+#define ABSTRACTDECLARATIVE_P_H
+
+#include "datavisualizationglobal_p.h"
+#include "abstract3dcontroller_p.h"
+#include "qabstract3dinputhandler.h"
+
+#include <QAbstractItemModel>
+#include <QQuickItem>
+#include <QObject>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class AbstractDeclarative : public QQuickItem
+{
+ Q_OBJECT
+ Q_PROPERTY(QtDataVisualization::QDataVis::SelectionMode selectionMode READ selectionMode WRITE setSelectionMode)
+ Q_PROPERTY(QtDataVisualization::QDataVis::LabelStyle labelStyle READ labelStyle WRITE setLabelStyle)
+ Q_PROPERTY(QtDataVisualization::QDataVis::ShadowQuality shadowQuality READ shadowQuality WRITE setShadowQuality)
+ Q_PROPERTY(Q3DScene* scene READ scene NOTIFY sceneChanged)
+ Q_PROPERTY(QAbstract3DInputHandler* inputHandler READ inputHandler WRITE setInputHandler NOTIFY inputHandlerChanged)
+ Q_PROPERTY(QtDataVisualization::QDataVis::Theme theme READ theme WRITE setTheme)
+ Q_PROPERTY(QFont font READ font WRITE setFont)
+ Q_PROPERTY(bool gridVisible READ isGridVisible WRITE setGridVisible)
+ Q_PROPERTY(bool backgroundVisible READ isBackgroundVisible WRITE setBackgroundVisible)
+ Q_PROPERTY(QString itemLabelFormat READ itemLabelFormat WRITE setItemLabelFormat)
+ Q_ENUMS(QtDataVisualization::QDataVis::SelectionMode)
+ Q_ENUMS(QtDataVisualization::QDataVis::ShadowQuality)
+ Q_ENUMS(QtDataVisualization::QDataVis::LabelStyle)
+ Q_ENUMS(QtDataVisualization::QDataVis::CameraPreset)
+ Q_ENUMS(QtDataVisualization::QDataVis::Theme)
+
+public:
+ explicit AbstractDeclarative(QQuickItem *parent = 0);
+ virtual ~AbstractDeclarative();
+
+ virtual Q3DScene *scene() const;
+
+ virtual QAbstract3DInputHandler *inputHandler() const;
+ virtual void setInputHandler(QAbstract3DInputHandler *inputHandler);
+
+ virtual void setTheme(QDataVis::Theme theme);
+ virtual QDataVis::Theme theme() const;
+
+ virtual void setSelectionMode(QDataVis::SelectionMode mode);
+ virtual QDataVis::SelectionMode selectionMode() const;
+
+ virtual void setFont(const QFont &font);
+ virtual QFont font() const;
+
+ virtual void setLabelStyle(QDataVis::LabelStyle style);
+ virtual QDataVis::LabelStyle labelStyle() const;
+
+ virtual void setGridVisible(bool visible);
+ virtual bool isGridVisible() const;
+
+ virtual void setBackgroundVisible(bool visible);
+ virtual bool isBackgroundVisible() const;
+
+ virtual void setShadowQuality(QDataVis::ShadowQuality quality);
+ virtual QDataVis::ShadowQuality shadowQuality() const;
+
+ virtual void setItemLabelFormat(const QString &format);
+ virtual QString itemLabelFormat() const;
+
+ void setSharedController(Abstract3DController *controller);
+
+protected:
+ virtual void mouseDoubleClickEvent(QMouseEvent *event);
+ virtual void touchEvent(QTouchEvent *event);
+ virtual void mousePressEvent(QMouseEvent *event);
+ virtual void mouseReleaseEvent(QMouseEvent *event);
+ virtual void mouseMoveEvent(QMouseEvent *event);
+ virtual void wheelEvent(QWheelEvent *event);
+
+ // Used to detect when shadow quality changes autonomously due to e.g. resizing.
+ virtual void handleShadowQualityUpdate(QDataVis::ShadowQuality quality);
+ virtual void handleInputHandlerUpdate(QAbstract3DInputHandler *inputHandler);
+signals:
+ // Signals shadow quality changes.
+ void shadowQualityChanged(QDataVis::ShadowQuality quality);
+ void sceneChanged(Q3DScene *scene);
+ void inputHandlerChanged(QAbstract3DInputHandler *inputHandler);
+
+private:
+ Abstract3DController *m_controller;
+};
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
+#endif // ABSTRACTDECLARATIVE_P_H
diff --git a/src/datavisualizationqml2/colorgradient.cpp b/src/datavisualizationqml2/colorgradient.cpp
new file mode 100644
index 00000000..43efbd1c
--- /dev/null
+++ b/src/datavisualizationqml2/colorgradient.cpp
@@ -0,0 +1,75 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 "colorgradient_p.h"
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+ColorGradientStop::ColorGradientStop(QObject *parent)
+ : QObject(parent)
+{
+}
+
+qreal ColorGradientStop::position() const
+{
+ return m_position;
+}
+
+void ColorGradientStop::setPosition(qreal position)
+{
+ m_position = position;
+ updateGradient();
+}
+
+QColor ColorGradientStop::color() const
+{
+ return m_color;
+}
+
+void ColorGradientStop::setColor(const QColor &color)
+{
+ m_color = color;
+ updateGradient();
+}
+
+void ColorGradientStop::updateGradient()
+{
+ if (ColorGradient *grad = qobject_cast<ColorGradient*>(parent()))
+ grad->doUpdate();
+}
+
+ColorGradient::ColorGradient(QObject *parent)
+: QObject(parent)
+{
+}
+
+ColorGradient::~ColorGradient()
+{
+}
+
+QQmlListProperty<ColorGradientStop> ColorGradient::stops()
+{
+ return QQmlListProperty<ColorGradientStop>(this, m_stops);
+}
+
+void ColorGradient::doUpdate()
+{
+ emit updated();
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualizationqml2/colorgradient_p.h b/src/datavisualizationqml2/colorgradient_p.h
new file mode 100644
index 00000000..37d3e407
--- /dev/null
+++ b/src/datavisualizationqml2/colorgradient_p.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 QtDataVisualization 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 COLORGRADIENT_P_H
+#define COLORGRADIENT_P_H
+
+#include "datavisualizationglobal_p.h"
+#include <QColor>
+#include <QQmlListProperty>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class ColorGradientStop : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(qreal position READ position WRITE setPosition)
+ Q_PROPERTY(QColor color READ color WRITE setColor)
+
+public:
+ ColorGradientStop(QObject *parent = 0);
+
+ qreal position() const;
+ void setPosition(qreal position);
+
+ QColor color() const;
+ void setColor(const QColor &color);
+
+private:
+ void updateGradient();
+
+private:
+ qreal m_position;
+ QColor m_color;
+};
+
+class ColorGradient : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QQmlListProperty<ColorGradientStop> stops READ stops)
+ Q_CLASSINFO("DefaultProperty", "stops")
+
+public:
+ ColorGradient(QObject *parent = 0);
+ ~ColorGradient();
+
+ QQmlListProperty<ColorGradientStop> stops();
+
+Q_SIGNALS:
+ void updated();
+
+private:
+ void doUpdate();
+
+private:
+ QList<ColorGradientStop *> m_stops;
+
+ friend class ColorGradientStop;
+ friend class DeclarativeSurface;
+};
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3dqml2/datavis3dqml2.pro b/src/datavisualizationqml2/datavisualizationqml2.pro
index c994c5be..d5191c62 100644
--- a/src/datavis3dqml2/datavis3dqml2.pro
+++ b/src/datavisualizationqml2/datavisualizationqml2.pro
@@ -1,38 +1,42 @@
TEMPLATE = lib
-TARGET = datavis3dqml2
-QT += qml quick datavis3d
+TARGET = datavisualizationqml2
+QT += qml quick datavisualization
CONFIG += qt plugin
TARGET = $$qtLibraryTarget($$TARGET)
-uri = com.digia.QtDataVis3D
+uri = com.digia.QtDataVisualization
static {
- DEFINES += QT_DATAVIS3D_STATICLIB
+ DEFINES += QT_DATAVISUALIZATION_STATICLIB
CONFIG -= static staticlib
}
# Input
-INCLUDEPATH += ../datavis3d/engine \
- ../datavis3d/global \
- ../datavis3d/data
+INCLUDEPATH += ../datavisualization/engine \
+ ../datavisualization/global \
+ ../datavisualization/data
SOURCES += \
- datavis3dqml2_plugin.cpp \
+ datavisualizationqml2_plugin.cpp \
declarativebars.cpp \
declarativebarsrenderer.cpp \
declarativescatter.cpp \
declarativescatterrenderer.cpp \
- declarativemaps.cpp \
- declarativemapsrenderer.cpp
+ declarativesurface.cpp \
+ declarativesurfacerenderer.cpp \
+ abstractdeclarative.cpp \
+ colorgradient.cpp
HEADERS += \
- datavis3dqml2_plugin.h \
+ datavisualizationqml2_plugin.h \
declarativebars_p.h \
declarativebarsrenderer_p.h \
declarativescatter_p.h \
declarativescatterrenderer_p.h \
- declarativemaps_p.h \
- declarativemapsrenderer_p.h
+ declarativesurface_p.h \
+ declarativesurfacerenderer_p.h \
+ abstractdeclarative_p.h \
+ colorgradient_p.h
OTHER_FILES = qmldir
diff --git a/src/datavisualizationqml2/datavisualizationqml2_plugin.cpp b/src/datavisualizationqml2/datavisualizationqml2_plugin.cpp
new file mode 100644
index 00000000..b98f72ac
--- /dev/null
+++ b/src/datavisualizationqml2/datavisualizationqml2_plugin.cpp
@@ -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 QtDataVisualization 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 "datavisualizationqml2_plugin.h"
+
+#include <qqml.h>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+void Datavis3Dqml2Plugin::registerTypes(const char *uri)
+{
+ // @uri com.digia.QtDataVisualization
+ qmlRegisterUncreatableType<const QAbstractItemModel>(uri, 1, 0, "AbstractItemModel",
+ QLatin1String("Trying to create uncreatable: AbstractItemModel."));
+ qmlRegisterUncreatableType<QDataVis>(uri, 1, 0, "DataVis",
+ QLatin1String("Trying to create uncreatable: DataVis."));
+ qmlRegisterUncreatableType<Q3DAbstractAxis>(uri, 1, 0, "AbstractAxis3D",
+ QLatin1String("Trying to create uncreatable: AbstractAxis."));
+ qmlRegisterUncreatableType<QAbstractDataProxy>(uri, 1, 0, "AbstractDataProxy",
+ QLatin1String("Trying to create uncreatable: AbstractDataProxy."));
+ qmlRegisterUncreatableType<QBarDataProxy>(uri, 1, 0, "BarDataProxy",
+ QLatin1String("Trying to create uncreatable: BarDataProxy."));
+ qmlRegisterUncreatableType<QScatterDataProxy>(uri, 1, 0, "ScatterDataProxy",
+ QLatin1String("Trying to create uncreatable: ScatterDataProxy."));
+ qmlRegisterUncreatableType<QSurfaceDataProxy>(uri, 1, 0, "SurfaceDataProxy",
+ QLatin1String("Trying to create uncreatable: SurfaceDataProxy."));
+ qmlRegisterUncreatableType<AbstractDeclarative>(uri, 1, 0, "AbstractGraph3D",
+ QLatin1String("Trying to create uncreatable: AbstractGraph3D."));
+ qmlRegisterUncreatableType<Q3DScene>(uri, 1, 0, "Scene3D",
+ QLatin1String("Trying to create uncreatable: Scene3D."));
+
+ qmlRegisterType<QItemModelBarDataMapping>(uri, 1, 0, "BarDataMapping");
+ qmlRegisterType<QItemModelScatterDataMapping>(uri, 1, 0, "ScatterDataMapping");
+ qmlRegisterType<QItemModelSurfaceDataMapping>(uri, 1, 0, "SurfaceDataMapping");
+
+ qmlRegisterType<DeclarativeBars>(uri, 1, 0, "Bars3D");
+ qmlRegisterType<DeclarativeScatter>(uri, 1, 0, "Scatter3D");
+ qmlRegisterType<DeclarativeSurface>(uri, 1, 0, "Surface3D");
+
+ qmlRegisterType<Q3DValueAxis>(uri, 1, 0, "ValueAxis3D");
+ qmlRegisterType<Q3DCategoryAxis>(uri, 1, 0, "CategoryAxis3D");
+
+ qmlRegisterType<Q3DCamera>(uri, 1, 0, "Camera3D");
+
+ qmlRegisterType<QItemModelBarDataProxy>(uri, 1, 0, "ItemModelBarDataProxy");
+ qmlRegisterType<QItemModelScatterDataProxy>(uri, 1, 0, "ItemModelScatterDataProxy");
+ qmlRegisterType<QItemModelSurfaceDataProxy>(uri, 1, 0, "ItemModelSurfaceDataProxy");
+ qmlRegisterType<QHeightMapSurfaceDataProxy>(uri, 1, 0, "HeightMapSurfaceDataProxy");
+
+ qmlRegisterType<ColorGradientStop>(uri, 1, 0, "ColorGradientStop");
+ qmlRegisterType<ColorGradient>(uri, 1, 0, "ColorGradient");
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
diff --git a/src/datavisualizationqml2/datavisualizationqml2_plugin.h b/src/datavisualizationqml2/datavisualizationqml2_plugin.h
new file mode 100644
index 00000000..c0d7c4b8
--- /dev/null
+++ b/src/datavisualizationqml2/datavisualizationqml2_plugin.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 QtDataVisualization 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 DATAVISUALIZATIONQML2_PLUGIN_H
+#define DATAVISUALIZATIONQML2_PLUGIN_H
+
+#include "datavisualizationglobal_p.h"
+#include "declarativebars_p.h"
+#include "declarativescatter_p.h"
+#include "declarativesurface_p.h"
+#include "qitemmodelbardatamapping.h"
+#include "qitemmodelscatterdatamapping.h"
+#include "qitemmodelsurfacedatamapping.h"
+#include "qitemmodelbardataproxy.h"
+#include "qitemmodelscatterdataproxy.h"
+#include "qitemmodelsurfacedataproxy.h"
+#include "qheightmapsurfacedataproxy.h"
+#include "q3dvalueaxis.h"
+#include "q3dcategoryaxis.h"
+#include "q3dobject.h"
+#include "q3dcamera.h"
+#include "q3dscene.h"
+
+#include <QQmlExtensionPlugin>
+
+QT_DATAVISUALIZATION_USE_NAMESPACE
+
+QML_DECLARE_TYPE(AbstractDeclarative)
+QML_DECLARE_TYPE(DeclarativeBars)
+QML_DECLARE_TYPE(DeclarativeScatter)
+QML_DECLARE_TYPE(DeclarativeSurface)
+
+QML_DECLARE_TYPE(QItemModelBarDataMapping)
+QML_DECLARE_TYPE(QItemModelScatterDataMapping)
+QML_DECLARE_TYPE(QItemModelSurfaceDataMapping)
+
+QML_DECLARE_TYPE(const QAbstractItemModel)
+QML_DECLARE_TYPE(QDataVis)
+
+QML_DECLARE_TYPE(Q3DAbstractAxis)
+QML_DECLARE_TYPE(Q3DCategoryAxis)
+QML_DECLARE_TYPE(Q3DValueAxis)
+
+QML_DECLARE_TYPE(Q3DScene)
+QML_DECLARE_TYPE(Q3DCamera)
+
+QML_DECLARE_TYPE(QAbstractDataProxy)
+QML_DECLARE_TYPE(QBarDataProxy)
+QML_DECLARE_TYPE(QItemModelBarDataProxy)
+QML_DECLARE_TYPE(QScatterDataProxy)
+QML_DECLARE_TYPE(QItemModelScatterDataProxy)
+QML_DECLARE_TYPE(QSurfaceDataProxy)
+QML_DECLARE_TYPE(QItemModelSurfaceDataProxy)
+QML_DECLARE_TYPE(QHeightMapSurfaceDataProxy)
+
+QML_DECLARE_TYPE(ColorGradientStop)
+QML_DECLARE_TYPE(ColorGradient)
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class Datavis3Dqml2Plugin : public QQmlExtensionPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface")
+
+public:
+ void registerTypes(const char *uri);
+};
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
+#endif // DATAVISUALIZATIONQML2_PLUGIN_H
+
diff --git a/src/datavisualizationqml2/declarativebars.cpp b/src/datavisualizationqml2/declarativebars.cpp
new file mode 100644
index 00000000..9ed80106
--- /dev/null
+++ b/src/datavisualizationqml2/declarativebars.cpp
@@ -0,0 +1,214 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 "declarativebars_p.h"
+#include "declarativebarsrenderer_p.h"
+#include "q3dvalueaxis.h"
+#include "qitemmodelbardataproxy.h"
+#include "theme_p.h"
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+const QString smoothString(QStringLiteral("Smooth"));
+
+DeclarativeBars::DeclarativeBars(QQuickItem *parent)
+ : AbstractDeclarative(parent),
+ m_shared(0),
+ m_initialisedSize(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);
+
+ // Create the shared component on the main GUI thread.
+ m_shared = new Bars3DController(boundingRect().toRect());
+ AbstractDeclarative::setSharedController(m_shared);
+ QObject::connect(m_shared, &Bars3DController::selectedBarPosChanged, this,
+ &DeclarativeBars::selectedBarPosChanged);
+
+ QItemModelBarDataProxy *proxy = new QItemModelBarDataProxy;
+ m_shared->setActiveDataProxy(proxy);
+}
+
+DeclarativeBars::~DeclarativeBars()
+{
+ delete m_shared;
+}
+
+
+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;
+ }
+
+ // 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
+ DeclarativeBarsRenderer *node = new DeclarativeBarsRenderer(window(), m_shared);
+ node->setRect(boundingRect());
+ m_shared->setBoundingRect(boundingRect().toRect());
+ return node;
+}
+
+void DeclarativeBars::setBarColor(const QColor &baseColor, bool uniform)
+{
+ m_shared->setObjectColor(baseColor, uniform);
+}
+
+void DeclarativeBars::setDataProxy(QBarDataProxy *dataProxy)
+{
+ m_shared->setActiveDataProxy(dataProxy);
+}
+
+QBarDataProxy *DeclarativeBars::dataProxy() const
+{
+ return static_cast<QBarDataProxy *>(m_shared->activeDataProxy());
+}
+
+Q3DCategoryAxis *DeclarativeBars::rowAxis() const
+{
+ return static_cast<Q3DCategoryAxis *>(m_shared->axisX());
+}
+
+void DeclarativeBars::setRowAxis(Q3DCategoryAxis *axis)
+{
+ m_shared->setAxisX(axis);
+}
+
+Q3DValueAxis *DeclarativeBars::valueAxis() const
+{
+ return static_cast<Q3DValueAxis *>(m_shared->axisY());
+}
+
+void DeclarativeBars::setValueAxis(Q3DValueAxis *axis)
+{
+ m_shared->setAxisY(axis);
+}
+
+Q3DCategoryAxis *DeclarativeBars::columnAxis() const
+{
+ return static_cast<Q3DCategoryAxis *>(m_shared->axisZ());
+}
+
+void DeclarativeBars::setColumnAxis(Q3DCategoryAxis *axis)
+{
+ m_shared->setAxisZ(axis);
+}
+
+void DeclarativeBars::setBarThickness(qreal thicknessRatio)
+{
+ m_shared->setBarSpecs(GLfloat(thicknessRatio), barSpacing(), isBarSpacingRelative());
+}
+
+qreal DeclarativeBars::barThickness() const
+{
+ return m_shared->barThickness();
+}
+
+void DeclarativeBars::setBarSpacing(QSizeF spacing)
+{
+ m_shared->setBarSpecs(GLfloat(barThickness()), spacing, isBarSpacingRelative());
+}
+
+QSizeF DeclarativeBars::barSpacing() const
+{
+ return m_shared->barSpacing();
+}
+
+void DeclarativeBars::setBarSpacingRelative(bool relative)
+{
+ m_shared->setBarSpecs(GLfloat(barThickness()), barSpacing(), relative);
+}
+
+bool DeclarativeBars::isBarSpacingRelative() const
+{
+ return m_shared->isBarSpecRelative();
+}
+
+void DeclarativeBars::setBarType(QDataVis::MeshStyle style)
+{
+ QString objFile = m_shared->meshFileName();
+ bool smooth = objFile.endsWith(smoothString);
+ m_shared->setBarType(style, smooth);
+}
+
+QDataVis::MeshStyle DeclarativeBars::barType() const
+{
+ QString objFile = m_shared->meshFileName();
+ if (objFile.contains("/sphere"))
+ return QDataVis::MeshStyleSpheres;
+ else
+ return QDataVis::MeshStyleDots;
+}
+
+void DeclarativeBars::setBarSmoothingEnabled(bool enabled)
+{
+ QString objFile = m_shared->meshFileName();
+ if (objFile.endsWith(smoothString)) {
+ if (enabled)
+ return; // Already smooth; do nothing
+ else // Rip Smooth off the end
+ objFile.resize(objFile.indexOf(smoothString));
+ } else {
+ if (!enabled) // Already flat; do nothing
+ return;
+ else // Append Smooth to the end
+ objFile.append(smoothString);
+ }
+ m_shared->setMeshFileName(objFile);
+}
+
+bool DeclarativeBars::isBarSmoothingEnabled() const
+{
+ QString objFile = m_shared->meshFileName();
+ return objFile.endsWith(smoothString);
+}
+
+void DeclarativeBars::setMeshFileName(const QString &objFileName)
+{
+ m_shared->setMeshFileName(objFileName);
+}
+
+QString DeclarativeBars::meshFileName() const
+{
+ return m_shared->meshFileName();
+}
+
+void DeclarativeBars::setSelectedBarPos(const QPointF &position)
+{
+ m_shared->setSelectedBarPos(position.toPoint());
+}
+
+QPointF DeclarativeBars::selectedBarPos() const
+{
+ return QPointF(m_shared->selectedBarPos());
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualizationqml2/declarativebars_p.h b/src/datavisualizationqml2/declarativebars_p.h
new file mode 100644
index 00000000..dfbf9934
--- /dev/null
+++ b/src/datavisualizationqml2/declarativebars_p.h
@@ -0,0 +1,113 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 QtDataVisualization 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 DECLARATIVEBARS_P_H
+#define DECLARATIVEBARS_P_H
+
+#include "datavisualizationglobal_p.h"
+#include "abstractdeclarative_p.h"
+#include "bars3dcontroller_p.h"
+#include "declarativebars_p.h"
+#include "q3dvalueaxis.h"
+#include "q3dcategoryaxis.h"
+#include "qbardataproxy.h"
+
+#include <QAbstractItemModel>
+#include <QQuickItem>
+#include <QObject>
+#include <QQuickWindow>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class DeclarativeBars : public AbstractDeclarative
+{
+ Q_OBJECT
+ Q_PROPERTY(QBarDataProxy *dataProxy READ dataProxy WRITE setDataProxy)
+ Q_PROPERTY(Q3DCategoryAxis *rowAxis READ rowAxis WRITE setRowAxis)
+ Q_PROPERTY(Q3DValueAxis *valueAxis READ valueAxis WRITE setValueAxis)
+ Q_PROPERTY(Q3DCategoryAxis *columnAxis READ columnAxis WRITE setColumnAxis)
+ Q_PROPERTY(QtDataVisualization::QDataVis::MeshStyle barType READ barType WRITE setBarType)
+ Q_PROPERTY(qreal barThickness READ barThickness WRITE setBarThickness)
+ Q_PROPERTY(QSizeF barSpacing READ barSpacing WRITE setBarSpacing)
+ Q_PROPERTY(bool barSpacingRelative READ isBarSpacingRelative WRITE setBarSpacingRelative)
+ Q_PROPERTY(bool barSmoothingEnabled READ isBarSmoothingEnabled WRITE setBarSmoothingEnabled)
+ Q_PROPERTY(QString meshFileName READ meshFileName WRITE setMeshFileName)
+ Q_PROPERTY(QPointF selectedBarPos READ selectedBarPos WRITE setSelectedBarPos NOTIFY selectedBarPosChanged)
+ Q_ENUMS(QtDataVisualization::QDataVis::MeshStyle)
+
+public:
+ explicit DeclarativeBars(QQuickItem *parent = 0);
+ ~DeclarativeBars();
+
+ Q_INVOKABLE void setBarColor(const QColor &baseColor, bool uniform = true);
+
+ QBarDataProxy *dataProxy() const;
+ void setDataProxy(QBarDataProxy *dataProxy);
+
+ Q3DCategoryAxis *rowAxis() const;
+ void setRowAxis(Q3DCategoryAxis *axis);
+ Q3DValueAxis *valueAxis() const;
+ void setValueAxis(Q3DValueAxis *axis);
+ Q3DCategoryAxis *columnAxis() const;
+ void setColumnAxis(Q3DCategoryAxis *axis);
+
+ void setBarThickness(qreal thicknessRatio);
+ qreal barThickness() const;
+
+ void setBarSpacing(QSizeF spacing);
+ QSizeF barSpacing() const;
+
+ void setBarSpacingRelative(bool relative);
+ bool isBarSpacingRelative() const;
+
+ void setBarType(QDataVis::MeshStyle style);
+ QDataVis::MeshStyle barType() const;
+
+ void setBarSmoothingEnabled(bool enabled);
+ bool isBarSmoothingEnabled() const;
+
+ void setMeshFileName(const QString &objFileName);
+ QString meshFileName() const;
+
+ void setSelectedBarPos(const QPointF &position);
+ QPointF selectedBarPos() const;
+
+signals:
+ void selectedBarPosChanged(const QPointF &position);
+
+protected:
+ QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *);
+
+private:
+ Bars3DController *m_shared;
+ QSize m_initialisedSize;
+};
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3dqml2/declarativebarsrenderer.cpp b/src/datavisualizationqml2/declarativebarsrenderer.cpp
index 1ecd4003..3925e062 100644
--- a/src/datavis3dqml2/declarativebarsrenderer.cpp
+++ b/src/datavisualizationqml2/declarativebarsrenderer.cpp
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -21,16 +21,20 @@
#include <QtQuick/QQuickWindow>
#include <QtGui/QOpenGLFramebufferObject>
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
-DeclarativeBarsRenderer::DeclarativeBarsRenderer(QQuickWindow *window, Bars3dController *renderer)
+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);
+ connect(m_window, &QQuickWindow::beforeSynchronizing, this,
+ &DeclarativeBarsRenderer::synchDataToRenderer, Qt::DirectConnection);
+ connect(m_window, &QQuickWindow::beforeRendering, this,
+ &DeclarativeBarsRenderer::renderFBO, Qt::DirectConnection);
+ connect(m_barsRenderer, &Abstract3DController::needRender, m_window,
+ &QQuickWindow::update);
}
DeclarativeBarsRenderer::~DeclarativeBarsRenderer()
@@ -78,9 +82,6 @@ void DeclarativeBarsRenderer::renderFBO()
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
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavis3dqml2/declarativebarsrenderer_p.h b/src/datavisualizationqml2/declarativebarsrenderer_p.h
index 1b40d3df..3be9b911 100644
--- a/src/datavis3dqml2/declarativebarsrenderer_p.h
+++ b/src/datavisualizationqml2/declarativebarsrenderer_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -29,7 +29,7 @@
#ifndef DECLARATIVEBARSRENDERER_H
#define DECLARATIVEBARSRENDERER_H
-#include "datavis3dglobal_p.h"
+#include "datavisualizationglobal_p.h"
#include "bars3dcontroller_p.h"
#include <qsgsimpletexturenode.h>
@@ -37,14 +37,14 @@ class QOpenGLFramebufferObject;
class QSGTexture;
class QQuickWindow;
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
class DeclarativeBarsRenderer : public QObject, public QSGSimpleTextureNode
{
Q_OBJECT
public:
- DeclarativeBarsRenderer(QQuickWindow *window, Bars3dController *shared);
+ DeclarativeBarsRenderer(QQuickWindow *window, Bars3DController *shared);
~DeclarativeBarsRenderer();
public slots:
@@ -57,9 +57,9 @@ private:
QOpenGLFramebufferObject *m_fbo;
QSGTexture *m_texture;
QQuickWindow *m_window;
- Bars3dController *m_barsRenderer;
+ Bars3DController *m_barsRenderer;
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif
diff --git a/src/datavisualizationqml2/declarativescatter.cpp b/src/datavisualizationqml2/declarativescatter.cpp
new file mode 100644
index 00000000..346abec2
--- /dev/null
+++ b/src/datavisualizationqml2/declarativescatter.cpp
@@ -0,0 +1,168 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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"
+#include "theme_p.h"
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+const QString smoothString(QStringLiteral("Smooth"));
+
+DeclarativeScatter::DeclarativeScatter(QQuickItem *parent)
+ : AbstractDeclarative(parent),
+ m_shared(0),
+ m_initialisedSize(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);
+
+ // Create the shared component on the main GUI thread.
+ m_shared = new Scatter3DController(boundingRect().toRect());
+ setSharedController(m_shared);
+ m_shared->setActiveDataProxy(new QItemModelScatterDataProxy);
+}
+
+DeclarativeScatter::~DeclarativeScatter()
+{
+ delete m_shared;
+}
+
+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::setObjectColor(const QColor &baseColor, bool uniform)
+{
+ m_shared->setObjectColor(baseColor, uniform);
+}
+
+QScatterDataProxy *DeclarativeScatter::dataProxy() const
+{
+ return static_cast<QScatterDataProxy *>(m_shared->activeDataProxy());
+}
+
+void DeclarativeScatter::setDataProxy(QScatterDataProxy *dataProxy)
+{
+ m_shared->setActiveDataProxy(dataProxy);
+}
+
+Q3DValueAxis *DeclarativeScatter::axisX() const
+{
+ return static_cast<Q3DValueAxis *>(m_shared->axisX());
+}
+
+void DeclarativeScatter::setAxisX(Q3DValueAxis *axis)
+{
+ m_shared->setAxisX(axis);
+}
+
+Q3DValueAxis *DeclarativeScatter::axisY() const
+{
+ return static_cast<Q3DValueAxis *>(m_shared->axisY());
+}
+
+void DeclarativeScatter::setAxisY(Q3DValueAxis *axis)
+{
+ m_shared->setAxisY(axis);
+}
+
+Q3DValueAxis *DeclarativeScatter::axisZ() const
+{
+ return static_cast<Q3DValueAxis *>(m_shared->axisZ());
+}
+
+void DeclarativeScatter::setAxisZ(Q3DValueAxis *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() const
+{
+ QString objFile = m_shared->meshFileName();
+ if (objFile.contains("/sphere"))
+ return QDataVis::MeshStyleSpheres;
+ else
+ return QDataVis::MeshStyleDots;
+}
+
+void DeclarativeScatter::setObjectSmoothingEnabled(bool enabled)
+{
+ QString objFile = m_shared->meshFileName();
+ if (objFile.endsWith(smoothString)) {
+ if (enabled)
+ return; // Already smooth; do nothing
+ else // Rip Smooth off the end
+ objFile.resize(objFile.indexOf(smoothString));
+ } else {
+ if (!enabled) // Already flat; do nothing
+ return;
+ else // Append Smooth to the end
+ objFile.append(smoothString);
+ }
+ m_shared->setMeshFileName(objFile);
+}
+
+bool DeclarativeScatter::isObjectSmoothingEnabled() const
+{
+ QString objFile = m_shared->meshFileName();
+ return objFile.endsWith(smoothString);
+}
+
+void DeclarativeScatter::setMeshFileName(const QString &objFileName)
+{
+ m_shared->setMeshFileName(objFileName);
+}
+
+QString DeclarativeScatter::meshFileName() const
+{
+ return m_shared->meshFileName();
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualizationqml2/declarativescatter_p.h b/src/datavisualizationqml2/declarativescatter_p.h
new file mode 100644
index 00000000..cc16e770
--- /dev/null
+++ b/src/datavisualizationqml2/declarativescatter_p.h
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 QtDataVisualization 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 "datavisualizationglobal_p.h"
+#include "abstractdeclarative_p.h"
+#include "scatter3dcontroller_p.h"
+#include "declarativescatter_p.h"
+#include "q3dvalueaxis.h"
+#include "qscatterdataproxy.h"
+
+#include <QAbstractItemModel>
+#include <QQuickItem>
+#include <QObject>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class DeclarativeScatter : public AbstractDeclarative
+{
+ Q_OBJECT
+ Q_PROPERTY(QScatterDataProxy *dataProxy READ dataProxy WRITE setDataProxy)
+ Q_PROPERTY(Q3DValueAxis *axisX READ axisX WRITE setAxisX)
+ Q_PROPERTY(Q3DValueAxis *axisY READ axisY WRITE setAxisY)
+ Q_PROPERTY(Q3DValueAxis *axisZ READ axisZ WRITE setAxisZ)
+ Q_PROPERTY(QtDataVisualization::QDataVis::MeshStyle objectType READ objectType WRITE setObjectType)
+ Q_PROPERTY(bool objectSmoothingEnabled READ isObjectSmoothingEnabled WRITE setObjectSmoothingEnabled)
+ Q_PROPERTY(QString meshFileName READ meshFileName WRITE setMeshFileName)
+ Q_PROPERTY(QString itemLabelFormat READ itemLabelFormat WRITE setItemLabelFormat)
+ Q_ENUMS(QtDataVisualization::QDataVis::MeshStyle)
+
+public:
+ explicit DeclarativeScatter(QQuickItem *parent = 0);
+ ~DeclarativeScatter();
+
+ Q_INVOKABLE void setObjectColor(const QColor &baseColor, bool uniform = true);
+
+ QScatterDataProxy *dataProxy() const;
+ void setDataProxy(QScatterDataProxy *dataProxy);
+
+ Q3DValueAxis *axisX() const;
+ void setAxisX(Q3DValueAxis *axis);
+ Q3DValueAxis *axisY() const;
+ void setAxisY(Q3DValueAxis *axis);
+ Q3DValueAxis *axisZ() const;
+ void setAxisZ(Q3DValueAxis *axis);
+
+ void setObjectType(QDataVis::MeshStyle style);
+ QDataVis::MeshStyle objectType() const;
+
+ void setObjectSmoothingEnabled(bool enabled);
+ bool isObjectSmoothingEnabled() const;
+
+ void setMeshFileName(const QString &objFileName);
+ QString meshFileName() const;
+
+protected:
+ Scatter3DController *m_shared;
+ QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *);
+
+private:
+ QSize m_initialisedSize;
+};
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3dqml2/declarativescatterrenderer.cpp b/src/datavisualizationqml2/declarativescatterrenderer.cpp
index 23c59c26..39aaa22e 100644
--- a/src/datavis3dqml2/declarativescatterrenderer.cpp
+++ b/src/datavisualizationqml2/declarativescatterrenderer.cpp
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -21,7 +21,7 @@
#include <QtQuick/QQuickWindow>
#include <QtGui/QOpenGLFramebufferObject>
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
DeclarativeScatterRenderer::DeclarativeScatterRenderer(QQuickWindow *window,
Scatter3DController *renderer)
@@ -30,8 +30,12 @@ DeclarativeScatterRenderer::DeclarativeScatterRenderer(QQuickWindow *window,
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);
+ connect(m_window, &QQuickWindow::beforeSynchronizing, this,
+ &DeclarativeScatterRenderer::synchDataToRenderer, Qt::DirectConnection);
+ connect(m_window, &QQuickWindow::beforeRendering, this,
+ &DeclarativeScatterRenderer::renderFBO, Qt::DirectConnection);
+ connect(m_scatterRenderer, &Abstract3DController::needRender, m_window,
+ &QQuickWindow::update);
}
DeclarativeScatterRenderer::~DeclarativeScatterRenderer()
@@ -79,9 +83,6 @@ void DeclarativeScatterRenderer::renderFBO()
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
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavis3dqml2/declarativescatterrenderer_p.h b/src/datavisualizationqml2/declarativescatterrenderer_p.h
index 498b1d83..0bbd01ec 100644
--- a/src/datavis3dqml2/declarativescatterrenderer_p.h
+++ b/src/datavisualizationqml2/declarativescatterrenderer_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,7 +20,7 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
@@ -29,7 +29,7 @@
#ifndef DECLARATIVESCATTERRENDERER_P_H
#define DECLARATIVESCATTERRENDERER_P_H
-#include "datavis3dglobal_p.h"
+#include "datavisualizationglobal_p.h"
#include "scatter3dcontroller_p.h"
#include <qsgsimpletexturenode.h>
@@ -37,7 +37,7 @@ class QOpenGLFramebufferObject;
class QSGTexture;
class QQuickWindow;
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
class DeclarativeScatterRenderer : public QObject, public QSGSimpleTextureNode
{
@@ -60,6 +60,6 @@ private:
Scatter3DController *m_scatterRenderer;
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif
diff --git a/src/datavisualizationqml2/declarativesurface.cpp b/src/datavisualizationqml2/declarativesurface.cpp
new file mode 100644
index 00000000..8375fa53
--- /dev/null
+++ b/src/datavisualizationqml2/declarativesurface.cpp
@@ -0,0 +1,185 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 "declarativesurface_p.h"
+#include "declarativesurfacerenderer_p.h"
+#include "q3dvalueaxis.h"
+#include "qitemmodelsurfacedataproxy.h"
+#include "theme_p.h"
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+DeclarativeSurface::DeclarativeSurface(QQuickItem *parent)
+ : AbstractDeclarative(parent),
+ m_shared(0),
+ m_initialisedSize(0, 0),
+ m_gradient(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);
+
+ // Create the shared component on the main GUI thread.
+ m_shared = new Surface3DController(boundingRect().toRect());
+ setSharedController(m_shared);
+
+ QItemModelSurfaceDataProxy *proxy = new QItemModelSurfaceDataProxy;
+ m_shared->setActiveDataProxy(proxy);
+}
+
+DeclarativeSurface::~DeclarativeSurface()
+{
+ delete m_shared;
+}
+
+void DeclarativeSurface::handleGradientUpdate()
+{
+ if (m_gradient)
+ setControllerGradient(*m_gradient);
+}
+
+QSGNode *DeclarativeSurface::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<DeclarativeSurfaceRenderer *>( 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
+ DeclarativeSurfaceRenderer *node = new DeclarativeSurfaceRenderer(window(), m_shared);
+ node->setRect(boundingRect());
+ m_shared->setBoundingRect(boundingRect().toRect());
+ return node;
+}
+
+void DeclarativeSurface::setDataProxy(QSurfaceDataProxy *dataProxy)
+{
+ m_shared->setActiveDataProxy(dataProxy);
+}
+
+QSurfaceDataProxy *DeclarativeSurface::dataProxy() const
+{
+ return static_cast<QSurfaceDataProxy *>(m_shared->activeDataProxy());
+}
+
+Q3DValueAxis *DeclarativeSurface::axisX() const
+{
+ return static_cast<Q3DValueAxis *>(m_shared->axisX());
+}
+
+void DeclarativeSurface::setAxisX(Q3DValueAxis *axis)
+{
+ m_shared->setAxisX(axis);
+}
+
+Q3DValueAxis *DeclarativeSurface::axisY() const
+{
+ return static_cast<Q3DValueAxis *>(m_shared->axisY());
+}
+
+void DeclarativeSurface::setAxisY(Q3DValueAxis *axis)
+{
+ m_shared->setAxisY(axis);
+}
+
+Q3DValueAxis *DeclarativeSurface::axisZ() const
+{
+ return static_cast<Q3DValueAxis *>(m_shared->axisZ());
+}
+
+void DeclarativeSurface::setAxisZ(Q3DValueAxis *axis)
+{
+ m_shared->setAxisZ(axis);
+}
+
+void DeclarativeSurface::setSmoothSurfaceEnabled(bool enabled)
+{
+ m_shared->setSmoothSurface(enabled);
+}
+
+bool DeclarativeSurface::isSmoothSurfaceEnabled() const
+{
+ return m_shared->smoothSurface();
+}
+
+void DeclarativeSurface::setSurfaceGridEnabled(bool enabled)
+{
+ m_shared->setSurfaceGrid(enabled);
+}
+
+bool DeclarativeSurface::isSurfaceGridEnabled() const
+{
+ return m_shared->surfaceGrid();
+}
+
+void DeclarativeSurface::setGradient(ColorGradient *gradient)
+{
+ // connect new / disconnect old
+ if (gradient != m_gradient) {
+ if (m_gradient)
+ QObject::disconnect(m_gradient, 0, this, 0);
+
+ m_gradient = gradient;
+
+ if (m_gradient) {
+ QObject::connect(m_gradient, &ColorGradient::updated, this,
+ &DeclarativeSurface::handleGradientUpdate);
+ }
+ }
+
+ if (m_gradient)
+ setControllerGradient(*m_gradient);
+}
+
+ColorGradient *DeclarativeSurface::gradient() const
+{
+
+ return m_gradient;
+}
+
+void DeclarativeSurface::setControllerGradient(const ColorGradient &gradient)
+{
+ QLinearGradient newGradient;
+ QGradientStops stops;
+ QList<ColorGradientStop *> qmlstops = gradient.m_stops;
+
+ // Get sorted gradient stops
+ for (int i = 0; i < qmlstops.size(); i++) {
+ int j = 0;
+ while (j < stops.size() && stops.at(j).first < qmlstops[i]->position())
+ j++;
+ stops.insert(j, QGradientStop(qmlstops.at(i)->position(), qmlstops.at(i)->color()));
+ }
+
+ newGradient.setStops(stops);
+ m_shared->setGradient(newGradient);
+}
+
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavisualizationqml2/declarativesurface_p.h b/src/datavisualizationqml2/declarativesurface_p.h
new file mode 100644
index 00000000..6ba52146
--- /dev/null
+++ b/src/datavisualizationqml2/declarativesurface_p.h
@@ -0,0 +1,97 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 QtDataVisualization 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 DECLARATIVESURFACE_P_H
+#define DECLARATIVESURFACE_P_H
+
+#include "datavisualizationglobal_p.h"
+#include "abstractdeclarative_p.h"
+#include "surface3dcontroller_p.h"
+#include "declarativesurface_p.h"
+#include "q3dvalueaxis.h"
+#include "qsurfacedataproxy.h"
+#include "colorgradient_p.h"
+
+#include <QAbstractItemModel>
+#include <QQuickItem>
+#include <QObject>
+#include <QQuickWindow>
+
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
+
+class DeclarativeSurface : public AbstractDeclarative
+{
+ Q_OBJECT
+ Q_PROPERTY(QSurfaceDataProxy *dataProxy READ dataProxy WRITE setDataProxy)
+ Q_PROPERTY(Q3DValueAxis *axisX READ axisX WRITE setAxisX)
+ Q_PROPERTY(Q3DValueAxis *axisY READ axisY WRITE setAxisY)
+ Q_PROPERTY(Q3DValueAxis *axisZ READ axisZ WRITE setAxisZ)
+ Q_PROPERTY(bool smoothSurfaceEnabled READ isSmoothSurfaceEnabled WRITE setSmoothSurfaceEnabled)
+ Q_PROPERTY(bool surfaceGridEnabled READ isSurfaceGridEnabled WRITE setSurfaceGridEnabled)
+ Q_PROPERTY(ColorGradient *gradient READ gradient WRITE setGradient)
+
+public:
+ explicit DeclarativeSurface(QQuickItem *parent = 0);
+ ~DeclarativeSurface();
+
+ QSurfaceDataProxy *dataProxy() const;
+ void setDataProxy(QSurfaceDataProxy *dataProxy);
+
+ Q3DValueAxis *axisX() const;
+ void setAxisX(Q3DValueAxis *axis);
+ Q3DValueAxis *axisY() const;
+ void setAxisY(Q3DValueAxis *axis);
+ Q3DValueAxis *axisZ() const;
+ void setAxisZ(Q3DValueAxis *axis);
+
+ void setSmoothSurfaceEnabled(bool enabled);
+ bool isSmoothSurfaceEnabled() const;
+
+ void setSurfaceGridEnabled(bool enabled);
+ bool isSurfaceGridEnabled() const;
+
+ void setGradient(ColorGradient *gradient);
+ ColorGradient *gradient() const;
+
+protected:
+ void handleGradientUpdate();
+
+ QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *);
+
+private:
+ Surface3DController *m_shared;
+
+ void setControllerGradient(const ColorGradient &gradient);
+
+ QSize m_initialisedSize;
+ ColorGradient *m_gradient; // Not owned
+};
+
+QT_DATAVISUALIZATION_END_NAMESPACE
+
+#endif
diff --git a/src/datavis3dqml2/declarativemapsrenderer.cpp b/src/datavisualizationqml2/declarativesurfacerenderer.cpp
index 6e8dc2db..87a290ce 100644
--- a/src/datavis3dqml2/declarativemapsrenderer.cpp
+++ b/src/datavisualizationqml2/declarativesurfacerenderer.cpp
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -16,29 +16,41 @@
**
****************************************************************************/
-#include "declarativemapsrenderer_p.h"
+#include "declarativesurfacerenderer_p.h"
#include <QtQuick/QQuickWindow>
#include <QtGui/QOpenGLFramebufferObject>
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
-DeclarativeMapsRenderer::DeclarativeMapsRenderer(QQuickWindow *window, Maps3DController *renderer)
+DeclarativeSurfaceRenderer::DeclarativeSurfaceRenderer(QQuickWindow *window,
+ Surface3DController *renderer)
: m_fbo(0),
m_texture(0),
m_window(window),
- m_mapsRenderer(renderer)
+ m_surfaceRenderer(renderer)
{
- connect(m_window, SIGNAL(beforeRendering()), this, SLOT(render()), Qt::DirectConnection);
+ connect(m_window, &QQuickWindow::beforeSynchronizing, this,
+ &DeclarativeSurfaceRenderer::synchDataToRenderer, Qt::DirectConnection);
+ connect(m_window, &QQuickWindow::beforeRendering, this,
+ &DeclarativeSurfaceRenderer::renderFBO, Qt::DirectConnection);
+ connect(m_surfaceRenderer, &Abstract3DController::needRender, m_window,
+ &QQuickWindow::update);
}
-DeclarativeMapsRenderer::~DeclarativeMapsRenderer()
+DeclarativeSurfaceRenderer::~DeclarativeSurfaceRenderer()
{
delete m_texture;
delete m_fbo;
}
-void DeclarativeMapsRenderer::render()
+void DeclarativeSurfaceRenderer::synchDataToRenderer()
+{
+ m_surfaceRenderer->initializeOpenGL();
+ m_surfaceRenderer->synchDataToRenderer();
+}
+
+void DeclarativeSurfaceRenderer::renderFBO()
{
QSize size = rect().size().toSize();
@@ -62,18 +74,14 @@ void DeclarativeMapsRenderer::render()
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_surfaceRenderer->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
+QT_DATAVISUALIZATION_END_NAMESPACE
diff --git a/src/datavis3dqml2/declarativemapsrenderer_p.h b/src/datavisualizationqml2/declarativesurfacerenderer_p.h
index 755764c9..09128f59 100644
--- a/src/datavis3dqml2/declarativemapsrenderer_p.h
+++ b/src/datavisualizationqml2/declarativesurfacerenderer_p.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -20,43 +20,46 @@
// W A R N I N G
// -------------
//
-// This file is not part of the QtDataVis3D API. It exists purely as an
+// This file is not part of the QtDataVisualization 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
+#ifndef DECLARATIVESURFACERENDERER_H
+#define DECLARATIVESURFACERENDERER_H
-#include "datavis3dglobal_p.h"
-#include "maps3dcontroller_p.h"
+#include "datavisualizationglobal_p.h"
+#include "surface3dcontroller_p.h"
#include <qsgsimpletexturenode.h>
class QOpenGLFramebufferObject;
class QSGTexture;
class QQuickWindow;
-QT_DATAVIS3D_BEGIN_NAMESPACE
+QT_DATAVISUALIZATION_BEGIN_NAMESPACE
-class DeclarativeMapsRenderer : public QObject, public QSGSimpleTextureNode
+class DeclarativeSurfaceRenderer : public QObject, public QSGSimpleTextureNode
{
Q_OBJECT
public:
- DeclarativeMapsRenderer(QQuickWindow *window, Maps3DController *shared);
- ~DeclarativeMapsRenderer();
+ DeclarativeSurfaceRenderer(QQuickWindow *window, Surface3DController *shared);
+ ~DeclarativeSurfaceRenderer();
public slots:
- void render();
+ // 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;
- Maps3DController *m_mapsRenderer;
+ Surface3DController *m_surfaceRenderer;
};
-QT_DATAVIS3D_END_NAMESPACE
+QT_DATAVISUALIZATION_END_NAMESPACE
#endif
diff --git a/src/datavisualizationqml2/qmldir b/src/datavisualizationqml2/qmldir
new file mode 100644
index 00000000..1def2238
--- /dev/null
+++ b/src/datavisualizationqml2/qmldir
@@ -0,0 +1,3 @@
+module com.digia.QtDataVisualization
+plugin datavisualizationqml2
+
diff --git a/src/src.pro b/src/src.pro
index 171f9fde..33e3c009 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -1,3 +1,4 @@
TEMPLATE = subdirs
-SUBDIRS += datavis3d \
- datavis3dqml2
+CONFIG += ordered
+SUBDIRS += datavisualization \
+ datavisualizationqml2
diff --git a/sync.profile b/sync.profile
index 0f8f0093..00e85462 100644
--- a/sync.profile
+++ b/sync.profile
@@ -1,5 +1,5 @@
%modules = ( # path to module name map
- "QtDataVis3D" => "$basedir/src/datavis3d",
+ "QtDataVisualization" => "$basedir/src/datavisualization",
);
%moduleheaders = ( # restrict the module headers to those found in relative path
);
diff --git a/examples/widget/widget.pro b/tests/barstest/barstest.pro
index 2b4078a4..55fbefbd 100644
--- a/examples/widget/widget.pro
+++ b/tests/barstest/barstest.pro
@@ -1,5 +1,5 @@
-!include( ../examples.pri ) {
- error( "Couldn't find the examples.pri file!" )
+!include( ../tests.pri ) {
+ error( "Couldn't find the tests.pri file!" )
}
SOURCES += main.cpp chart.cpp
diff --git a/tests/barstest/chart.cpp b/tests/barstest/chart.cpp
new file mode 100644
index 00000000..ad27d83c
--- /dev/null
+++ b/tests/barstest/chart.cpp
@@ -0,0 +1,580 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 "chart.h"
+#include <QtDataVisualization/q3dcategoryaxis.h>
+#include <QtDataVisualization/q3dvalueaxis.h>
+#include <QtDataVisualization/qbardataproxy.h>
+#include <QtDataVisualization/q3dscene.h>
+#include <QtDataVisualization/q3dcamera.h>
+#include <QTime>
+
+QT_DATAVISUALIZATION_USE_NAMESPACE
+
+const QString celsiusString = QString(QChar(0xB0)) + "C";
+
+GraphModifier::GraphModifier(Q3DBars *barchart)
+ : m_chart(barchart),
+ m_columnCount(21),
+ m_rowCount(21),
+ m_xRotation(0.0),
+ m_yRotation(0.0),
+ m_static(true),
+ m_barSpacingX(0.1),
+ m_barSpacingZ(0.1),
+ m_fontSize(20),
+ 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),
+ m_selectedBarPos(-1, -1),
+ m_autoAdjustingAxis(new Q3DValueAxis),
+ m_fixedRangeAxis(new Q3DValueAxis),
+ m_temperatureAxis(new Q3DValueAxis),
+ m_yearAxis(new Q3DCategoryAxis),
+ m_monthAxis(new Q3DCategoryAxis),
+ m_genericRowAxis(new Q3DCategoryAxis),
+ m_genericColumnAxis(new Q3DCategoryAxis),
+ m_temperatureData(new QBarDataProxy),
+ m_genericData(new QBarDataProxy),
+ m_currentAxis(m_fixedRangeAxis)
+{
+ // Generate generic labels
+ QStringList genericColumnLabels;
+ for (int i = 0; i < 400; i++) {
+ if (i % 5)
+ genericColumnLabels << QString();
+ else
+ genericColumnLabels << QStringLiteral("Column %1").arg(i);
+ }
+
+ m_months << "January" << "February" << "March" << "April" << "May" << "June" << "July" << "August" << "September" << "October" << "November" << "December";
+ m_years << "2006" << "2007" << "2008" << "2009" << "2010" << "2011" << "2012";
+
+ QString labelFormat(QStringLiteral("%.3f"));
+ QString axisTitle("Generic Value");
+
+ m_autoAdjustingAxis->setLabelFormat(labelFormat);
+ m_autoAdjustingAxis->setTitle(axisTitle);
+ m_autoAdjustingAxis->setSegmentCount(m_segments * 2);
+ m_autoAdjustingAxis->setSubSegmentCount(1);
+ m_autoAdjustingAxis->setAutoAdjustRange(true);
+
+ m_fixedRangeAxis->setLabelFormat(labelFormat);
+ m_fixedRangeAxis->setTitle(axisTitle);
+ m_fixedRangeAxis->setSegmentCount(m_segments);
+ m_fixedRangeAxis->setSubSegmentCount(m_subSegments);
+ m_fixedRangeAxis->setRange(0.0, 100.0);
+
+ m_genericRowAxis->setTitle("Generic Row");
+ m_genericRowAxis->setRange(0, m_rowCount - 1);
+
+ m_genericColumnAxis->setTitle("Generic Column");
+ m_genericColumnAxis->setRange(0, m_columnCount - 1);
+
+ m_temperatureAxis->setTitle("Average temperature");
+ m_temperatureAxis->setSegmentCount(m_segments);
+ m_temperatureAxis->setSubSegmentCount(m_subSegments);
+ m_temperatureAxis->setRange(m_minval, m_maxval);
+ m_temperatureAxis->setLabelFormat(QString(QStringLiteral("%d ") + celsiusString));
+
+ m_yearAxis->setTitle("Year");
+
+ m_monthAxis->setTitle("Month");
+
+ m_chart->addAxis(m_autoAdjustingAxis);
+ m_chart->addAxis(m_fixedRangeAxis);
+ m_chart->addAxis(m_temperatureAxis);
+ m_chart->addAxis(m_yearAxis);
+ m_chart->addAxis(m_monthAxis);
+ m_chart->addAxis(m_genericRowAxis);
+ m_chart->addAxis(m_genericColumnAxis);
+
+ m_chart->setShadowQuality(QDataVis::ShadowQualitySoftMedium);
+
+ m_temperatureData->setItemLabelFormat(QStringLiteral("@valueTitle for @colLabel @rowLabel: @valueLabel"));
+ m_genericData->setItemLabelFormat(QStringLiteral("@valueTitle for (@rowIdx, @colIdx): @valueLabel"));
+ m_genericData->setColumnLabels(genericColumnLabels);
+
+ m_chart->addDataProxy(m_temperatureData);
+ m_chart->addDataProxy(m_genericData);
+
+ m_chart->setFont(QFont("Times Roman", 20));
+
+ resetTemperatureData();
+}
+
+GraphModifier::~GraphModifier()
+{
+ delete m_chart;
+}
+
+void GraphModifier::start()
+{
+ restart(false);
+}
+
+void GraphModifier::restart(bool dynamicData)
+{
+ m_static = !dynamicData;
+
+ if (m_static) {
+ m_chart->setActiveDataProxy(m_temperatureData);
+
+ m_chart->setTitle(QStringLiteral("Average temperatures in Oulu, Finland (2006-2012)"));
+
+ m_chart->setValueAxis(m_temperatureAxis);
+ m_chart->setRowAxis(m_yearAxis);
+ m_chart->setColumnAxis(m_monthAxis);
+
+ m_chart->setSelectionMode(QDataVis::SelectionModeItem);
+ } else {
+ m_chart->setActiveDataProxy(m_genericData);
+
+ m_chart->setTitle(QStringLiteral("Generic data"));
+
+ m_chart->setValueAxis(m_currentAxis);
+ m_chart->setRowAxis(m_genericRowAxis);
+ m_chart->setColumnAxis(m_genericColumnAxis);
+
+ m_chart->setSelectionMode(QDataVis::SelectionModeItem);
+ }
+}
+
+void GraphModifier::selectBar()
+{
+ QPoint targetBar(5, 5);
+ QPoint noSelection(-1, -1);
+ if (m_selectedBarPos != targetBar)
+ m_chart->setSelectedBarPos(targetBar);
+ else
+ m_chart->setSelectedBarPos(noSelection);
+}
+
+void GraphModifier::swapAxis()
+{
+ static int counter = 0;
+ int state = ++counter % 3;
+
+ if (state == 0) {
+ m_currentAxis = m_fixedRangeAxis;
+ qDebug() << "Fixed range axis";
+ } else if (state == 1) {
+ m_currentAxis = m_autoAdjustingAxis;
+ qDebug() << "Automatic range axis";
+ } else {
+ m_currentAxis = 0;
+ qDebug() << "default axis";
+ }
+
+ m_chart->setValueAxis(m_currentAxis);
+}
+
+void GraphModifier::releaseAxes()
+{
+ // Releases all axes - results in default axes for all dimensions.
+ // Axes reset when the graph is switched as set*Axis calls are made, which
+ // implicitly add axes.
+ m_chart->releaseAxis(m_autoAdjustingAxis);
+ m_chart->releaseAxis(m_fixedRangeAxis);
+ m_chart->releaseAxis(m_temperatureAxis);
+ m_chart->releaseAxis(m_yearAxis);
+ m_chart->releaseAxis(m_monthAxis);
+ m_chart->releaseAxis(m_genericRowAxis);
+ m_chart->releaseAxis(m_genericColumnAxis);
+}
+
+void GraphModifier::releaseProxies()
+{
+ // Releases all proxies - results in default proxy.
+ // Proxies will get readded back when graph is switched as setDataProxy call is made.
+ m_chart->releaseDataProxy(m_temperatureData);
+ m_chart->releaseDataProxy(m_genericData);
+}
+
+void GraphModifier::createMassiveArray()
+{
+ const int arrayDimension = 1000;
+ QTime timer;
+ timer.start();
+
+ QStringList genericColumnLabels;
+ for (int i = 0; i < arrayDimension; i++) {
+ if (i % 5)
+ genericColumnLabels << QString();
+ else
+ genericColumnLabels << QStringLiteral("Column %1").arg(i);
+ }
+
+ QStringList genericRowLabels;
+ for (int i = 0; i < arrayDimension; i++) {
+ if (i % 5)
+ genericRowLabels << QString();
+ else
+ genericRowLabels << QStringLiteral("Row %1").arg(i);
+ }
+
+ QBarDataArray *dataArray = new QBarDataArray;
+ dataArray->reserve(arrayDimension);
+ for (int i = 0; i < arrayDimension; i++) {
+ QBarDataRow *dataRow = new QBarDataRow(arrayDimension);
+ for (int j = 0; j < arrayDimension; j++)
+ (*dataRow)[j].setValue((qreal(i % 300 + 1) / 300.0) * qreal(rand() % 100));
+ dataArray->append(dataRow);
+ }
+
+ m_chart->activeDataProxy()->resetArray(dataArray, genericRowLabels, genericColumnLabels);
+
+ qDebug() << "Created Massive Array (" << arrayDimension << "), time:" << timer.elapsed();
+}
+
+void GraphModifier::resetTemperatureData()
+{
+
+ // Set up data
+ static const qreal temp[7][12] = {
+ {-6.7, -11.7, -9.7, 3.3, 9.2, 14.0, 16.3, 17.8, 10.2, 2.1, -2.6, -0.3}, // 2006
+ {-6.8, -13.3, 0.2, 1.5, 7.9, 13.4, 16.1, 15.5, 8.2, 5.4, -2.6, -0.8}, // 2007
+ {-4.2, -4.0, -4.6, 1.9, 7.3, 12.5, 15.0, 12.8, 7.6, 5.1, -0.9, -1.3}, // 2008
+ {-7.8, -8.8, -4.2, 0.7, 9.3, 13.2, 15.8, 15.5, 11.2, 0.6, 0.7, -8.4}, // 2009
+ {-14.4, -12.1, -7.0, 2.3, 11.0, 12.6, 18.8, 13.8, 9.4, 3.9, -5.6, -13.0}, // 2010
+ {-9.0, -15.2, -3.8, 2.6, 8.3, 15.9, 18.6, 14.9, 11.1, 5.3, 1.8, -0.2}, // 2011
+ {-8.7, -11.3, -2.3, 0.4, 7.5, 12.2, 16.4, 14.1, 9.2, 3.1, 0.3, -12.1} // 2012
+ };
+
+ // Create data rows
+ QBarDataArray *dataSet = new QBarDataArray;
+ QBarDataRow *dataRow;
+
+ dataSet->reserve(m_years.size());
+ for (int year = 0; year < m_years.size(); year++) {
+ dataRow = new QBarDataRow(m_months.size());
+ // Create data items
+ for (int month = 0; month < m_months.size(); month++) {
+ // Add data to rows
+ (*dataRow)[month].setValue(temp[year][month]);
+ }
+ // Add row to set
+ dataSet->append(dataRow);
+ }
+
+
+ // Add data to chart (chart assumes ownership)
+ m_temperatureData->resetArray(dataSet, m_years, m_months);
+}
+
+
+static int addCounter = 0;
+static int insertCounter = 0;
+static int changeCounter = 0;
+
+void GraphModifier::addRow()
+{
+ QBarDataRow *dataRow = new QBarDataRow(m_columnCount);
+ for (qreal i = 0; i < m_columnCount; i++)
+ (*dataRow)[i].setValue(((i + 1) / (qreal)m_columnCount) * (qreal)(rand() % 100));
+
+ // TODO Needs to be changed to account for data window offset once it is implemented.
+ QString label = QStringLiteral("Add %1").arg(addCounter++);
+ m_chart->activeDataProxy()->addRow(dataRow, label);
+}
+
+void GraphModifier::addRows()
+{
+ QBarDataArray dataArray;
+ QStringList labels;
+ 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->activeDataProxy()->rowCount()));
+ dataArray.append(dataRow);
+ labels.append(QStringLiteral("Add %1").arg(addCounter++));
+ }
+
+ // TODO Needs to be changed to account for data window offset once it is implemented.
+ m_chart->activeDataProxy()->addRows(dataArray, labels);
+}
+
+void GraphModifier::insertRow()
+{
+ QBarDataRow *dataRow = new QBarDataRow(m_columnCount);
+ for (qreal i = 0; i < m_columnCount; i++)
+ (*dataRow)[i].setValue(((i + 1) / (qreal)m_columnCount) * (qreal)(rand() % 100));
+
+ // TODO Needs to be changed to account for data window offset once it is implemented.
+ int row = qMax(m_selectedBarPos.x(), 0);
+ QString label = QStringLiteral("Insert %1").arg(insertCounter++);
+ m_chart->activeDataProxy()->insertRow(row, dataRow, label);
+}
+
+void GraphModifier::insertRows()
+{
+ QTime timer;
+ timer.start();
+ QBarDataArray dataArray;
+ QStringList labels;
+ 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->activeDataProxy()->rowCount()));
+ dataArray.append(dataRow);
+ labels.append(QStringLiteral("Insert %1").arg(insertCounter++));
+ }
+
+ // TODO Needs to be changed to account for data window offset once it is implemented.
+ int row = qMax(m_selectedBarPos.x(), 0);
+ m_chart->activeDataProxy()->insertRows(row, dataArray, labels);
+ qDebug() << "Inserted" << m_rowCount << "rows, time:" << timer.elapsed();
+}
+
+void GraphModifier::changeItem()
+{
+ // TODO Needs to be changed to account for data window offset once it is implemented.
+ int row = m_selectedBarPos.x();
+ int column = m_selectedBarPos.y();
+ if (row >= 0 && column >= 0) {
+ QBarDataItem item(qreal(rand() % 100));
+ m_chart->activeDataProxy()->setItem(row, column, item);
+ }
+}
+
+void GraphModifier::changeRow()
+{
+ // TODO Needs to be changed to account for data window offset once it is implemented.
+ int row = m_selectedBarPos.x();
+ if (row >= 0) {
+ QBarDataRow *newRow = new QBarDataRow(m_chart->activeDataProxy()->rowAt(row)->size());
+ for (int i = 0; i < newRow->size(); i++)
+ (*newRow)[i].setValue(qreal(rand() % 100));
+ QString label = QStringLiteral("Change %1").arg(changeCounter++);
+ m_chart->activeDataProxy()->setRow(row, newRow, label);
+ }
+}
+
+void GraphModifier::changeRows()
+{
+ // TODO Needs to be changed to account for data window offset once it is implemented.
+ int row = m_selectedBarPos.x();
+ if (row >= 0) {
+ int startRow = qMax(row - 2, 0);
+ QBarDataArray newArray;
+ QStringList labels;
+ for (int i = startRow; i <= row; i++ ) {
+ QBarDataRow *newRow = new QBarDataRow(m_chart->activeDataProxy()->rowAt(i)->size());
+ for (int j = 0; j < newRow->size(); j++)
+ (*newRow)[j].setValue(qreal(rand() % 100));
+ newArray.append(newRow);
+ labels.append(QStringLiteral("Change %1").arg(changeCounter++));
+ }
+ m_chart->activeDataProxy()->setRows(startRow, newArray, labels);
+ }
+}
+
+void GraphModifier::removeRow()
+{
+ // TODO Needs to be changed to account for data window offset once it is implemented.
+ int row = m_selectedBarPos.x();
+ if (row >= 0)
+ m_chart->activeDataProxy()->removeRows(row, 1);
+}
+
+void GraphModifier::removeRows()
+{
+ // TODO Needs to be changed to account for data window offset once it is implemented.
+ int row = m_selectedBarPos.x();
+ if (row >= 0) {
+ int startRow = qMax(row - 2, 0);
+ m_chart->activeDataProxy()->removeRows(startRow, 3);
+ }
+}
+
+void GraphModifier::changeStyle()
+{
+ static int model = 0;
+ switch (model) {
+ case 0:
+ m_chart->setBarType(QDataVis::MeshStyleCylinders, false);
+ break;
+ case 1:
+ m_chart->setBarType(QDataVis::MeshStyleCylinders, true);
+ break;
+ case 2:
+ m_chart->setBarType(QDataVis::MeshStyleCones, false);
+ break;
+ case 3:
+ m_chart->setBarType(QDataVis::MeshStyleCones, true);
+ break;
+ case 4:
+ m_chart->setBarType(QDataVis::MeshStyleBars, false);
+ break;
+ case 5:
+ m_chart->setBarType(QDataVis::MeshStyleBars, true);
+ break;
+ case 6:
+ m_chart->setBarType(QDataVis::MeshStylePyramids, false);
+ break;
+ case 7:
+ m_chart->setBarType(QDataVis::MeshStylePyramids, true);
+ break;
+ case 8:
+ m_chart->setBarType(QDataVis::MeshStyleBevelBars, false);
+ break;
+ case 9:
+ m_chart->setBarType(QDataVis::MeshStyleBevelBars, true);
+ break;
+ }
+ model++;
+ if (model > 9)
+ model = 0;
+}
+
+void GraphModifier::changePresetCamera()
+{
+ static int preset = QDataVis::CameraPresetFrontLow;
+
+ m_chart->scene()->activeCamera()->setCameraPreset((QDataVis::CameraPreset)preset);
+
+ if (++preset > QDataVis::CameraPresetDirectlyBelow)
+ preset = QDataVis::CameraPresetFrontLow;
+}
+
+void GraphModifier::changeTheme()
+{
+ static int theme = QDataVis::ThemeQt;
+
+ m_chart->setTheme((QDataVis::Theme)theme);
+
+ if (++theme > QDataVis::ThemeIsabelle)
+ theme = QDataVis::ThemeQt;
+}
+
+void GraphModifier::changeLabelStyle()
+{
+ static int style = QDataVis::LabelStyleOpaque;
+
+ m_chart->setLabelStyle((QDataVis::LabelStyle)style);
+
+ if (++style > QDataVis::LabelStyleTransparent)
+ style = QDataVis::LabelStyleOpaque;
+}
+
+void GraphModifier::changeSelectionMode()
+{
+ static int selectionMode = m_chart->selectionMode();
+
+ if (++selectionMode > QDataVis::SelectionModeSliceColumn)
+ selectionMode = QDataVis::SelectionModeNone;
+
+ m_chart->setSelectionMode((QDataVis::SelectionMode)selectionMode);
+}
+
+void GraphModifier::changeFont(const QFont &font)
+{
+ QFont newFont = font;
+ newFont.setPointSize(m_fontSize);
+ m_chart->setFont(newFont);
+}
+
+void GraphModifier::changeFontSize(int fontsize)
+{
+ m_fontSize = fontsize;
+ QFont font = m_chart->font();
+ font.setPointSize(m_fontSize);
+ m_chart->setFont(font);
+}
+
+void GraphModifier::shadowQualityUpdatedByVisual(QDataVis::ShadowQuality sq)
+{
+ int quality = int(sq);
+ // Updates the UI component to show correct shadow quality
+ emit shadowQualityChanged(quality);
+}
+
+void GraphModifier::handleSelectionChange(const QPoint &position)
+{
+ m_selectedBarPos = position;
+ qDebug() << "Selected bar position:" << position;
+}
+
+void GraphModifier::changeShadowQuality(int quality)
+{
+ QDataVis::ShadowQuality sq = QDataVis::ShadowQuality(quality);
+ m_chart->setShadowQuality(sq);
+ emit shadowQualityChanged(quality);
+}
+
+void GraphModifier::setBackgroundEnabled(int enabled)
+{
+ m_chart->setBackgroundVisible((bool)enabled);
+}
+
+void GraphModifier::setGridEnabled(int enabled)
+{
+ m_chart->setGridVisible((bool)enabled);
+}
+
+void GraphModifier::rotateX(int rotation)
+{
+ m_xRotation = rotation;
+ m_chart->scene()->activeCamera()->setCameraPosition(m_xRotation, m_yRotation);
+}
+
+void GraphModifier::rotateY(int rotation)
+{
+ m_yRotation = rotation;
+ m_chart->scene()->activeCamera()->setCameraPosition(m_xRotation, m_yRotation);
+}
+
+void GraphModifier::setSpecsRatio(int barwidth)
+{
+ m_chart->setBarThickness((qreal)barwidth / 30.0);
+}
+
+void GraphModifier::setSpacingSpecsX(int spacing)
+{
+ m_barSpacingX = (qreal)spacing / 100.0;
+ m_chart->setBarSpacing(QSizeF(m_barSpacingX, m_barSpacingZ));
+}
+
+void GraphModifier::setSpacingSpecsZ(int spacing)
+{
+ m_barSpacingZ = (qreal)spacing / 100.0;
+ m_chart->setBarSpacing(QSizeF(m_barSpacingX, m_barSpacingZ));
+}
+
+void GraphModifier::setSampleCountX(int samples)
+{
+ m_columnCount = samples;
+ m_genericColumnAxis->setRange(m_genericRowAxis->min(), m_genericRowAxis->min() + samples - 1);
+}
+
+void GraphModifier::setSampleCountZ(int samples)
+{
+ m_rowCount = samples;
+ m_genericRowAxis->setRange(m_genericColumnAxis->min(), m_genericColumnAxis->min() + samples - 1);
+}
+
+void GraphModifier::setMinX(int min)
+{
+ m_genericRowAxis->setRange(min, min + m_rowCount - 1);
+}
+
+void GraphModifier::setMinZ(int min)
+{
+ m_genericColumnAxis->setRange(min, min + m_rowCount - 1);
+}
diff --git a/examples/widget/chart.h b/tests/barstest/chart.h
index 67280e13..e4e96ffb 100644
--- a/examples/widget/chart.h
+++ b/tests/barstest/chart.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -19,24 +19,27 @@
#ifndef CHARTMODIFIER_H
#define CHARTMODIFIER_H
-#include <QtDataVis3D/q3dbars.h>
+#include <QtDataVisualization/q3dbars.h>
#include <QFont>
#include <QDebug>
#include <QStringList>
+#include <QPointer>
-using namespace QtDataVis3D;
+using namespace QtDataVisualization;
-class ChartModifier : public QObject
+class GraphModifier : public QObject
{
Q_OBJECT
public:
- explicit ChartModifier(Q3DBars *barchart);
- ~ChartModifier();
+ explicit GraphModifier(Q3DBars *barchart);
+ ~GraphModifier();
- void addDataSet();
+ void resetTemperatureData();
void addRow();
void addRows();
+ void insertRow();
+ void insertRows();
void changeItem();
void changeRow();
void changeRows();
@@ -45,7 +48,7 @@ public:
void changeStyle();
void changePresetCamera();
void changeTheme();
- void changeTransparency();
+ void changeLabelStyle();
void changeSelectionMode();
void changeFont(const QFont &font);
void changeFontSize(int fontsize);
@@ -53,18 +56,26 @@ public:
void rotateY(int rotation);
void setBackgroundEnabled(int enabled);
void setGridEnabled(int enabled);
- void setSpecsX(int barwidth);
+ void setSpecsRatio(int barwidth);
void setSpecsZ(int bardepth);
void setSpacingSpecsX(int spacing);
void setSpacingSpecsZ(int spacing);
void setSampleCountX(int samples);
void setSampleCountZ(int samples);
+ void setMinX(int min);
+ void setMinZ(int min);
void start();
void restart(bool dynamicData);
+ void selectBar();
+ void swapAxis();
+ void releaseAxes();
+ void releaseProxies();
+ void createMassiveArray();
public slots:
void changeShadowQuality(int quality);
void shadowQualityUpdatedByVisual(QDataVis::ShadowQuality shadowQuality);
+ void handleSelectionChange(const QPoint &position);
signals:
void shadowQualityChanged(int quality);
@@ -73,20 +84,29 @@ private:
Q3DBars *m_chart;
int m_columnCount;
int m_rowCount;
- float m_xRotation;
- float m_yRotation;
+ qreal m_xRotation;
+ qreal m_yRotation;
bool m_static;
- float m_barWidth;
- float m_barDepth;
- float m_barSpacingX;
- float m_barSpacingZ;
+ qreal m_barSpacingX;
+ qreal m_barSpacingZ;
int m_fontSize;
int m_segments;
int m_subSegments;
qreal m_minval;
qreal m_maxval;
- QStringList m_genericRowLabels;
- QStringList m_genericColumnLabels;
+ QStringList m_months;
+ QStringList m_years;
+ QPoint m_selectedBarPos;
+ Q3DValueAxis *m_autoAdjustingAxis;
+ Q3DValueAxis *m_fixedRangeAxis;
+ Q3DValueAxis *m_temperatureAxis;
+ Q3DCategoryAxis *m_yearAxis;
+ Q3DCategoryAxis *m_monthAxis;
+ Q3DCategoryAxis *m_genericRowAxis;
+ Q3DCategoryAxis *m_genericColumnAxis;
+ QBarDataProxy *m_temperatureData;
+ QBarDataProxy *m_genericData;
+ Q3DValueAxis *m_currentAxis;
};
#endif
diff --git a/examples/widget/main.cpp b/tests/barstest/main.cpp
index 47892484..850561a7 100644
--- a/examples/widget/main.cpp
+++ b/tests/barstest/main.cpp
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -37,6 +37,7 @@ int main(int argc, char **argv)
QWidget *widget = new QWidget;
QHBoxLayout *hLayout = new QHBoxLayout(widget);
QVBoxLayout *vLayout = new QVBoxLayout();
+ QVBoxLayout *vLayout2 = new QVBoxLayout();
Q3DBars *widgetchart = new Q3DBars();
QSize screenSize = widgetchart->screen()->size();
@@ -51,14 +52,23 @@ int main(int argc, char **argv)
hLayout->addWidget(container, 1);
hLayout->addLayout(vLayout);
+ hLayout->addLayout(vLayout2);
- QPushButton *dataButton = new QPushButton(widget);
- dataButton->setText(QStringLiteral("Insert a row of data"));
- dataButton->setEnabled(false);
+ QPushButton *addDataButton = new QPushButton(widget);
+ addDataButton->setText(QStringLiteral("Add a row of data"));
+ addDataButton->setEnabled(false);
- QPushButton *multiDataButton = new QPushButton(widget);
- multiDataButton->setText(QStringLiteral("Insert many rows of data"));
- multiDataButton->setEnabled(false);
+ QPushButton *addMultiDataButton = new QPushButton(widget);
+ addMultiDataButton->setText(QStringLiteral("Add many rows of data"));
+ addMultiDataButton->setEnabled(false);
+
+ QPushButton *insertDataButton = new QPushButton(widget);
+ insertDataButton->setText(QStringLiteral("Insert a row of data"));
+ insertDataButton->setEnabled(false);
+
+ QPushButton *insertMultiDataButton = new QPushButton(widget);
+ insertMultiDataButton->setText(QStringLiteral("Insert many rows of data"));
+ insertMultiDataButton->setEnabled(false);
QPushButton *changeSingleDataButton = new QPushButton(widget);
changeSingleDataButton->setText(QStringLiteral("Change selected bar value"));
@@ -77,9 +87,13 @@ int main(int argc, char **argv)
removeRowButton->setEnabled(false);
QPushButton *removeRowsButton = new QPushButton(widget);
- removeRowsButton->setText(QStringLiteral("remove three rows from selected"));
+ removeRowsButton->setText(QStringLiteral("Remove three rows from selected"));
removeRowsButton->setEnabled(false);
+ QPushButton *massiveArrayButton = new QPushButton(widget);
+ massiveArrayButton->setText(QStringLiteral("Create massive array"));
+ massiveArrayButton->setEnabled(false);
+
QPushButton *themeButton = new QPushButton(widget);
themeButton->setText(QStringLiteral("Change theme"));
@@ -95,6 +109,21 @@ int main(int argc, char **argv)
QPushButton *selectionButton = new QPushButton(widget);
selectionButton->setText(QStringLiteral("Change selection mode"));
+ QPushButton *setSelectedBarButton = new QPushButton(widget);
+ setSelectedBarButton->setText(QStringLiteral("Select/deselect bar at (5,5)"));
+
+ QPushButton *swapAxisButton = new QPushButton(widget);
+ swapAxisButton->setText(QStringLiteral("Swap value axis"));
+ swapAxisButton->setEnabled(false);
+
+ QPushButton *releaseAxesButton = new QPushButton(widget);
+ releaseAxesButton->setText(QStringLiteral("Release all axes"));
+ releaseAxesButton->setEnabled(true);
+
+ QPushButton *releaseProxiesButton = new QPushButton(widget);
+ releaseProxiesButton->setText(QStringLiteral("Release all proxies"));
+ releaseProxiesButton->setEnabled(true);
+
QCheckBox *backgroundCheckBox = new QCheckBox(widget);
backgroundCheckBox->setText(QStringLiteral("Show background"));
backgroundCheckBox->setChecked(true);
@@ -123,16 +152,11 @@ int main(int argc, char **argv)
rotationSliderY->setMaximum(90);
rotationSliderY->setEnabled(false);
- QSlider *sizeSliderX = new QSlider(Qt::Horizontal, widget);
- sizeSliderX->setTickInterval(1);
- sizeSliderX->setMinimum(1);
- sizeSliderX->setValue(100);
- sizeSliderX->setMaximum(100);
- QSlider *sizeSliderZ = new QSlider(Qt::Horizontal, widget);
- sizeSliderZ->setTickInterval(1);
- sizeSliderZ->setMinimum(1);
- sizeSliderZ->setValue(100);
- sizeSliderZ->setMaximum(100);
+ QSlider *ratioSlider = new QSlider(Qt::Horizontal, widget);
+ ratioSlider->setTickInterval(1);
+ ratioSlider->setMinimum(10);
+ ratioSlider->setValue(30);
+ ratioSlider->setMaximum(100);
QSlider *spacingSliderX = new QSlider(Qt::Horizontal, widget);
spacingSliderX->setTickInterval(1);
@@ -147,17 +171,30 @@ int main(int argc, char **argv)
QSlider *sampleSliderX = new QSlider(Qt::Horizontal, widget);
sampleSliderX->setTickInterval(1);
- sampleSliderX->setMinimum(2);
- sampleSliderX->setValue(10);
+ sampleSliderX->setMinimum(1);
+ sampleSliderX->setValue(21);
sampleSliderX->setMaximum(200);
sampleSliderX->setEnabled(false);
QSlider *sampleSliderZ = new QSlider(Qt::Horizontal, widget);
sampleSliderZ->setTickInterval(1);
- sampleSliderZ->setMinimum(2);
- sampleSliderZ->setValue(10);
+ sampleSliderZ->setMinimum(1);
+ sampleSliderZ->setValue(21);
sampleSliderZ->setMaximum(200);
sampleSliderZ->setEnabled(false);
+ QSlider *minSliderX = new QSlider(Qt::Horizontal, widget);
+ minSliderX->setTickInterval(1);
+ minSliderX->setMinimum(0);
+ minSliderX->setValue(0);
+ minSliderX->setMaximum(200);
+ minSliderX->setEnabled(false);
+ QSlider *minSliderZ = new QSlider(Qt::Horizontal, widget);
+ minSliderZ->setTickInterval(1);
+ minSliderZ->setMinimum(0);
+ minSliderZ->setValue(0);
+ minSliderZ->setMaximum(200);
+ minSliderZ->setEnabled(false);
+
QSlider *fontSizeSlider = new QSlider(Qt::Horizontal, widget);
fontSizeSlider->setTickInterval(1);
fontSizeSlider->setMinimum(1);
@@ -171,96 +208,125 @@ int main(int argc, char **argv)
shadowQuality->addItem(QStringLiteral("Low"));
shadowQuality->addItem(QStringLiteral("Medium"));
shadowQuality->addItem(QStringLiteral("High"));
- shadowQuality->setCurrentIndex(1);
-
- vLayout->addWidget(staticCheckBox, 0, Qt::AlignTop);
- vLayout->addWidget(rotationCheckBox, 0, Qt::AlignTop);
- vLayout->addWidget(rotationSliderX, 0, Qt::AlignTop);
- vLayout->addWidget(rotationSliderY, 0, Qt::AlignTop);
- vLayout->addWidget(new QLabel(QStringLiteral("Adjust relative bar size")));
- vLayout->addWidget(sizeSliderX, 0, Qt::AlignTop);
- vLayout->addWidget(sizeSliderZ, 0, Qt::AlignTop);
- vLayout->addWidget(new QLabel(QStringLiteral("Adjust relative bar spacing")));
- vLayout->addWidget(spacingSliderX, 0, Qt::AlignTop);
- vLayout->addWidget(spacingSliderZ, 0, Qt::AlignTop);
- vLayout->addWidget(new QLabel(QStringLiteral("Adjust sample count")));
- vLayout->addWidget(sampleSliderX, 0, Qt::AlignTop);
- vLayout->addWidget(sampleSliderZ, 1, Qt::AlignTop);
- vLayout->addWidget(dataButton, 0, Qt::AlignTop);
- vLayout->addWidget(multiDataButton, 0, Qt::AlignTop);
+ shadowQuality->addItem(QStringLiteral("Low Soft"));
+ shadowQuality->addItem(QStringLiteral("Medium Soft"));
+ shadowQuality->addItem(QStringLiteral("High Soft"));
+ shadowQuality->setCurrentIndex(5);
+
+ vLayout->addWidget(addDataButton, 0, Qt::AlignTop);
+ vLayout->addWidget(addMultiDataButton, 0, Qt::AlignTop);
+ vLayout->addWidget(insertDataButton, 0, Qt::AlignTop);
+ vLayout->addWidget(insertMultiDataButton, 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(massiveArrayButton, 0, Qt::AlignTop);
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(selectionButton, 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, 0, Qt::AlignTop);
+ vLayout->addWidget(setSelectedBarButton, 0, Qt::AlignTop);
+ vLayout->addWidget(swapAxisButton, 0, Qt::AlignTop);
+ vLayout->addWidget(releaseAxesButton, 0, Qt::AlignTop);
+ vLayout->addWidget(releaseProxiesButton, 1, Qt::AlignTop);
+
+ vLayout2->addWidget(staticCheckBox, 0, Qt::AlignTop);
+ vLayout2->addWidget(rotationCheckBox, 0, Qt::AlignTop);
+ vLayout2->addWidget(rotationSliderX, 0, Qt::AlignTop);
+ vLayout2->addWidget(rotationSliderY, 0, Qt::AlignTop);
+ vLayout2->addWidget(new QLabel(QStringLiteral("Adjust relative bar size")), 0, Qt::AlignTop);
+ vLayout2->addWidget(ratioSlider, 0, Qt::AlignTop);
+ vLayout2->addWidget(new QLabel(QStringLiteral("Adjust relative bar spacing")), 0, Qt::AlignTop);
+ vLayout2->addWidget(spacingSliderX, 0, Qt::AlignTop);
+ vLayout2->addWidget(spacingSliderZ, 0, Qt::AlignTop);
+ vLayout2->addWidget(new QLabel(QStringLiteral("Adjust sample count")), 0, Qt::AlignTop);
+ vLayout2->addWidget(sampleSliderX, 0, Qt::AlignTop);
+ vLayout2->addWidget(sampleSliderZ, 0, Qt::AlignTop);
+ vLayout2->addWidget(new QLabel(QStringLiteral("Adjust data window minimums")), 0, Qt::AlignTop);
+ vLayout2->addWidget(minSliderX, 0, Qt::AlignTop);
+ vLayout2->addWidget(minSliderZ, 0, Qt::AlignTop);
+ vLayout2->addWidget(backgroundCheckBox, 0, Qt::AlignTop);
+ vLayout2->addWidget(gridCheckBox, 0, Qt::AlignTop);
+ vLayout2->addWidget(new QLabel(QStringLiteral("Adjust shadow quality")), 0, Qt::AlignTop);
+ vLayout2->addWidget(shadowQuality, 0, Qt::AlignTop);
+ vLayout2->addWidget(new QLabel(QStringLiteral("Change font")), 0, Qt::AlignTop);
+ vLayout2->addWidget(fontList, 0, Qt::AlignTop);
+ vLayout2->addWidget(new QLabel(QStringLiteral("Adjust font size")), 0, Qt::AlignTop);
+ vLayout2->addWidget(fontSizeSlider, 1, Qt::AlignTop);
// TODO: Add example for setMeshFileName
widget->show();
- ChartModifier *modifier = new ChartModifier(widgetchart);
+ GraphModifier *modifier = new GraphModifier(widgetchart);
- QObject::connect(rotationSliderX, &QSlider::valueChanged, modifier, &ChartModifier::rotateX);
- QObject::connect(rotationSliderY, &QSlider::valueChanged, modifier, &ChartModifier::rotateY);
+ QObject::connect(rotationSliderX, &QSlider::valueChanged, modifier, &GraphModifier::rotateX);
+ QObject::connect(rotationSliderY, &QSlider::valueChanged, modifier, &GraphModifier::rotateY);
- QObject::connect(sizeSliderX, &QSlider::valueChanged, modifier, &ChartModifier::setSpecsX);
- QObject::connect(sizeSliderZ, &QSlider::valueChanged, modifier, &ChartModifier::setSpecsZ);
+ QObject::connect(ratioSlider, &QSlider::valueChanged, modifier, &GraphModifier::setSpecsRatio);
QObject::connect(spacingSliderX, &QSlider::valueChanged, modifier,
- &ChartModifier::setSpacingSpecsX);
+ &GraphModifier::setSpacingSpecsX);
QObject::connect(spacingSliderZ, &QSlider::valueChanged, modifier,
- &ChartModifier::setSpacingSpecsZ);
+ &GraphModifier::setSpacingSpecsZ);
QObject::connect(sampleSliderX, &QSlider::valueChanged, modifier,
- &ChartModifier::setSampleCountX);
+ &GraphModifier::setSampleCountX);
QObject::connect(sampleSliderZ, &QSlider::valueChanged, modifier,
- &ChartModifier::setSampleCountZ);
+ &GraphModifier::setSampleCountZ);
+ QObject::connect(minSliderX, &QSlider::valueChanged, modifier,
+ &GraphModifier::setMinX);
+ QObject::connect(minSliderZ, &QSlider::valueChanged, modifier,
+ &GraphModifier::setMinZ);
QObject::connect(shadowQuality, SIGNAL(currentIndexChanged(int)), modifier,
SLOT(changeShadowQuality(int)));
- QObject::connect(modifier, &ChartModifier::shadowQualityChanged, shadowQuality,
+ QObject::connect(modifier, &GraphModifier::shadowQualityChanged, shadowQuality,
&QComboBox::setCurrentIndex);
QObject::connect(widgetchart, &Q3DBars::shadowQualityChanged, modifier,
- &ChartModifier::shadowQualityUpdatedByVisual);
+ &GraphModifier::shadowQualityUpdatedByVisual);
+ QObject::connect(widgetchart, &Q3DBars::selectedBarPosChanged, modifier,
+ &GraphModifier::handleSelectionChange);
QObject::connect(fontSizeSlider, &QSlider::valueChanged, modifier,
- &ChartModifier::changeFontSize);
+ &GraphModifier::changeFontSize);
- QObject::connect(styleButton, &QPushButton::clicked, modifier, &ChartModifier::changeStyle);
+ QObject::connect(styleButton, &QPushButton::clicked, modifier, &GraphModifier::changeStyle);
QObject::connect(cameraButton, &QPushButton::clicked, modifier,
- &ChartModifier::changePresetCamera);
- QObject::connect(themeButton, &QPushButton::clicked, modifier, &ChartModifier::changeTheme);
+ &GraphModifier::changePresetCamera);
+ QObject::connect(themeButton, &QPushButton::clicked, modifier, &GraphModifier::changeTheme);
QObject::connect(labelButton, &QPushButton::clicked, modifier,
- &ChartModifier::changeTransparency);
- 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);
+ &GraphModifier::changeStyle);
+ QObject::connect(addDataButton, &QPushButton::clicked, modifier, &GraphModifier::addRow);
+ QObject::connect(addMultiDataButton, &QPushButton::clicked, modifier, &GraphModifier::addRows);
+ QObject::connect(insertDataButton, &QPushButton::clicked, modifier, &GraphModifier::insertRow);
+ QObject::connect(insertMultiDataButton, &QPushButton::clicked, modifier, &GraphModifier::insertRows);
+ QObject::connect(changeSingleDataButton, &QPushButton::clicked, modifier, &GraphModifier::changeItem);
+ QObject::connect(changeRowButton, &QPushButton::clicked, modifier, &GraphModifier::changeRow);
+ QObject::connect(changeRowsButton, &QPushButton::clicked, modifier, &GraphModifier::changeRows);
+ QObject::connect(removeRowButton, &QPushButton::clicked, modifier, &GraphModifier::removeRow);
+ QObject::connect(removeRowsButton, &QPushButton::clicked, modifier, &GraphModifier::removeRows);
+ QObject::connect(massiveArrayButton, &QPushButton::clicked, modifier, &GraphModifier::createMassiveArray);
QObject::connect(selectionButton, &QPushButton::clicked, modifier,
- &ChartModifier::changeSelectionMode);
+ &GraphModifier::changeSelectionMode);
+ QObject::connect(setSelectedBarButton, &QPushButton::clicked, modifier,
+ &GraphModifier::selectBar);
+ QObject::connect(swapAxisButton, &QPushButton::clicked, modifier,
+ &GraphModifier::swapAxis);
+ QObject::connect(releaseAxesButton, &QPushButton::clicked, modifier,
+ &GraphModifier::releaseAxes);
+ QObject::connect(releaseProxiesButton, &QPushButton::clicked, modifier,
+ &GraphModifier::releaseProxies);
QObject::connect(fontList, &QFontComboBox::currentFontChanged, modifier,
- &ChartModifier::changeFont);
+ &GraphModifier::changeFont);
QObject::connect(backgroundCheckBox, &QCheckBox::stateChanged, modifier,
- &ChartModifier::setBackgroundEnabled);
+ &GraphModifier::setBackgroundEnabled);
QObject::connect(gridCheckBox, &QCheckBox::stateChanged, modifier,
- &ChartModifier::setGridEnabled);
+ &GraphModifier::setGridEnabled);
QObject::connect(rotationCheckBox, &QCheckBox::stateChanged, rotationSliderX,
&QSlider::setEnabled);
@@ -271,9 +337,13 @@ int main(int argc, char **argv)
QObject::connect(rotationCheckBox, &QCheckBox::stateChanged, rotationSliderY,
&QSlider::setValue);
- QObject::connect(staticCheckBox, &QCheckBox::stateChanged, dataButton,
+ QObject::connect(staticCheckBox, &QCheckBox::stateChanged, addDataButton,
+ &QPushButton::setEnabled);
+ QObject::connect(staticCheckBox, &QCheckBox::stateChanged, addMultiDataButton,
&QPushButton::setEnabled);
- QObject::connect(staticCheckBox, &QCheckBox::stateChanged, multiDataButton,
+ QObject::connect(staticCheckBox, &QCheckBox::stateChanged, insertDataButton,
+ &QPushButton::setEnabled);
+ QObject::connect(staticCheckBox, &QCheckBox::stateChanged, insertMultiDataButton,
&QPushButton::setEnabled);
QObject::connect(staticCheckBox, &QCheckBox::stateChanged, changeSingleDataButton,
&QPushButton::setEnabled);
@@ -285,11 +355,19 @@ int main(int argc, char **argv)
&QPushButton::setEnabled);
QObject::connect(staticCheckBox, &QCheckBox::stateChanged, removeRowsButton,
&QPushButton::setEnabled);
+ QObject::connect(staticCheckBox, &QCheckBox::stateChanged, massiveArrayButton,
+ &QPushButton::setEnabled);
QObject::connect(staticCheckBox, &QCheckBox::stateChanged, sampleSliderX,
&QSlider::setEnabled);
QObject::connect(staticCheckBox, &QCheckBox::stateChanged, sampleSliderZ,
&QSlider::setEnabled);
- QObject::connect(staticCheckBox, &QCheckBox::stateChanged, modifier, &ChartModifier::restart);
+ QObject::connect(staticCheckBox, &QCheckBox::stateChanged, minSliderX,
+ &QSlider::setEnabled);
+ QObject::connect(staticCheckBox, &QCheckBox::stateChanged, minSliderZ,
+ &QSlider::setEnabled);
+ QObject::connect(staticCheckBox, &QCheckBox::stateChanged, swapAxisButton,
+ &QSlider::setEnabled);
+ QObject::connect(staticCheckBox, &QCheckBox::stateChanged, modifier, &GraphModifier::restart);
modifier->start();
diff --git a/tests/kinectsurface/QtKinectWrapper/00openni_notes.txt b/tests/kinectsurface/QtKinectWrapper/00openni_notes.txt
new file mode 100644
index 00000000..2487a1ff
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/00openni_notes.txt
@@ -0,0 +1,2 @@
+OpenNI/Include: contains includes of OpenNI-1.5.4
+
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/ARC/XnOSARC.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/ARC/XnOSARC.h
new file mode 100644
index 00000000..0a183724
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/ARC/XnOSARC.h
@@ -0,0 +1,166 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef _XN_OSLINUX_X86_H_
+#define _XN_OSLINUX_X86_H_
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include <sys/types.h>
+#include <stdarg.h>
+#include <time.h>
+#include <stdio.h>
+
+//---------------------------------------------------------------------------
+// Files
+//---------------------------------------------------------------------------
+/** A generic handle type. */
+typedef void* XN_HANDLE;
+
+/** A file handle type. */
+typedef FILE* XN_FILE_HANDLE;
+
+/** The value of an invalid file handle. */
+#define XN_INVALID_FILE_HANDLE NULL
+
+/** A string that specifies the current directory. */
+#define XN_FILE_LOCAL_DIR "./"
+
+/** The file directory separator. */
+#define XN_FILE_DIR_SEP "/"
+
+/** The file extension separator. */
+#define XN_FILE_EXT_SEP "."
+
+/** The file "all" wildcard. */
+#define XN_FILE_ALL_WILDCARD "*"
+
+/** The newline separation string. */
+#define XN_NEW_LINE_SEP "\n"
+
+//---------------------------------------------------------------------------
+// INI Files
+//---------------------------------------------------------------------------
+/** A string that specifies the extension of INI files. */
+#define XN_INI_FILE_EXT "ini"
+
+/** The maximum allowed INI string length (in bytes). */
+// Note: This must always be big enough to contain a 32-bit number!
+#define XN_INI_MAX_LEN 256
+
+//---------------------------------------------------------------------------
+// Shared Libraries
+//---------------------------------------------------------------------------
+/** A shared library handle type. */
+typedef void* XN_LIB_HANDLE;
+
+/** A string that specifies the prefix of shared library files. */
+#define XN_SHARED_LIBRARY_PREFIX "lib"
+
+/** A string that specifies the postfix of shared library files. */
+#define XN_SHARED_LIBRARY_POSTFIX ".so"
+
+//---------------------------------------------------------------------------
+// Threads
+//---------------------------------------------------------------------------
+/** A Xiron thread type. */
+typedef int XN_THREAD_HANDLE;
+
+/** A Xiron thread ID. */
+typedef int XN_THREAD_ID;
+
+/** A Xiron process ID. */
+typedef int XN_PROCESS_ID;
+
+/** The thread entry point function prototype. */
+typedef void* (*XN_THREAD_PROC_PROTO)(void* arg);
+
+/** The thread entry point function definition. */
+#define XN_THREAD_PROC void*
+
+/** The thread return function. */
+#define XN_THREAD_PROC_RETURN(ret) return((void*)ret)
+
+/** The thread passable data pointer type. */
+typedef void* XN_THREAD_PARAM;
+
+//---------------------------------------------------------------------------
+// Time Outs
+//---------------------------------------------------------------------------
+/** The mutex lock infinite timeout. */
+#define XN_WAIT_INFINITE 0xFFFFFFFF
+
+//---------------------------------------------------------------------------
+// Mutex
+//---------------------------------------------------------------------------
+/** A Xiron mutex type. */
+struct XnMutex;
+typedef struct XnMutex* XN_MUTEX_HANDLE;
+
+//---------------------------------------------------------------------------
+// Critical Sections
+//---------------------------------------------------------------------------
+/** A Xiron critical sections type. */
+typedef XN_MUTEX_HANDLE XN_CRITICAL_SECTION_HANDLE;
+
+//---------------------------------------------------------------------------
+// Events
+//---------------------------------------------------------------------------
+/** A Xiron event type. */
+struct _XnEvent;
+typedef struct _XnEvent *XN_EVENT_HANDLE;
+
+//---------------------------------------------------------------------------
+// Semaphores
+//---------------------------------------------------------------------------
+/** A Xiron event type. */
+struct _XnSemaphore;
+typedef struct _XnSemaphore *XN_SEMAPHORE_HANDLE;
+
+//---------------------------------------------------------------------------
+// Timer
+//---------------------------------------------------------------------------
+/** The Xiron OS timer structure. */
+typedef struct XnOSTimer
+{
+ XnUInt64 nStartTick;
+} XnOSTimer;
+
+//---------------------------------------------------------------------------
+// Network
+//---------------------------------------------------------------------------
+/** The network host name and port separator. */
+#define XN_NETWORK_HOST_PORT_SEP ":"
+
+//---------------------------------------------------------------------------
+// Swaps
+//---------------------------------------------------------------------------
+#define XN_PREPARE_VAR16_IN_BUFFER(var) (var)
+#define XN_PREPARE_VAR32_IN_BUFFER(var) (var)
+#define XN_PREPARE_VAR64_IN_BUFFER(var) (var)
+#define XN_PREPARE_VAR_FLOAT_IN_BUFFER(var) (var)
+
+#define XN_IMPLEMENT_OS \
+ printf("Not Implemented: %s at %s(%u)\n", __FUNCTION__, __FILE__, __LINE__); \
+ _brk();
+
+#endif //_XN_OSLINUX_X86_H_
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/ARC/XnPlatformARC.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/ARC/XnPlatformARC.h
new file mode 100644
index 00000000..01bebafe
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/ARC/XnPlatformARC.h
@@ -0,0 +1,194 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef _XN_PLATFORM_ARC_H_
+#define _XN_PLATFORM_ARC_H_
+
+//---------------------------------------------------------------------------
+// Prerequisites
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+//---------------------------------------------------------------------------
+// Platform Basic Definition
+//---------------------------------------------------------------------------
+#define XN_PLATFORM XN_PLATFORM_ARC
+#define XN_PLATFORM_STRING "ARC"
+
+//---------------------------------------------------------------------------
+// Platform Capabilities
+//---------------------------------------------------------------------------
+#define XN_PLATFORM_ENDIAN_TYPE XN_PLATFORM_IS_LITTLE_ENDIAN
+#define XN_PLATFORM_VAARGS_TYPE XN_PLATFORM_USE_ARC_VAARGS_STYLE
+#define XN_PLATFORM_SUPPORTS_DYNAMIC_LIBS 0
+
+//---------------------------------------------------------------------------
+// Basic Types
+//---------------------------------------------------------------------------
+/** Boolean TRUE/FALSE type. */
+typedef unsigned int XnBool;
+
+/** Signed character for strings. */
+typedef char XnChar;
+/** Unsigned character for strings. */
+typedef unsigned char XnUChar;
+
+/** Signed wide character for strings. */
+typedef wchar_t XnWChar;
+
+/** 8-bit signed integer. */
+typedef signed char XnInt8;
+/** 8-bit unsigned integer. */
+typedef unsigned char XnUInt8;
+
+/** 16-bit signed integer. */
+typedef short XnInt16;
+/** 16-bit unsigned integer. */
+typedef unsigned short XnUInt16;
+
+/** 32-bit signed integer. */
+typedef int XnInt32;
+/** 32-bit unsigned integer. */
+typedef unsigned int XnUInt32;
+
+/** 64-bit signed integer. */
+typedef long long XnInt64;
+/** 64-bit unsigned integer. */
+typedef unsigned long long XnUInt64;
+
+/** natural signed integer. */
+typedef int XnInt;
+/** natural unsigned integer. */
+typedef unsigned int XnUInt;
+
+/** Float (32bit) */
+typedef float XnFloat;
+/** Double (64bit) */
+typedef double XnDouble;
+
+/** Far procedures type (for shared libraries functions). */
+typedef void (*XnFarProc)(void *);
+
+/** Size type. */
+typedef size_t XnSizeT;
+
+/** Max unsigned 8-bit value */
+#define XN_MAX_UINT8 255
+/** Max unsigned 16-bit value */
+#define XN_MAX_UINT16 65535
+/** Max unsigned 32-bit value */
+#define XN_MAX_UINT32 4294967295UL
+/** Max unsigned 64-bit value */
+#define XN_MAX_UINT64 18446744073709551615ULL
+
+/** Min signed 8-bit value */
+#define XN_MIN_INT8 -128
+/** Min signed 16-bit value */
+#define XN_MIN_INT16 -32768
+/** Min signed 32-bit value */
+#define XN_MIN_INT32 -2147483648
+/** Min signed 64-bit value */
+#define XN_MIN_INT64 -9223372036854775808LL
+
+/** Max signed 8-bit value */
+#define XN_MAX_INT8 127
+/** Max signed 16-bit value */
+#define XN_MAX_INT16 32767
+/** Max signed 32-bit value */
+#define XN_MAX_INT32 2147483647
+/** Max signed 64-bit value */
+#define XN_MAX_INT64 9223372036854775807LL
+
+//---------------------------------------------------------------------------
+// Memory
+//---------------------------------------------------------------------------
+/** The default memory alignment. */
+#define XN_DEFAULT_MEM_ALIGN 16
+
+/** The thread static declarator (using TLS). */
+#define XN_THREAD_STATIC __declspec(thread)
+
+//---------------------------------------------------------------------------
+// Files
+//---------------------------------------------------------------------------
+/** The maximum allowed file path size (in bytes). */
+#define XN_FILE_MAX_PATH 256
+
+//---------------------------------------------------------------------------
+// Call back
+//---------------------------------------------------------------------------
+/** The std call type. */
+#define XN_STDCALL __stdcall
+
+/** The call back calling convention. */
+#define XN_CALLBACK_TYPE
+
+/** The C and C++ calling convension. */
+#define XN_C_DECL
+
+//---------------------------------------------------------------------------
+// Macros
+//---------------------------------------------------------------------------
+/** Returns the date and time at compile time. */
+#define XN_TIMESTAMP __DATE__ " " __TIME__
+
+/** Converts n into a pre-processor string. */
+#define XN_STRINGIFY(n) XN_STRINGIFY_HELPER(n)
+#define XN_STRINGIFY_HELPER(n) #n
+
+/** Asserts an expression, only on Debug build. */
+#define XN_ASSERT(x)
+
+//---------------------------------------------------------------------------
+// API Export/Import Macros
+//---------------------------------------------------------------------------
+/** Indicates an exported shared library function. */
+#define XN_API_EXPORT
+
+/** Indicates an imported shared library function. */
+#define XN_API_IMPORT
+
+/** Indicates a deprecated function */
+#define XN_API_DEPRECATED(msg)
+
+#define XN_DEPRECATED_WARNING_IDS
+#define XN_HIDES_PARENT_METHOD_WARNING_ID
+#define XN_CONDITION_IS_CONST_WARNING_ID
+#define XN_INHERITS_VIA_DOMINANCE_WARNING_ID
+#define XN_UNALIGNED_ADDRESS_WARNING_ID
+#define XN_STRUCT_PADDED_WARNING_ID
+
+#define XN_PRAGMA_START_DISABLED_WARNING_SECTION(warnings)
+#define XN_PRAGMA_STOP_DISABLED_WARNING_SECTION
+
+/** Declares a global shared library export function. */
+#define XN_API_EXPORT_INIT()
+
+#endif //_XN_PLATFORM_ARC_H_
+
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/Android-Arm/XnPlatformAndroid-Arm.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/Android-Arm/XnPlatformAndroid-Arm.h
new file mode 100644
index 00000000..948a47ea
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/Android-Arm/XnPlatformAndroid-Arm.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef _XN_PLATFORM_ANDROID_ARM_H_
+#define _XN_PLATFORM_ANDROID_ARM_H_
+
+// Start with Linux-x86, and override what's different
+#include "../Linux-x86/XnPlatformLinux-x86.h"
+
+//---------------------------------------------------------------------------
+// Platform Basic Definition
+//---------------------------------------------------------------------------
+#undef XN_PLATFORM
+#undef XN_PLATFORM_STRING
+
+#define XN_PLATFORM XN_PLATFORM_ANDROID_ARM
+#define XN_PLATFORM_STRING "Android-Arm"
+
+#define XN_PLATFORM_HAS_NO_TIMED_OPS
+#define XN_PLATFORM_HAS_NO_CLOCK_GETTIME
+#define XN_PLATFORM_HAS_NO_SCHED_PARAM
+#define XN_PLATFORM_HAS_BUILTIN_SEMUN
+
+#define XN_PLATFORM_LINUX_NO_GLIBC
+#define XN_PLATFORM_LINUX_NO_SYSV
+#define XN_PLATFORM_LINUX_NO_GLOB
+#define XN_PLATFORM_LINUX_NO_POSIX_MEMALIGN
+#define XN_PLATFORM_LINUX_NO_SHM
+#define XN_PLATFORM_LINUX_NO_PTHREAD_CANCEL
+
+#endif //_XN_PLATFORM_LINUX_ARM_H_
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/IXnNodeAllocator.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/IXnNodeAllocator.h
new file mode 100644
index 00000000..1571e881
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/IXnNodeAllocator.h
@@ -0,0 +1,53 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef _ININODEALLOCATOR_H
+#define _ININODEALLOCATOR_H
+
+//---------------------------------------------------------------------------
+// Types
+//---------------------------------------------------------------------------
+class XnNode;
+
+/**
+ * Node Allocator - general interface for node allocation and deallocation.
+ */
+class INiNodeAllocator
+{
+public:
+ virtual ~INiNodeAllocator() {}
+
+ /**
+ * Allocate a new XnNode
+ *
+ * @return NULL if allocating a new node failed
+ */
+ virtual XnNode *Allocate() = 0;
+
+ /**
+ * Release an XnNode
+ *
+ * @param pNode [in] The node to deallocate
+ */
+ virtual void Deallocate(XnNode *pNode) = 0;
+};
+
+#endif //_ININODEALLOCATOR_H
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/Linux-Arm/XnPlatformLinux-Arm.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/Linux-Arm/XnPlatformLinux-Arm.h
new file mode 100644
index 00000000..877e4e72
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/Linux-Arm/XnPlatformLinux-Arm.h
@@ -0,0 +1,37 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef _XN_PLATFORM_LINUX_ARM_H_
+#define _XN_PLATFORM_LINUX_ARM_H_
+
+// Start with Linux-x86, and override what's different
+#include "../Linux-x86/XnPlatformLinux-x86.h"
+
+//---------------------------------------------------------------------------
+// Platform Basic Definition
+//---------------------------------------------------------------------------
+#undef XN_PLATFORM
+#undef XN_PLATFORM_STRING
+#define XN_PLATFORM XN_PLATFORM_LINUX_ARM
+#define XN_PLATFORM_STRING "Linux-Arm"
+
+#endif //_XN_PLATFORM_LINUX_ARM_H_
+
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/Linux-x86/XnOSLinux-x86.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/Linux-x86/XnOSLinux-x86.h
new file mode 100644
index 00000000..0cbd12fc
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/Linux-x86/XnOSLinux-x86.h
@@ -0,0 +1,165 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef _XN_OSLINUX_X86_H_
+#define _XN_OSLINUX_X86_H_
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include <sys/types.h>
+#include <stdarg.h>
+#include <time.h>
+#include <pthread.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+//---------------------------------------------------------------------------
+// Files
+//---------------------------------------------------------------------------
+/** A generic handle type. */
+typedef void* XN_HANDLE;
+
+/** A file handle type. */
+typedef XnInt XN_FILE_HANDLE;
+
+/** The value of an invalid file handle. */
+#define XN_INVALID_FILE_HANDLE -1
+
+/** A string that specifies the current directory. */
+#define XN_FILE_LOCAL_DIR "./"
+
+/** The file directory separator. */
+#define XN_FILE_DIR_SEP "/"
+
+/** The file extension separator. */
+#define XN_FILE_EXT_SEP "."
+
+/** The file "all" wildcard. */
+#define XN_FILE_ALL_WILDCARD "*"
+
+/** The newline separation string. */
+#define XN_NEW_LINE_SEP "\n"
+
+//---------------------------------------------------------------------------
+// INI Files
+//---------------------------------------------------------------------------
+/** A string that specifies the extension of INI files. */
+#define XN_INI_FILE_EXT "ini"
+
+/** The maximum allowed INI string length (in bytes). */
+// Note: This must always be big enough to contain a 32-bit number!
+#define XN_INI_MAX_LEN 256
+
+//---------------------------------------------------------------------------
+// Shared Libraries
+//---------------------------------------------------------------------------
+/** A shared library handle type. */
+typedef void* XN_LIB_HANDLE;
+
+/** A string that specifies the prefix of shared library files. */
+#define XN_SHARED_LIBRARY_PREFIX "lib"
+
+/** A string that specifies the postfix of shared library files. */
+#define XN_SHARED_LIBRARY_POSTFIX ".so"
+
+//---------------------------------------------------------------------------
+// Threads
+//---------------------------------------------------------------------------
+/** A Xiron thread type. */
+typedef pthread_t* XN_THREAD_HANDLE;
+
+/** A Xiron thread ID. */
+typedef pthread_t XN_THREAD_ID;
+
+/** A Xiron process ID. */
+typedef pid_t XN_PROCESS_ID;
+
+/** The thread entry point function prototype. */
+typedef void* (*XN_THREAD_PROC_PROTO)(void* arg);
+
+/** The thread entry point function definition. */
+#define XN_THREAD_PROC void*
+
+/** The thread return function. */
+#define XN_THREAD_PROC_RETURN(ret) return((void*)ret)
+
+/** The thread passable data pointer type. */
+typedef void* XN_THREAD_PARAM;
+
+//---------------------------------------------------------------------------
+// Time Outs
+//---------------------------------------------------------------------------
+/** The mutex lock infinite timeout. */
+#define XN_WAIT_INFINITE 0xFFFFFFFF
+
+//---------------------------------------------------------------------------
+// Mutex
+//---------------------------------------------------------------------------
+/** A Xiron mutex type. */
+struct XnMutex;
+typedef struct XnMutex* XN_MUTEX_HANDLE;
+
+//---------------------------------------------------------------------------
+// Critical Sections
+//---------------------------------------------------------------------------
+/** A Xiron critical sections type. */
+typedef XN_MUTEX_HANDLE XN_CRITICAL_SECTION_HANDLE;
+
+//---------------------------------------------------------------------------
+// Events
+//---------------------------------------------------------------------------
+/** A Xiron event type. */
+struct _XnEvent;
+typedef struct _XnEvent _XnEvent, *XN_EVENT_HANDLE ;
+
+//---------------------------------------------------------------------------
+// Semaphores
+//---------------------------------------------------------------------------
+/** A Xiron event type. */
+struct _XnSemaphore;
+typedef struct _XnSemaphore *XN_SEMAPHORE_HANDLE;
+
+//---------------------------------------------------------------------------
+// Timer
+//---------------------------------------------------------------------------
+/** The Xiron OS timer structure. */
+typedef struct XnOSTimer
+{
+ struct timespec tStartTime;
+ XnBool bHighRes;
+} XnOSTimer;
+
+//---------------------------------------------------------------------------
+// Network
+//---------------------------------------------------------------------------
+/** The network host name and port separator. */
+#define XN_NETWORK_HOST_PORT_SEP ":"
+
+//---------------------------------------------------------------------------
+// Swaps
+//---------------------------------------------------------------------------
+#define XN_PREPARE_VAR16_IN_BUFFER(var) (var)
+#define XN_PREPARE_VAR32_IN_BUFFER(var) (var)
+#define XN_PREPARE_VAR64_IN_BUFFER(var) (var)
+#define XN_PREPARE_VAR_FLOAT_IN_BUFFER(var) (var)
+
+#endif //_XN_OSLINUX_X86_H_
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/Linux-x86/XnPlatformLinux-x86.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/Linux-x86/XnPlatformLinux-x86.h
new file mode 100644
index 00000000..1b91a388
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/Linux-x86/XnPlatformLinux-x86.h
@@ -0,0 +1,195 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef _XN_PLATFORM_LINUX_X86_H_
+#define _XN_PLATFORM_LINUX_X86_H_
+
+//---------------------------------------------------------------------------
+// Prerequisites
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <limits.h>
+
+//---------------------------------------------------------------------------
+// Platform Basic Definition
+//---------------------------------------------------------------------------
+#define XN_PLATFORM XN_PLATFORM_LINUX_X86
+#define XN_PLATFORM_STRING "Linux-x86"
+
+//---------------------------------------------------------------------------
+// Platform Capabilities
+//---------------------------------------------------------------------------
+#define XN_PLATFORM_ENDIAN_TYPE XN_PLATFORM_IS_LITTLE_ENDIAN
+#define XN_PLATFORM_VAARGS_TYPE XN_PLATFORM_USE_GCC_VAARGS_STYLE
+#define XN_PLATFORM_SUPPORTS_DYNAMIC_LIBS 1
+
+//---------------------------------------------------------------------------
+// Basic Types
+//---------------------------------------------------------------------------
+/** Boolean TRUE/FALSE type. */
+typedef unsigned int XnBool;
+
+/** Signed character for strings. */
+typedef char XnChar;
+/** Unsigned character for strings. */
+typedef unsigned char XnUChar;
+
+/** Signed wide character for strings. */
+typedef wchar_t XnWChar;
+
+/** 8-bit signed integer. */
+typedef signed char XnInt8;
+/** 8-bit unsigned integer. */
+typedef unsigned char XnUInt8;
+
+/** 16-bit signed integer. */
+typedef short XnInt16;
+/** 16-bit unsigned integer. */
+typedef unsigned short XnUInt16;
+
+/** 32-bit signed integer. */
+typedef int XnInt32;
+/** 32-bit unsigned integer. */
+typedef unsigned int XnUInt32;
+
+/** 64-bit signed integer. */
+typedef long long XnInt64;
+/** 64-bit unsigned integer. */
+typedef unsigned long long XnUInt64;
+
+/** natural signed integer. */
+typedef int XnInt;
+/** natural unsigned integer. */
+typedef unsigned int XnUInt;
+
+/** Float (32bit) */
+typedef float XnFloat;
+/** Double (64bit) */
+typedef double XnDouble;
+
+/** Far procedures type (for shared libraries functions). */
+typedef void (*XnFarProc)(void *);
+
+/** Size type. */
+typedef size_t XnSizeT;
+
+/** Max unsigned 8-bit value */
+#define XN_MAX_UINT8 UCHAR_MAX
+/** Max unsigned 16-bit value */
+#define XN_MAX_UINT16 USHRT_MAX
+/** Max unsigned 32-bit value */
+#define XN_MAX_UINT32 UINT_MAX
+/** Max unsigned 64-bit value */
+#define XN_MAX_UINT64 ULLONG_MAX
+
+/** Min signed 8-bit value */
+#define XN_MIN_INT8 SCHAR_MIN
+/** Min signed 16-bit value */
+#define XN_MIN_INT16 SHRT_MIN
+/** Min signed 32-bit value */
+#define XN_MIN_INT32 INT_MIN
+/** Min signed 64-bit value */
+#define XN_MIN_INT64 LLONG_MIN
+
+/** Max signed 8-bit value */
+#define XN_MAX_INT8 SCHAR_MAX
+/** Max signed 16-bit value */
+#define XN_MAX_INT16 SHRT_MAX
+/** Max signed 32-bit value */
+#define XN_MAX_INT32 INT_MAX
+/** Max signed 64-bit value */
+#define XN_MAX_INT64 LLONG_MAX
+
+//---------------------------------------------------------------------------
+// Memory
+//---------------------------------------------------------------------------
+/** The default memory alignment. */
+#define XN_DEFAULT_MEM_ALIGN 16
+
+/** The thread static declarator (using TLS). */
+#define XN_THREAD_STATIC __thread
+
+//---------------------------------------------------------------------------
+// Files
+//---------------------------------------------------------------------------
+/** The maximum allowed file path size (in bytes). */
+#define XN_FILE_MAX_PATH 256
+
+//---------------------------------------------------------------------------
+// Call back
+//---------------------------------------------------------------------------
+/** The std call type. */
+#define XN_STDCALL __stdcall
+
+/** The call back calling convention. */
+#define XN_CALLBACK_TYPE
+
+/** The C and C++ calling convension. */
+#define XN_C_DECL
+
+//---------------------------------------------------------------------------
+// Macros
+//---------------------------------------------------------------------------
+/** Returns the date and time at compile time. */
+#define XN_TIMESTAMP __DATE__ " " __TIME__
+
+/** Converts n into a pre-processor string. */
+#define XN_STRINGIFY(n) XN_STRINGIFY_HELPER(n)
+#define XN_STRINGIFY_HELPER(n) #n
+
+/** Asserts an expression, only on Debug build. */
+#define XN_ASSERT(x)
+
+//---------------------------------------------------------------------------
+// API Export/Import Macros
+//---------------------------------------------------------------------------
+/** Indicates an exported shared library function. */
+#define XN_API_EXPORT __attribute__ ((visibility("default")))
+
+/** Indicates an imported shared library function. */
+#define XN_API_IMPORT
+
+/** Indicates a deprecated function */
+#define XN_API_DEPRECATED(msg) __attribute__((warning("This function is deprecated: " msg)))
+
+#define XN_DEPRECATED_WARNING_IDS
+#define XN_HIDES_PARENT_METHOD_WARNING_ID
+#define XN_CONDITION_IS_CONST_WARNING_ID
+#define XN_INHERITS_VIA_DOMINANCE_WARNING_ID
+#define XN_UNALIGNED_ADDRESS_WARNING_ID
+#define XN_STRUCT_PADDED_WARNING_ID
+
+#define XN_PRAGMA_START_DISABLED_WARNING_SECTION(warnings)
+#define XN_PRAGMA_STOP_DISABLED_WARNING_SECTION
+
+/** Declares a global shared library export function. */
+#define XN_API_EXPORT_INIT()
+
+#endif //_XN_PLATFORM_LINUX_X86_H_
+
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/MacOSX/XnPlatformMacOSX.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/MacOSX/XnPlatformMacOSX.h
new file mode 100644
index 00000000..cb46dd7d
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/MacOSX/XnPlatformMacOSX.h
@@ -0,0 +1,43 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef _XN_PLATFORM_MACOSX_H_
+#define _XN_PLATFORM_MACOSX_H_
+
+// Start with Linux-x86, and override what's different
+#include "../Linux-x86/XnPlatformLinux-x86.h"
+
+#include <sys/time.h>
+
+#undef XN_PLATFORM
+#undef XN_PLATFORM_STRING
+#define XN_PLATFORM XN_PLATFORM_MACOSX
+#define XN_PLATFORM_STRING "MacOSX"
+
+#define XN_PLATFORM_HAS_NO_TIMED_OPS
+#define XN_PLATFORM_HAS_NO_CLOCK_GETTIME
+#define XN_PLATFORM_HAS_NO_SCHED_PARAM
+#define XN_PLATFORM_HAS_BUILTIN_SEMUN
+
+#undef XN_THREAD_STATIC
+#define XN_THREAD_STATIC
+
+#endif //_XN_PLATFORM_MACOSX_H_
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/Win32/XnOSWin32.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/Win32/XnOSWin32.h
new file mode 100644
index 00000000..c821744d
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/Win32/XnOSWin32.h
@@ -0,0 +1,157 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef __XN_OS_WIN32_H__
+#define __XN_OS_WIN32_H__
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include <XnPlatform.h>
+
+//---------------------------------------------------------------------------
+// Files
+//---------------------------------------------------------------------------
+/** A generic handle type. */
+typedef HANDLE XN_HANDLE;
+
+/** A file handle type. */
+typedef HANDLE XN_FILE_HANDLE;
+
+/** The value of an invalid file handle. */
+#define XN_INVALID_FILE_HANDLE INVALID_HANDLE_VALUE
+
+/** A string that specifies the current directory. */
+#define XN_FILE_LOCAL_DIR ".\\"
+
+/** The file directory separator. */
+#define XN_FILE_DIR_SEP "\\"
+
+/** The file extension separator. */
+#define XN_FILE_EXT_SEP "."
+
+/** The file "all" wildcard. */
+#define XN_FILE_ALL_WILDCARD "*"
+
+/** The newline separation string. */
+#define XN_NEW_LINE_SEP "\r\n"
+
+//---------------------------------------------------------------------------
+// INI Files
+//---------------------------------------------------------------------------
+/** A string that specifies the extension of INI files. */
+#define XN_INI_FILE_EXT "ini"
+
+/** The maximum allowed INI string length (in bytes). */
+// Note: This must always be big enough to contain a 32-bit number!
+#define XN_INI_MAX_LEN 256
+
+//---------------------------------------------------------------------------
+// Shared Libraries
+//---------------------------------------------------------------------------
+/** A shared library handle type. */
+typedef HMODULE XN_LIB_HANDLE;
+
+/** A string that specifies the prefix of shared library files. */
+#define XN_SHARED_LIBRARY_PREFIX ""
+
+/** A string that specifies the postfix of shared library files. */
+#define XN_SHARED_LIBRARY_POSTFIX ".dll"
+
+//---------------------------------------------------------------------------
+// Threads
+//---------------------------------------------------------------------------
+/** A Xiron thread type. */
+typedef HANDLE XN_THREAD_HANDLE;
+
+/** A Xiron thread ID. */
+typedef DWORD XN_THREAD_ID;
+
+/** A Xiron process ID. */
+typedef DWORD XN_PROCESS_ID;
+
+/** The thread entry point function prototype. */
+typedef LPTHREAD_START_ROUTINE XN_THREAD_PROC_PROTO;
+
+/** The thread entry point function definition. */
+#define XN_THREAD_PROC DWORD WINAPI
+
+/** The thread return function. */
+#define XN_THREAD_PROC_RETURN(ret) return(ret)
+
+/** The thread passable data pointer type. */
+typedef LPVOID XN_THREAD_PARAM;
+
+//---------------------------------------------------------------------------
+// Time Outs
+//---------------------------------------------------------------------------
+/** The mutex lock infinite timeout. */
+#define XN_WAIT_INFINITE INFINITE
+
+//---------------------------------------------------------------------------
+// Mutex
+//---------------------------------------------------------------------------
+/** A Xiron mutex type. */
+typedef HANDLE XN_MUTEX_HANDLE;
+
+//---------------------------------------------------------------------------
+// Critical Sections
+//---------------------------------------------------------------------------
+/** A Xiron critical sections type. */
+typedef CRITICAL_SECTION* XN_CRITICAL_SECTION_HANDLE;
+
+//---------------------------------------------------------------------------
+// Events
+//---------------------------------------------------------------------------
+/** A Xiron event type. */
+typedef HANDLE XN_EVENT_HANDLE;
+
+//---------------------------------------------------------------------------
+// Semaphores
+//---------------------------------------------------------------------------
+/** A Xiron semaphore type. */
+typedef HANDLE XN_SEMAPHORE_HANDLE;
+
+//---------------------------------------------------------------------------
+// Timer
+//---------------------------------------------------------------------------
+/** The Xiron OS timer structure. */
+typedef struct XnOSTimer
+{
+ XnDouble dTicksPerTimeUnit;
+ LARGE_INTEGER nStartTick;
+} XnOSTimer;
+
+//---------------------------------------------------------------------------
+// Network
+//---------------------------------------------------------------------------
+/** The network host name and port separator. */
+#define XN_NETWORK_HOST_PORT_SEP ":"
+
+//---------------------------------------------------------------------------
+// Swaps
+//---------------------------------------------------------------------------
+#define XN_PREPARE_VAR16_IN_BUFFER(var) (var)
+#define XN_PREPARE_VAR32_IN_BUFFER(var) (var)
+#define XN_PREPARE_VAR64_IN_BUFFER(var) (var)
+#define XN_PREPARE_VAR_FLOAT_IN_BUFFER(var) (var)
+
+#endif //__XN_OS_WIN32_H__ \ No newline at end of file
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/Win32/XnPlatformWin32.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/Win32/XnPlatformWin32.h
new file mode 100644
index 00000000..efc26ead
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/Win32/XnPlatformWin32.h
@@ -0,0 +1,255 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef _XN_PLATFORM_WIN32_H_
+#define _XN_PLATFORM_WIN32_H_
+
+//---------------------------------------------------------------------------
+// Prerequisites
+//---------------------------------------------------------------------------
+#ifndef WINVER // Allow use of features specific to Windows XP or later
+ #define WINVER 0x0501
+#endif
+#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later
+ #define _WIN32_WINNT 0x0501
+#endif
+#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later
+ #define _WIN32_WINDOWS 0x0410
+#endif
+#ifndef _WIN32_IE // Allow use of features specific to IE 6.0 or later
+ #define _WIN32_IE 0x0600
+#endif
+#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
+
+// Undeprecate CRT functions
+#ifndef _CRT_SECURE_NO_DEPRECATE
+ #define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include <windows.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <malloc.h>
+#include <io.h>
+#include <time.h>
+#include <assert.h>
+#include <float.h>
+#include <crtdbg.h>
+
+//---------------------------------------------------------------------------
+// Platform Basic Definition
+//---------------------------------------------------------------------------
+#define XN_PLATFORM XN_PLATFORM_WIN32
+#define XN_PLATFORM_STRING "Win32"
+
+//---------------------------------------------------------------------------
+// Platform Capabilities
+//---------------------------------------------------------------------------
+#define XN_PLATFORM_ENDIAN_TYPE XN_PLATFORM_IS_LITTLE_ENDIAN
+
+#if _MSC_VER < 1400 // Before VS2005 there was no support for the vaargs macro...
+ #define XN_PLATFORM_VAARGS_TYPE XN_PLATFORM_USE_NO_VAARGS
+#else
+ #define XN_PLATFORM_VAARGS_TYPE XN_PLATFORM_USE_WIN32_VAARGS_STYLE
+#endif
+
+#define XN_PLATFORM_SUPPORTS_DYNAMIC_LIBS 1
+
+//---------------------------------------------------------------------------
+// Basic Types
+//---------------------------------------------------------------------------
+/** Boolean TRUE/FALSE type. */
+typedef BOOL XnBool;
+
+/** Signed character for strings. */
+typedef char XnChar;
+/** Unsigned character for strings. */
+typedef unsigned char XnUChar;
+
+/** Signed wide character for strings. */
+typedef wchar_t XnWChar;
+
+/** 8-bit signed integer. */
+typedef signed char XnInt8;
+/** 8-bit unsigned integer. */
+typedef unsigned char XnUInt8;
+
+/** 16-bit signed integer. */
+typedef short XnInt16;
+/** 16-bit unsigned integer. */
+typedef unsigned short XnUInt16;
+
+/** 32-bit signed integer. */
+typedef int XnInt32;
+/** 32-bit unsigned integer. */
+typedef unsigned int XnUInt32;
+
+/** 64-bit signed integer. */
+typedef __int64 XnInt64;
+/** 64-bit unsigned integer. */
+typedef unsigned __int64 XnUInt64;
+
+/** natural signed integer. */
+typedef int XnInt;
+/** natural unsigned integer. */
+typedef unsigned int XnUInt;
+
+/** Float (32bit) */
+typedef float XnFloat;
+/** Double (64bit) */
+typedef double XnDouble;
+
+/** Far procedures type (for shared libraries functions). */
+typedef FARPROC XnFarProc;
+
+/** Size type. */
+typedef size_t XnSizeT;
+
+/** Max unsigned 8-bit value */
+#define XN_MAX_UINT8 _UI8_MAX
+/** Max unsigned 16-bit value */
+#define XN_MAX_UINT16 _UI16_MAX
+/** Max unsigned 32-bit value */
+#define XN_MAX_UINT32 _UI32_MAX
+/** Max unsigned 64-bit value */
+#define XN_MAX_UINT64 _UI64_MAX
+
+/** Min signed 8-bit value */
+#define XN_MIN_INT8 _I8_MIN
+/** Min signed 16-bit value */
+#define XN_MIN_INT16 _I16_MIN
+/** Min signed 32-bit value */
+#define XN_MIN_INT32 _I32_MIN
+/** Min signed 64-bit value */
+#define XN_MIN_INT64 _I64_MIN
+
+/** Max signed 8-bit value */
+#define XN_MAX_INT8 _I8_MAX
+/** Max signed 16-bit value */
+#define XN_MAX_INT16 _I16_MAX
+/** Max signed 32-bit value */
+#define XN_MAX_INT32 _I32_MAX
+/** Max signed 64-bit value */
+#define XN_MAX_INT64 _I64_MAX
+
+/** Min double value */
+#define XN_MIN_DOUBLE DBL_MIN
+/** Max double value */
+#define XN_MAX_DOUBLE DBL_MAX
+
+//---------------------------------------------------------------------------
+// Memory
+//---------------------------------------------------------------------------
+/** The default memory alignment. */
+#define XN_DEFAULT_MEM_ALIGN 16
+
+/** The thread static declarator (using TLS). */
+#define XN_THREAD_STATIC __declspec(thread)
+
+//---------------------------------------------------------------------------
+// Files
+//---------------------------------------------------------------------------
+/** The maximum allowed file path size (in bytes). */
+#define XN_FILE_MAX_PATH MAX_PATH
+
+//---------------------------------------------------------------------------
+// Call backs
+//---------------------------------------------------------------------------
+/** The std call type. */
+#define XN_STDCALL __stdcall
+
+/** The call back calling convention. */
+#define XN_CALLBACK_TYPE XN_STDCALL
+
+/** The C and C++ calling convension. */
+#define XN_C_DECL __cdecl
+
+//---------------------------------------------------------------------------
+// Macros
+//---------------------------------------------------------------------------
+/** Returns the date and time at compile time. */
+#define XN_TIMESTAMP __DATE__ " " __TIME__
+
+/** Converts n into a pre-processor string. */
+#define XN_STRINGIFY(n) XN_STRINGIFY_HELPER(n)
+#define XN_STRINGIFY_HELPER(n) #n
+
+/** Asserts an expression, only on Debug build. */
+#define XN_ASSERT(x) _ASSERTE(x)
+
+//---------------------------------------------------------------------------
+// API Export/Import Macros
+//---------------------------------------------------------------------------
+/** Indicates an exported shared library function. */
+#define XN_API_EXPORT __declspec(dllexport)
+
+/** Indicates an imported shared library function. */
+#define XN_API_IMPORT __declspec(dllimport)
+
+/** Indicates a deprecated function */
+#if _MSC_VER < 1400 // Before VS2005 there was no support for declspec deprecated...
+ #define XN_API_DEPRECATED(msg)
+#else
+ #define XN_API_DEPRECATED(msg) __declspec(deprecated(msg))
+#endif
+
+#ifdef __INTEL_COMPILER
+ #define XN_DEPRECATED_WARNING_IDS 1786
+ #define XN_HIDES_PARENT_METHOD_WARNING_ID 1125
+ #define XN_CONDITION_IS_CONST_WARNING_ID
+ #define XN_INHERITS_VIA_DOMINANCE_WARNING_ID
+ #define XN_UNALIGNED_ADDRESS_WARNING_ID
+ #define XN_STRUCT_PADDED_WARNING_ID
+#else
+ #define XN_DEPRECATED_WARNING_IDS 4995 4996
+ #define XN_HIDES_PARENT_METHOD_WARNING_ID
+ #define XN_CONDITION_IS_CONST_WARNING_ID 4127
+ #define XN_INHERITS_VIA_DOMINANCE_WARNING_ID 4250
+ #define XN_UNALIGNED_ADDRESS_WARNING_ID 4366
+ #define XN_STRUCT_PADDED_WARNING_ID 4324
+#endif
+
+#define XN_PRAGMA_START_DISABLED_WARNING_SECTION(warnings) \
+ __pragma(warning(push)) \
+ __pragma(warning(disable: warnings))
+
+#define XN_PRAGMA_STOP_DISABLED_WARNING_SECTION \
+ __pragma(warning(pop))
+
+/** Declares a global shared library export function. */
+#define XN_API_EXPORT_INIT() \
+ BOOL APIENTRY DllMain (HMODULE /*hModule*/, DWORD nReasonForCall, LPVOID /*lpReserved*/) \
+ { \
+ switch (nReasonForCall) \
+ { \
+ case DLL_PROCESS_ATTACH: \
+ case DLL_THREAD_ATTACH: \
+ case DLL_THREAD_DETACH: \
+ case DLL_PROCESS_DETACH: \
+ break; \
+ } \
+ return TRUE; \
+ }
+
+#endif //_XN_PLATFORM_WIN32_H_
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/Win32/usb100.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/Win32/usb100.h
new file mode 100644
index 00000000..63c87b58
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/Win32/usb100.h
@@ -0,0 +1,270 @@
+#ifndef __USB100_H__
+#define __USB100_H__
+
+
+#include <PSHPACK1.H>
+
+
+//bmRequest.Dir
+#define BMREQUEST_HOST_TO_DEVICE 0
+#define BMREQUEST_DEVICE_TO_HOST 1
+
+//bmRequest.Type
+#define BMREQUEST_STANDARD 0
+#define BMREQUEST_CLASS 1
+#define BMREQUEST_VENDOR 2
+
+//bmRequest.Recipient
+#define BMREQUEST_TO_DEVICE 0
+#define BMREQUEST_TO_INTERFACE 1
+#define BMREQUEST_TO_ENDPOINT 2
+#define BMREQUEST_TO_OTHER 3
+
+
+#define MAXIMUM_USB_STRING_LENGTH 255
+
+// values for the bits returned by the USB GET_STATUS command
+#define USB_GETSTATUS_SELF_POWERED 0x01
+#define USB_GETSTATUS_REMOTE_WAKEUP_ENABLED 0x02
+
+
+#define USB_DEVICE_DESCRIPTOR_TYPE 0x01
+#define USB_CONFIGURATION_DESCRIPTOR_TYPE 0x02
+#define USB_STRING_DESCRIPTOR_TYPE 0x03
+#define USB_INTERFACE_DESCRIPTOR_TYPE 0x04
+#define USB_ENDPOINT_DESCRIPTOR_TYPE 0x05
+
+// descriptor types defined by DWG documents
+#define USB_RESERVED_DESCRIPTOR_TYPE 0x06
+#define USB_CONFIG_POWER_DESCRIPTOR_TYPE 0x07
+#define USB_INTERFACE_POWER_DESCRIPTOR_TYPE 0x08
+
+#define USB_DESCRIPTOR_MAKE_TYPE_AND_INDEX(d, i) ((USHORT)((USHORT)d<<8 | i))
+
+//
+// Values for bmAttributes field of an
+// endpoint descriptor
+//
+
+#define USB_ENDPOINT_TYPE_MASK 0x03
+
+#define USB_ENDPOINT_TYPE_CONTROL 0x00
+#define USB_ENDPOINT_TYPE_ISOCHRONOUS 0x01
+#define USB_ENDPOINT_TYPE_BULK 0x02
+#define USB_ENDPOINT_TYPE_INTERRUPT 0x03
+
+
+//
+// definitions for bits in the bmAttributes field of a
+// configuration descriptor.
+//
+#define USB_CONFIG_POWERED_MASK 0xc0
+
+#define USB_CONFIG_BUS_POWERED 0x80
+#define USB_CONFIG_SELF_POWERED 0x40
+#define USB_CONFIG_REMOTE_WAKEUP 0x20
+
+//
+// Endpoint direction bit, stored in address
+//
+
+#define USB_ENDPOINT_DIRECTION_MASK 0x80
+
+// test direction bit in the bEndpointAddress field of
+// an endpoint descriptor.
+#define USB_ENDPOINT_DIRECTION_OUT(addr) (!((addr) & USB_ENDPOINT_DIRECTION_MASK))
+#define USB_ENDPOINT_DIRECTION_IN(addr) ((addr) & USB_ENDPOINT_DIRECTION_MASK)
+
+//
+// USB defined request codes
+// see chapter 9 of the USB 1.0 specifcation for
+// more information.
+//
+
+// These are the correct values based on the USB 1.0
+// specification
+
+#define USB_REQUEST_GET_STATUS 0x00
+#define USB_REQUEST_CLEAR_FEATURE 0x01
+
+#define USB_REQUEST_SET_FEATURE 0x03
+
+#define USB_REQUEST_SET_ADDRESS 0x05
+#define USB_REQUEST_GET_DESCRIPTOR 0x06
+#define USB_REQUEST_SET_DESCRIPTOR 0x07
+#define USB_REQUEST_GET_CONFIGURATION 0x08
+#define USB_REQUEST_SET_CONFIGURATION 0x09
+#define USB_REQUEST_GET_INTERFACE 0x0A
+#define USB_REQUEST_SET_INTERFACE 0x0B
+#define USB_REQUEST_SYNC_FRAME 0x0C
+
+
+//
+// defined USB device classes
+//
+
+
+#define USB_DEVICE_CLASS_RESERVED 0x00
+#define USB_DEVICE_CLASS_AUDIO 0x01
+#define USB_DEVICE_CLASS_COMMUNICATIONS 0x02
+#define USB_DEVICE_CLASS_HUMAN_INTERFACE 0x03
+#define USB_DEVICE_CLASS_MONITOR 0x04
+#define USB_DEVICE_CLASS_PHYSICAL_INTERFACE 0x05
+#define USB_DEVICE_CLASS_POWER 0x06
+#define USB_DEVICE_CLASS_PRINTER 0x07
+#define USB_DEVICE_CLASS_STORAGE 0x08
+#define USB_DEVICE_CLASS_HUB 0x09
+#define USB_DEVICE_CLASS_VENDOR_SPECIFIC 0xFF
+
+//
+// USB Core defined Feature selectors
+//
+
+#define USB_FEATURE_ENDPOINT_STALL 0x0000
+#define USB_FEATURE_REMOTE_WAKEUP 0x0001
+
+//
+// USB DWG defined Feature selectors
+//
+
+#define USB_FEATURE_INTERFACE_POWER_D0 0x0002
+#define USB_FEATURE_INTERFACE_POWER_D1 0x0003
+#define USB_FEATURE_INTERFACE_POWER_D2 0x0004
+#define USB_FEATURE_INTERFACE_POWER_D3 0x0005
+
+typedef struct _USB_DEVICE_DESCRIPTOR {
+ UCHAR bLength;
+ UCHAR bDescriptorType;
+ USHORT bcdUSB;
+ UCHAR bDeviceClass;
+ UCHAR bDeviceSubClass;
+ UCHAR bDeviceProtocol;
+ UCHAR bMaxPacketSize0;
+ USHORT idVendor;
+ USHORT idProduct;
+ USHORT bcdDevice;
+ UCHAR iManufacturer;
+ UCHAR iProduct;
+ UCHAR iSerialNumber;
+ UCHAR bNumConfigurations;
+} USB_DEVICE_DESCRIPTOR, *PUSB_DEVICE_DESCRIPTOR;
+
+typedef struct _USB_ENDPOINT_DESCRIPTOR {
+ UCHAR bLength;
+ UCHAR bDescriptorType;
+ UCHAR bEndpointAddress;
+ UCHAR bmAttributes;
+ USHORT wMaxPacketSize;
+ UCHAR bInterval;
+} USB_ENDPOINT_DESCRIPTOR, *PUSB_ENDPOINT_DESCRIPTOR;
+
+typedef struct _USB_CONFIGURATION_DESCRIPTOR {
+ UCHAR bLength;
+ UCHAR bDescriptorType;
+ USHORT wTotalLength;
+ UCHAR bNumInterfaces;
+ UCHAR bConfigurationValue;
+ UCHAR iConfiguration;
+ UCHAR bmAttributes;
+ UCHAR MaxPower;
+} USB_CONFIGURATION_DESCRIPTOR, *PUSB_CONFIGURATION_DESCRIPTOR;
+
+typedef struct _USB_INTERFACE_DESCRIPTOR {
+ UCHAR bLength;
+ UCHAR bDescriptorType;
+ UCHAR bInterfaceNumber;
+ UCHAR bAlternateSetting;
+ UCHAR bNumEndpoints;
+ UCHAR bInterfaceClass;
+ UCHAR bInterfaceSubClass;
+ UCHAR bInterfaceProtocol;
+ UCHAR iInterface;
+} USB_INTERFACE_DESCRIPTOR, *PUSB_INTERFACE_DESCRIPTOR;
+
+typedef struct _USB_STRING_DESCRIPTOR {
+ UCHAR bLength;
+ UCHAR bDescriptorType;
+ WCHAR bString[1];
+} USB_STRING_DESCRIPTOR, *PUSB_STRING_DESCRIPTOR;
+
+typedef struct _USB_COMMON_DESCRIPTOR {
+ UCHAR bLength;
+ UCHAR bDescriptorType;
+} USB_COMMON_DESCRIPTOR, *PUSB_COMMON_DESCRIPTOR;
+
+
+//
+// Standard USB HUB definitions
+//
+// See Chapter 11 USB core specification
+//
+
+typedef struct _USB_HUB_DESCRIPTOR {
+ UCHAR bDescriptorLength; // Length of this descriptor
+ UCHAR bDescriptorType; // Hub configuration type
+ UCHAR bNumberOfPorts; // number of ports on this hub
+ USHORT wHubCharacteristics; // Hub Charateristics
+ UCHAR bPowerOnToPowerGood; // port power on till power good in 2ms
+ UCHAR bHubControlCurrent; // max current in mA
+ //
+ // room for 255 ports power control and removable bitmask
+ UCHAR bRemoveAndPowerMask[64];
+} USB_HUB_DESCRIPTOR, *PUSB_HUB_DESCRIPTOR;
+
+
+//
+// Structures defined by various DWG feature documents
+//
+
+
+//
+// See DWG USB Feature Specification: Interface Power Management
+//
+
+#define USB_SUPPORT_D0_COMMAND 0x01
+#define USB_SUPPORT_D1_COMMAND 0x02
+#define USB_SUPPORT_D2_COMMAND 0x04
+#define USB_SUPPORT_D3_COMMAND 0x08
+
+#define USB_SUPPORT_D1_WAKEUP 0x10
+#define USB_SUPPORT_D2_WAKEUP 0x20
+
+
+typedef struct _USB_CONFIGURATION_POWER_DESCRIPTOR {
+ UCHAR bLength;
+ UCHAR bDescriptorType;
+ UCHAR SelfPowerConsumedD0[3];
+ UCHAR bPowerSummaryId;
+ UCHAR bBusPowerSavingD1;
+ UCHAR bSelfPowerSavingD1;
+ UCHAR bBusPowerSavingD2;
+ UCHAR bSelfPowerSavingD2;
+ UCHAR bBusPowerSavingD3;
+ UCHAR bSelfPowerSavingD3;
+ USHORT TransitionTimeFromD1;
+ USHORT TransitionTimeFromD2;
+ USHORT TransitionTimeFromD3;
+} USB_CONFIGURATION_POWER_DESCRIPTOR, *PUSB_CONFIGURATION_POWER_DESCRIPTOR;
+
+
+typedef struct _USB_INTERFACE_POWER_DESCRIPTOR {
+ UCHAR bLength;
+ UCHAR bDescriptorType;
+ UCHAR bmCapabilitiesFlags;
+ UCHAR bBusPowerSavingD1;
+ UCHAR bSelfPowerSavingD1;
+ UCHAR bBusPowerSavingD2;
+ UCHAR bSelfPowerSavingD2;
+ UCHAR bBusPowerSavingD3;
+ UCHAR bSelfPowerSavingD3;
+ USHORT TransitionTimeFromD1;
+ USHORT TransitionTimeFromD2;
+ USHORT TransitionTimeFromD3;
+} USB_INTERFACE_POWER_DESCRIPTOR, *PUSB_INTERFACE_POWER_DESCRIPTOR;
+
+
+#include <POPPACK.H>
+
+
+#endif /* __USB100_H__ */
+
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnAlgorithms.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnAlgorithms.h
new file mode 100644
index 00000000..a829bcbb
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnAlgorithms.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef __XN_ALGORITHMS_H__
+#define __XN_ALGORITHMS_H__
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include <XnPlatform.h>
+
+//---------------------------------------------------------------------------
+// Types
+//---------------------------------------------------------------------------
+template<class T>
+XnBool DefaultComparer(const T& arg1, const T& arg2)
+{
+ return arg1 < arg2;
+}
+
+class XnAlgorithms
+{
+public:
+ template<class T, class Comparer>
+ static void BubbleSort(T elements[], XnUInt32 nCount, Comparer comp)
+ {
+ XnUInt32 n = nCount;
+ XnBool bSwapped;
+ T temp;
+
+ if (nCount == 0)
+ return;
+
+ do
+ {
+ bSwapped = FALSE;
+ for (XnUInt32 i = 0; i < n - 1; ++i)
+ {
+ if (!comp(elements[i], elements[i+1]))
+ {
+ // swap
+ temp = elements[i];
+ elements[i] = elements[i+1];
+ elements[i+1] = temp;
+
+ bSwapped = TRUE;
+ }
+ }
+
+ n -= 1;
+
+ } while (bSwapped);
+ }
+
+ template<class T>
+ static void BubbleSort(T elements[], XnUInt32 nCount)
+ {
+ BubbleSort(elements, nCount, DefaultComparer);
+ }
+
+};
+
+#endif // __XN_ALGORITHMS_H__ \ No newline at end of file
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnArray.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnArray.h
new file mode 100644
index 00000000..d90cff0c
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnArray.h
@@ -0,0 +1,313 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef __XNARRAY_H__
+#define __XNARRAY_H__
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include <XnOS.h>
+
+//---------------------------------------------------------------------------
+// Types
+//---------------------------------------------------------------------------
+template <typename T>
+class XnArray
+{
+public:
+ enum {BASE_SIZE = 8};
+
+ /** An iterator object that allows you to iterate over members in the array. **/
+ typedef T* Iterator;
+
+ /** A constant iterator object that allows you to iterate over members in the array as read-only values. **/
+ typedef const T* ConstIterator;
+
+ /** Default constructor. Initializes the array to BASE_SIZE. **/
+ XnArray(XnUInt32 nBaseSize = BASE_SIZE)
+ {
+ Init(nBaseSize);
+ }
+
+ /** Copy constructor. Initializes this array from another array of the same type. **/
+ XnArray(const XnArray& other) : m_pData(NULL), m_nSize(0), m_nAllocatedSize(0)
+ {
+ *this = other;
+ }
+
+ /** Destructor. Deallocates data in this array. **/
+ virtual ~XnArray()
+ {
+ XN_DELETE_ARR(m_pData);
+ }
+
+ /** Assignment operator. Copies data from another array of the same type. **/
+ XnArray& operator=(const XnArray& other)
+ {
+ CopyFrom(other);
+ return *this;
+ }
+
+ /** Copies data from another array of the same type. **/
+ XnStatus CopyFrom(const XnArray& other)
+ {
+ if (this != &other)
+ {
+ XnStatus nRetVal = SetData(other.m_pData, other.m_nSize);
+ XN_IS_STATUS_OK(nRetVal);
+ }
+ return XN_STATUS_OK;
+ }
+
+ /** Copies data from a raw buffer of the same type pointed to by pData, and sets size to nSize. **/
+ XnStatus SetData(const T* pData, XnUInt32 nSize)
+ {
+ Clear();
+ XnStatus nRetVal = SetSize(nSize);
+ XN_IS_STATUS_OK(nRetVal);
+ for (XnUInt32 i = 0; i < nSize; i++)
+ {
+ m_pData[i] = pData[i];
+ }
+ return XN_STATUS_OK;
+ }
+
+ /** @returns the raw data of this array as a read-only buffer. **/
+ const T* GetData() const
+ {
+ return m_pData;
+ }
+
+ /** @returns the raw data of this array as a modifiable buffer. **/
+ T* GetData()
+ {
+ return m_pData;
+ }
+
+ /** Reserves space in this array for the specified number of elements.
+ This saves you re-allocations and data copies if you know the size in advance. **/
+ XnStatus Reserve(XnUInt32 nReservedSize)
+ {
+ if (nReservedSize > m_nAllocatedSize)
+ {
+ //Calculate next power of 2 after nReservedSize
+ nReservedSize--;
+ nReservedSize = (nReservedSize >> 1) | nReservedSize;
+ nReservedSize = (nReservedSize >> 2) | nReservedSize;
+ nReservedSize = (nReservedSize >> 4) | nReservedSize;
+ nReservedSize = (nReservedSize >> 8) | nReservedSize;
+ nReservedSize = (nReservedSize >> 16) | nReservedSize;
+ nReservedSize++; // nReservedSize is now the next power of 2.
+
+ //Allocate new data
+ T* pNewData = XN_NEW_ARR(T, nReservedSize);
+ XN_VALIDATE_ALLOC_PTR(pNewData);
+
+ //Copy old data into new data
+ for (XnUInt32 i = 0; i < m_nSize; i++)
+ {
+ pNewData[i] = m_pData[i];
+ }
+
+ //Delete old data
+ XN_DELETE_ARR(m_pData);
+
+ //Point to new data
+ m_pData = pNewData;
+ m_nAllocatedSize = nReservedSize;
+ }
+ return XN_STATUS_OK;
+ }
+
+ /** @returns TRUE if this array is empty, FALSE otherwise. **/
+ XnBool IsEmpty() const
+ {
+ return (m_nSize == 0);
+ }
+
+ /** @returns The number of elements in this array. **/
+ XnUInt32 GetSize() const
+ {
+ return m_nSize;
+ }
+
+ /** Sets the size of this array to the specified number of elements.
+ Note that for primitive types, the data is uninitialized. **/
+ XnStatus SetSize(XnUInt32 nSize)
+ {
+ //TODO: Shrink allocated array if new size is smaller
+ XnStatus nRetVal = SetMinSize(nSize);
+ XN_IS_STATUS_OK(nRetVal);
+ m_nSize = nSize;
+ return XN_STATUS_OK;
+ }
+
+ /** Sets the size of this array to the specified number of elements, initializing all elements with the
+ value specified by fillVal. **/
+ XnStatus SetSize(XnUInt32 nSize, const T& fillVal)
+ {
+ //TODO: Shrink allocated array if new size is smaller
+ XnStatus nRetVal = SetMinSize(nSize, fillVal);
+ XN_IS_STATUS_OK(nRetVal);
+ m_nSize = nSize;
+ return XN_STATUS_OK;
+ }
+
+ /** Makes sure the array has at least nSize elements.
+ If nSize is less than the current size, there is no effect.
+ Note that for primitive types, any added elements are uninitialized. **/
+ XnStatus SetMinSize(XnUInt32 nSize)
+ {
+ if (nSize > m_nSize)
+ {
+ XnStatus nRetVal = Reserve(nSize);
+ XN_IS_STATUS_OK(nRetVal);
+ m_nSize = nSize;
+ }
+ return XN_STATUS_OK;
+ }
+
+ /** Makes sure the array has at least nSize elements.
+ If nSize is less than the current size, there is no effect.
+ Any added elements are initialized by the value specified by fillVal. **/
+ XnStatus SetMinSize(XnUInt32 nSize, const T& fillVal)
+ {
+ if (nSize > m_nSize)
+ {
+ XnStatus nRetVal = Reserve(nSize);
+ XN_IS_STATUS_OK(nRetVal);
+ for (XnUInt32 i = m_nSize; i < nSize; i++)
+ {
+ m_pData[i] = fillVal;
+ }
+ m_nSize = nSize;
+ }
+
+ return XN_STATUS_OK;
+ }
+
+ /** @returns The allocated size of this array. This is the maximum number of elements that the array can hold
+ without re-allocating and copying data. **/
+ XnUInt32 GetAllocatedSize() const
+ {
+ return m_nAllocatedSize;
+ }
+
+ /** Sets value at specified index, grows array if needed.
+ Note that when dealing with primitive types and adding beyond the current size of the array,
+ any added values that fill the gap are uninitialized**/
+ XnStatus Set(XnUInt32 nIndex, const T& val)
+ {
+ XnStatus nRetVal = SetMinSize(nIndex+1);
+ XN_IS_STATUS_OK(nRetVal);
+ m_pData[nIndex] = val;
+ return XN_STATUS_OK;
+ }
+
+ /** Sets value at specified index and grows array if needed, filling any resulting blank elements with fillVal. **/
+ XnStatus Set(XnUInt32 nIndex, const T& val, const T& fillVal)
+ {
+ XnStatus nRetVal = SetMinSize(nIndex+1, fillVal);
+ XN_IS_STATUS_OK(nRetVal);
+ m_pData[nIndex] = val;
+ return XN_STATUS_OK;
+ }
+
+ /** Adds one element to the end of this array. **/
+ XnStatus AddLast(const T& val)
+ {
+ return Set(m_nSize, val);
+ }
+
+ /** Adds a range of values to the end of this array. **/
+ XnStatus AddLast(const T* aValues, XnUInt32 nCount)
+ {
+ XN_VALIDATE_INPUT_PTR(aValues);
+ XnUInt32 nOffset = GetSize();
+ XnStatus nRetVal = SetMinSize(GetSize() + nCount);
+ XN_IS_STATUS_OK(nRetVal);
+ for (XnUInt32 i = 0; i < nCount; ++i)
+ {
+ m_pData[nOffset + i] = aValues[i];
+ }
+ return XN_STATUS_OK;
+ }
+
+ /** Resets the data of this array and sets its size to 0. **/
+ void Clear()
+ {
+ XN_DELETE_ARR(m_pData);
+ Init();
+ }
+
+ /** Element access operator. Returns a modifiable reference to the element at specified index. **/
+ T& operator[](XnUInt32 nIndex)
+ {
+ XN_ASSERT(nIndex < m_nSize);
+ return m_pData[nIndex];
+ }
+
+ /** Element access operator. Returns a const reference to the element at specified index. **/
+ const T& operator[](XnUInt32 nIndex) const
+ {
+ XN_ASSERT(nIndex < m_nSize);
+ return m_pData[nIndex];
+ }
+
+ /** @returns a modifiable iterator pointing to the beginning of this array. **/
+ Iterator begin()
+ {
+ return &m_pData[0];
+ }
+
+ /** @returns a const iterator pointing to the beginning of this array. **/
+ ConstIterator begin() const
+ {
+ return &m_pData[0];
+ }
+
+ /** @returns a modifiable itertor pointing to the end of this array. **/
+ Iterator end()
+ {
+ return m_pData + m_nSize;
+ }
+
+ /** @returns a const itertor pointing to the end of this array. **/
+ ConstIterator end() const
+ {
+ return m_pData + m_nSize;
+ }
+
+private:
+ void Init(XnUInt32 nBaseSize = BASE_SIZE)
+ {
+ m_pData = XN_NEW_ARR(T, nBaseSize);
+ m_nAllocatedSize = nBaseSize;
+ m_nSize = 0;
+ }
+
+ T* m_pData;
+ XnUInt32 m_nSize;
+ XnUInt32 m_nAllocatedSize;
+};
+
+#endif // __XNARRAY_H__ \ No newline at end of file
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnBaseNode.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnBaseNode.h
new file mode 100644
index 00000000..a4df6c11
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnBaseNode.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef _NINODEALLOC_H
+#define _NINODEALLOC_H
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include <XnDataTypes.h>
+
+//---------------------------------------------------------------------------
+// Types
+//---------------------------------------------------------------------------
+/**
+ * The base of the building block of the data types - XnBaseNode
+ */
+typedef struct XnBaseNode
+{
+ /** the next XnNode */
+ XnBaseNode* m_pNext;
+ /** the previous XnNode */
+ XnBaseNode* m_pPrevious;
+ /** the value of the XnNode */
+ XnValue m_Data;
+} XnBaseNode;
+
+//---------------------------------------------------------------------------
+// Exported Function Declaration
+//---------------------------------------------------------------------------
+/**
+ * Provide an available xnBaseNode from the node pool.
+ */
+XN_C_API XnBaseNode* XN_C_DECL xnAllocateBaseNode();
+
+/**
+ * Release an xnBaseNode to the node pool.
+ * @param pNode [in] The base node to return to the pool.
+ */
+XN_C_API void XN_C_DECL xnDeallocateBaseNode(XnBaseNode* pNode);
+
+#endif //_NINODEALLOC_H
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnBitSet.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnBitSet.h
new file mode 100644
index 00000000..89ad6450
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnBitSet.h
@@ -0,0 +1,135 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef __XNBITSET_H__
+#define __XNBITSET_H__
+
+#include <XnArray.h>
+
+class XnBitSet
+{
+public:
+ XnBitSet() : m_nSize(0) {}
+
+ /** Reserves space in this bitset for the specified number of bits.
+ This saves you re-allocations and data copies if you know the size in advance. **/
+ XnStatus Reserve(XnUInt32 nBits)
+ {
+ return m_array.Reserve((nBits >> 5) + 1);
+ }
+
+ /** Sets the size of the bitset to the specified number of bits and sets them all to 0. **/
+ XnStatus SetSize(XnUInt32 nBits)
+ {
+ return m_array.SetSize((nBits >> 5) + 1, 0);
+ }
+
+ /** Sets the bit at nIndex to bValue. **/
+ XnStatus Set(XnUInt32 nIndex, XnBool bValue)
+ {
+ XnUInt32 nArrayIndex = (nIndex >> 5);
+ XnUInt32 nMask = (1 << ((~nIndex) & 0x1F));
+ XnUInt32 nOldVal = nArrayIndex < m_array.GetSize() ? m_array[nArrayIndex] : 0;
+ XnUInt32 nNewVal = bValue ? (nOldVal | nMask) : (nOldVal & (~nMask));
+ XnStatus nRetVal = m_array.Set(nArrayIndex, nNewVal, 0);
+ XN_IS_STATUS_OK(nRetVal);
+ m_nSize = XN_MAX(m_nSize, nIndex + 1);
+ return XN_STATUS_OK;
+ }
+
+ /** @returns the value of the bit specified by nIndex. **/
+ XnBool IsSet(XnUInt32 nIndex) const
+ {
+ XnUInt32 nArrayIndex = (nIndex >> 5);
+ if (nArrayIndex >= m_array.GetSize())
+ {
+ return FALSE;
+ }
+ return (m_array[nArrayIndex] & (1 << ((~nIndex) & 0x1F))) ? TRUE : FALSE;
+ }
+
+ /** Copies raw data from a buffer of dwords to this bitset. **/
+ XnStatus SetData(const XnUInt32* pData, XnUInt32 nSizeInDwords)
+ {
+ XnStatus nRetVal = m_array.SetData(pData, nSizeInDwords);
+ XN_IS_STATUS_OK(nRetVal);
+ m_nSize = (nSizeInDwords << 5);
+ return XN_STATUS_OK;
+ }
+
+ /** Copies raw data from a buffer of bytes to this bitset. **/
+ XnStatus SetDataBytes(const XnUInt8* pData, XnUInt32 nSizeInBytes)
+ {
+ //XnStatus nRetVal = m_array.SetData(reinterpret_cast<const XnUInt32*>(pData), XN_MAX(1, nSizeInBytes >> 2));
+ XnUInt32 nSizeInDwords = XN_MAX(1, nSizeInBytes >> 2);
+ XnStatus nRetVal = m_array.SetSize(nSizeInDwords);
+ XN_IS_STATUS_OK(nRetVal);
+ for (XnUInt32 nDwordIdx = 0, nByteIdx = 0; nDwordIdx < nSizeInDwords; nDwordIdx++, nByteIdx += 4)
+ {
+ m_array[nDwordIdx] = ((pData[nByteIdx] << 24) | (pData[nByteIdx + 1] << 16) | (pData[nByteIdx + 2] << 8) | pData[nByteIdx + 3] );
+ }
+ m_nSize = (nSizeInBytes << 3);
+ return XN_STATUS_OK;
+ }
+
+ /** @returns The raw data of this bitset as a buffer of dwords. **/
+ const XnUInt32* GetData() const
+ {
+ return m_array.GetData();
+ }
+
+ /** @returns The raw data of this bitset as a buffer of dwords. Allows modification of underlying data. **/
+ XnUInt32* GetData()
+ {
+ return m_array.GetData();
+ }
+
+ /** @returns size in bytes of this bitset. **/
+ XnUInt32 GetDataSize() const
+ {
+ return m_array.GetSize();
+ }
+
+ /** @returns size in bits of this bitset. **/
+ XnUInt32 GetSize() const
+ {
+ return m_nSize;
+ }
+
+ /** Clears data in this bitset and sets size to 0. **/
+ void Clear()
+ {
+ m_array.Clear();
+ m_nSize = 0;
+ }
+
+ /** @returns TRUE if this bitset is empty, FALSE otherwise. **/
+ XnBool IsEmpty() const
+ {
+ return m_array.IsEmpty();
+ }
+
+private:
+ XnArray<XnUInt32> m_array;
+ XnUInt32 m_nSize;
+};
+
+#endif // __XNBITSET_H__ \ No newline at end of file
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnCallback.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnCallback.h
new file mode 100644
index 00000000..4d2418c8
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnCallback.h
@@ -0,0 +1,41 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef __XN_CALLBACK_H__
+#define __XN_CALLBACK_H__
+
+//---------------------------------------------------------------------------
+// Types
+//---------------------------------------------------------------------------
+/**
+* Holds a pair of function pointer and user cookie to be used as callbacks.
+*/
+struct XnCallback
+{
+ XnCallback() : pFuncPtr(NULL), pCookie(NULL) {}
+ XnCallback(XnFuncPtr pFuncPtr, void* pCookie) : pFuncPtr(pFuncPtr), pCookie(pCookie) {}
+ void Set(XnFuncPtr pFuncPtr, void* pCookie) { this->pFuncPtr = pFuncPtr; this->pCookie = pCookie; }
+
+ XnFuncPtr pFuncPtr;
+ void* pCookie;
+};
+
+#endif //__XN_CALLBACK_H__
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnCodecIDs.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnCodecIDs.h
new file mode 100644
index 00000000..f90025d0
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnCodecIDs.h
@@ -0,0 +1,34 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef __NICODECIDS_H__
+#define __NICODECIDS_H__
+
+#include "XnTypes.h"
+
+#define XN_CODEC_NULL XN_CODEC_ID(0, 0, 0, 0)
+#define XN_CODEC_UNCOMPRESSED XN_CODEC_ID('N','O','N','E')
+#define XN_CODEC_JPEG XN_CODEC_ID('J','P','E','G')
+#define XN_CODEC_16Z XN_CODEC_ID('1','6','z','P')
+#define XN_CODEC_16Z_EMB_TABLES XN_CODEC_ID('1','6','z','T')
+#define XN_CODEC_8Z XN_CODEC_ID('I','m','8','z')
+
+#endif // __NICODECIDS_H__
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnContext.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnContext.h
new file mode 100644
index 00000000..fb6414c4
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnContext.h
@@ -0,0 +1,569 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef __XN_CONTEXT_H__
+#define __XN_CONTEXT_H__
+
+/**
+ * @ingroup cref
+ * @defgroup context Context
+ * This page details functions for managing an OpenNI context.
+ *
+ * @section init Initializing and Deinitializing OpenNI Context
+ *
+ * Initialization must be performed before using any OpenNI functionality, and similarly you
+ * must not call any OpenNI functions after deinitialization.
+ *
+ * @section trees Enumerating and Creating Production Trees
+ *
+ * A production tree is composed of a production node, and optionally a list of other
+ * production trees needed for this production node. Each production node has a type (one of
+ * the types defined by OpenNI spec), a vendor name, and a specific name (unique for this type
+ * and vendor), with a version.
+ * For example, a User generator may need a Depth generator, which in turn might need a Device node.
+ *
+ * @subsection results Enumeration Results
+ *
+ * The results from an enumeration operation is a pointer to the first node of a linked list, representing
+ * all the different possibilities to get data of the requested type. A single possibility contains
+ * the provider description, an optional instance name (that can be used by the provider as proprietary
+ * information, like a device S/N), and the bExists field, which tells if this node already exists in
+ * the context (and as such, doesn't need to be created) or not, and a list of needed nodes by this node.
+ *
+ * @subsection enumex Enumerating Example
+ *
+ * For example, let's take a look at an application in need of depth maps:
+ * @code
+// Enumerate for production trees that can produce depth
+XnNodeInfoList* pNodesList;
+nRetVal = xnEnumerateProductionTrees(pNiteCtx, XN_NODE_TYPE_DEPTH, NULL, &pNodesList);
+CHECK_RC(nRetVal, "Enumerate");
+
+// choose a tree (for simplicity, take first one)
+XnNodeInfoListIterator itChosen = xnNodeInfoListGetFirst(pNodesList);
+XnNodeInfo* pChosen = xnNodeInfoListGetCurrent(itChosen);
+
+// create first one
+XnNodeHandle hDepth;
+nRetVal = xnCreateProductionTree(pNiteCtx, pChosen, &hDepth);
+CHECK_RC(nRetVal, "Create");
+
+// free the list (it is no longer needed)
+xnNodeInfoListFree(pNodesList);
+
+// TODO: use handle for configuration and data extraction
+ * @endcode
+ *
+ * @{
+*/
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include <XnTypes.h>
+#include <XnQueries.h>
+#include <XnPrdNodeInfoList.h>
+
+//---------------------------------------------------------------------------
+// Functions
+//---------------------------------------------------------------------------
+
+/** @name Initialization
+ * Functions for initializing and shutting down an OpenNI context.
+ * @{
+ */
+
+/**
+ * @brief Initializes the OpenNI library.
+ *
+ * This function must be called before calling any other OpenNI function (except for @ref xnInitFromXmlFile())
+ *
+ * @param ppContext [out] Output location for context pointer.
+ */
+XN_C_API XnStatus XN_C_DECL xnInit(XnContext** ppContext);
+
+/**
+ * @brief Runs an XML script in the given context.
+ *
+ * @param pContext [in] The context to be configured.
+ * @param strFileName [in] The name of the file containing the script. for a full description of the XML structure, see @ref xmlscripts.
+ * @param pErrors [in/out] Optional. If provided, will be filled with enumeration errors.
+ * @param phScriptNode [out] Handle to a node holding all the nodes created from the script. When no longer
+ * needed, the node can be released, causing all those nodes to dec ref.
+ */
+XN_C_API XnStatus XN_C_DECL xnContextRunXmlScriptFromFileEx(XnContext* pContext, const XnChar* strFileName, XnEnumerationErrors* pErrors, XnNodeHandle* phScriptNode);
+
+/**
+ * @brief Runs an XML script in the given context.
+ * NOTE: when using this function, the context will be the owner of the created nodes, so those nodes and
+ * the context will only be destroyed if calling @ref xnShutdown(). It is highly suggested to use
+ * @ref xnContextRunXmlScriptFromFileEx() instead, which returns a node referencing created nodes, making the caller
+ * owner of those nodes.
+ *
+ * @param pContext [in] The context to be configured.
+ * @param strFileName [in] The name of the file containing the script. for a full description of the XML structure, see @ref xmlscripts.
+ * @param pErrors [in/out] Optional. If provided, will be filled with enumeration errors.
+ */
+XN_C_API XnStatus XN_API_DEPRECATED("Please use xnContextRunXmlScriptFromFileEx() instead") xnContextRunXmlScriptFromFile(XnContext* pContext, const XnChar* strFileName, XnEnumerationErrors* pErrors);
+
+/**
+ * @brief Runs an XML script in the given context.
+ *
+ * @param pContext [in] The context.
+ * @param xmlScript [in] A string representation of the XML script. for a full description of the XML structure, see @ref xmlscripts.
+ * @param pErrors [in/out] Optional. If provided, will be filled with enumeration errors.
+ * @param phScriptNode [out] Handle to a node holding all the nodes created from the script. When no longer
+ * needed, the node can be released, causing all those nodes to dec ref.
+ */
+XN_C_API XnStatus XN_C_DECL xnContextRunXmlScriptEx(XnContext* pContext, const XnChar* xmlScript, XnEnumerationErrors* pErrors, XnNodeHandle* phScriptNode);
+
+/**
+ * @brief Runs an XML script in the given context.
+ * NOTE: when using this function, the context will be the owner of the created nodes, so those nodes and
+ * the context will only be destroyed if calling @ref xnShutdown(). It is highly suggested to use
+ * @ref xnContextRunXmlScriptEx() instead, which returns a node referencing created nodes, making the caller
+ * owner of those nodes.
+ *
+ * @param pContext [in] The context.
+ * @param xmlScript [in] A string representation of the XML script. for a full description of the XML structure, see @ref xmlscripts.
+ * @param pErrors [in/out] Optional. If provided, will be filled with enumeration errors.
+ */
+XN_C_API XnStatus XN_API_DEPRECATED("Please use xnContextRunXmlScriptEx() instead") XN_C_DECL xnContextRunXmlScript(XnContext* pContext, const XnChar* xmlScript, XnEnumerationErrors* pErrors);
+
+/**
+ * @brief Initializes OpenNI context, and then configures it using the given file.
+ *
+ * @param strFileName [in] The name of the file to read configuration from.
+ * @param ppContext [out] Output location for context pointer.
+ * @param pErrors [in/out] Optional. If provided, will be filled with enumeration errors.
+ * @param phScriptNode [out] Handle to a node holding all the nodes created from the script. When no longer
+ * needed, the node can be released, causing all those nodes to dec ref.
+ */
+XN_C_API XnStatus XN_C_DECL xnInitFromXmlFileEx(const XnChar* strFileName, XnContext** ppContext, XnEnumerationErrors* pErrors, XnNodeHandle* phScriptNode);
+
+/**
+ * @brief Initializes OpenNI context, and then configures it using the given file.
+ * NOTE: when using this function, the context will be the owner of the created nodes, so those nodes and
+ * the context will only be destroyed if calling @ref xnShutdown(). It is highly suggested to use
+ * @ref xnInitFromXmlFileEx() instead, which returns a node referencing created nodes, making the caller
+ * owner of those nodes.
+ *
+ * @param strFileName [in] The name of the file to read configuration from.
+ * @param ppContext [out] Output location for context pointer.
+ * @param pErrors [in/out] Optional. If provided, will be filled with enumeration errors.
+ */
+XN_C_API XnStatus XN_API_DEPRECATED("Please use xnInitFromXmlFileEx() instead") XN_C_DECL xnInitFromXmlFile(const XnChar* strFileName, XnContext** ppContext, XnEnumerationErrors* pErrors);
+
+/**
+ * @brief Opens a recording file, adding all nodes in it to the context.
+ *
+ * @param pContext [in] The context.
+ * @param strFileName [in] The file to open.
+ * @param phPlayerNode [out] The created player node.
+ */
+XN_C_API XnStatus XN_C_DECL xnContextOpenFileRecordingEx(XnContext* pContext, const XnChar* strFileName, XnNodeHandle* phPlayerNode);
+
+/**
+ * @brief Opens a recording file, adding all nodes in it to the context.
+ * NOTE: when using this function, the context will be the owner of the created player node, so this nodes and
+ * the context will only be destroyed if calling @ref xnShutdown(). It is highly suggested to use
+ * @ref xnContextOpenFileRecordingEx() instead, which returns the player node, making the caller
+ * owner of this node.
+ *
+ * @param pContext [in] The context.
+ * @param strFileName [in] The file to open.
+ */
+XN_C_API XnStatus XN_API_DEPRECATED("Please use xnContextOpenFileRecordingEx() instead") XN_C_DECL xnContextOpenFileRecording(XnContext* pContext, const XnChar* strFileName);
+
+/**
+ * @brief Adds a reference to the context object.
+ *
+ * @param pContext [in] The context.
+ */
+XN_C_API XnStatus XN_C_DECL xnContextAddRef(XnContext* pContext);
+
+/**
+ * @brief Releases a context object, decreasing its ref count by 1. If reference count has reached 0,
+ * the context will be destroyed.
+ *
+ * @param pContext [in] The context.
+ */
+XN_C_API void XN_C_DECL xnContextRelease(XnContext* pContext);
+
+/**
+ * @brief Shuts down an OpenNI context, destroying all its nodes. Do not call any function of this
+ * context or any correlated node after calling this method.
+ * NOTE: this function destroys the context and all the nodes it holds and so should be used very carefully.
+ * Normally you should just call @ref xnContextRelease()
+ *
+ * @param pContext [in] The context to be destroyed.
+ */
+XN_C_API void XN_API_DEPRECATED("Use xnContextRelease() instead") XN_C_DECL xnShutdown(XnContext* pContext);
+
+/**
+ * @brief Forces a context to shutdown, destroying all nodes. This function is used for backwards compatibility
+ * and should not be called by any client. Please use @ref xnContextRelease() instead.
+ *
+ * @param pContext [in] The context to be destroyed.
+ */
+XN_C_API void XN_C_DECL xnForceShutdown(XnContext* pContext);
+
+/**
+ * @brief Registers for context shutting down event. This function is used for backwards compatibility and
+ * should not be called by any client.
+ */
+XN_C_API XnStatus XN_C_DECL xnContextRegisterForShutdown(XnContext* pContext, XnContextShuttingDownHandler pHandler, void* pCookie, XnCallbackHandle* phCallback);
+
+/**
+ * @brief Unregisters from context shutting down event. This function is used for backwards compatibility and
+ * should not be called by any client.
+ */
+XN_C_API void XN_C_DECL xnContextUnregisterFromShutdown(XnContext* pContext, XnCallbackHandle hCallback);
+
+// @}
+
+/** @name Enumeration
+ * Functions for enumeration and creation of nodes.
+ * @{
+ */
+
+/**
+ * @brief Enumerates all available production trees for a specific node type. The trees populated in the
+ * list should be freed by calling @ref xnNodeInfoListFree() once not needed.
+ *
+ * @param pContext [in] OpenNI context.
+ * @param Type [in] The requested node type.
+ * @param pQuery [in] Optional. A query object that can be used to filter results.
+ * @param ppTreesList [out] A list of possible production trees.
+ * @param pErrors [in/out] Optional. If provided, will be filled with enumeration errors.
+ */
+XN_C_API XnStatus XN_C_DECL xnEnumerateProductionTrees(
+ XnContext* pContext,
+ XnProductionNodeType Type,
+ const XnNodeQuery* pQuery,
+ XnNodeInfoList** ppTreesList,
+ XnEnumerationErrors* pErrors
+ );
+
+/**
+ * @brief Creates a production node. If the tree specifies additional needed nodes, and those nodes
+ * do not exist, they will be created too, and passed to this node as input.
+ *
+ * @param pContext [in] OpenNI context.
+ * @param pTree [in] A production tree to create.
+ * @param phNode [out] A handle to the newly created node.
+ */
+XN_C_API XnStatus XN_C_DECL xnCreateProductionTree(
+ XnContext* pContext,
+ XnNodeInfo* pTree,
+ XnNodeHandle* phNode
+ );
+
+/**
+ * @brief Enumerates for production trees for a specific node type, and creates the first found tree.
+ * This function is a shortcut version for using @ref xnEnumerateProductionTrees(), iterating the list,
+ * and then calling @ref xnCreateProductionTree().
+ *
+ * @param pContext [in] OpenNI context.
+ * @param type [in] The requested node type.
+ * @param pQuery [in] Optional. A query object that can be used to filter results.
+ * @param phNode [out] A handle to the newly created node.
+ * @param pErrors [in/out] Optional. If provided, will be filled with enumeration errors.
+ */
+XN_C_API XnStatus XN_C_DECL xnCreateAnyProductionTree(
+ XnContext* pContext,
+ XnProductionNodeType type,
+ XnNodeQuery* pQuery,
+ XnNodeHandle* phNode,
+ XnEnumerationErrors* pErrors
+ );
+
+/**
+ * @brief Creates a production node which is only a mock. This node does not represent an actual node, but only
+ * keeps a state and implements an interface above it.
+ * Mock nodes are useful when simulating nodes for playing recordings, or for use in tests.
+ * See also @ref xnCreateMockNodeBasedOn().
+ *
+ * @param pContext [in] OpenNI context.
+ * @param type [in] The type of the mock to create.
+ * @param strName [in] Optional. The name of the node. If NULL is provided, a name will be automatically generated.
+ * @param phNode [out] A handle to the newly created node.
+ */
+XN_C_API XnStatus XN_C_DECL xnCreateMockNode(
+ XnContext* pContext,
+ XnProductionNodeType type,
+ const XnChar* strName,
+ XnNodeHandle* phNode
+ );
+
+/**
+ * @brief Creates a production node which is only a mock, base on the type and properties of another node.
+ * This node does not represent an actual node, but only keeps a state and implements an interface above it.
+ * Mock nodes are useful when simulating nodes for playing recordings, or for use in tests.
+ * See also @ref xnCreateMockNode().
+ *
+ * @param pContext [in] OpenNI context.
+ * @param hOriginalNode [in] A handle to an existing node on which the mock node will be based on.
+ * @param strName [in] The name of the node. If set to NULL, a name will be generated based on the name of hOriginalNode.
+ * @param phMockNode [out] A handle to the newly created mock node.
+ */
+XN_C_API XnStatus XN_C_DECL xnCreateMockNodeBasedOn(
+ XnContext* pContext,
+ XnNodeHandle hOriginalNode,
+ const XnChar* strName,
+ XnNodeHandle* phMockNode
+ );
+
+/**
+ * @brief References a production node, increasing its reference count by 1.
+ *
+ * @param hNode [in] A handle to the node.
+ */
+XN_C_API XnStatus XN_C_DECL xnProductionNodeAddRef(XnNodeHandle hNode);
+
+/**
+ * References a production node, increasing its reference count by 1.
+ * Note: this function is deprecated. Please use @ref xnProductionNodeAddRef() instead.
+ *
+ * @param hNode [in] A handle to the node.
+ */
+XN_C_API XnStatus XN_API_DEPRECATED("Please use xnProductionNodeAddRef() instead.") XN_C_DECL xnRefProductionNode(XnNodeHandle hNode);
+
+/**
+ * @brief Unreference a production node, decreasing its reference count by 1. If the reference count reaches zero,
+ * the node will be destroyed.
+ *
+ * @param hNode [in] A handle to the node.
+ */
+XN_C_API void XN_C_DECL xnProductionNodeRelease(XnNodeHandle hNode);
+
+/**
+ * Unreference a production node, decreasing its reference count by 1. If the reference count reaches zero,
+ * the node will be destroyed.
+ * Note: this function is deprecated. Please use @ref xnProductionNodeAddRef() instead.
+ *
+ * @param hNode [in] A handle to the node.
+ */
+XN_C_API void XN_API_DEPRECATED("Please use xnProductionNodeRelease() instead.") XN_C_DECL xnUnrefProductionNode(XnNodeHandle hNode);
+
+/**
+ * @brief Gets a list of all existing node in the context. Each node that was returned increases its ref count.
+ * The list must be freed using @ref xnNodeInfoListFree().
+ *
+ * @param pContext [in] OpenNI context.
+ * @param ppList [out] A linked list of current existing nodes
+ */
+XN_C_API XnStatus XN_C_DECL xnEnumerateExistingNodes(XnContext* pContext, XnNodeInfoList** ppList);
+
+/**
+ * @brief Gets a list of all existing node in the context. Each node that was returned increases its ref count.
+ * The list must be freed using @ref xnNodeInfoListFree().
+ *
+ * @param pContext [in] OpenNI context.
+ * @param type [in] Type to look for.
+ * @param ppList [out] A linked list of current existing nodes
+ */
+XN_C_API XnStatus XN_C_DECL xnEnumerateExistingNodesByType(XnContext* pContext, XnProductionNodeType type, XnNodeInfoList** ppList);
+
+/**
+ * @brief Returns the first found existing node of the specified type.
+ *
+ * @param pContext [in] OpenNI context.
+ * @param type [in] Type to look for.
+ * @param phNode [out] A handle to the found node.
+ */
+XN_C_API XnStatus XN_C_DECL xnFindExistingRefNodeByType(
+ XnContext* pContext,
+ XnProductionNodeType type,
+ XnNodeHandle* phNode
+ );
+
+XN_C_API XnStatus XN_API_DEPRECATED("Please use xnFindExistingRefNodeByType() instead") XN_C_DECL xnFindExistingNodeByType(
+ XnContext* pContext,
+ XnProductionNodeType type,
+ XnNodeHandle* phNode
+ );
+
+/**
+ * @brief Gets a handle to an existing production node instance using that instance name.
+ *
+ * @param pContext [in] OpenNI context.
+ * @param strInstanceName [in] Name of the instance to get.
+ * @param phNode [out] A handle to that instance.
+ *
+ * @return XN_STATUS_BAD_NODE_NAME if node by name of strInstanceName doesn't exist.
+ */
+XN_C_API XnStatus XN_C_DECL xnGetRefNodeHandleByName(
+ XnContext* pContext,
+ const XnChar* strInstanceName,
+ XnNodeHandle* phNode
+ );
+
+XN_C_API XnStatus XN_API_DEPRECATED("Please use xnGetRefNodeHandleByName() instead") XN_C_DECL xnGetNodeHandleByName(
+ XnContext* pContext,
+ const XnChar* strInstanceName,
+ XnNodeHandle* phNode
+ );
+
+// @}
+
+/** @name Multi-Node Handling
+ * Functions that affect all the nodes in the context.
+ * @{
+ */
+
+/**
+ * @brief Updates all generators nodes in the context, waiting for all to have new data.
+ *
+ * @param pContext [in] OpenNI context.
+ */
+XN_C_API XnStatus XN_C_DECL xnWaitAndUpdateAll(XnContext* pContext);
+
+/**
+ * @brief Updates all generators nodes in the context, waiting for a specific one to have new data.
+ *
+ * @param pContext [in] OpenNI context.
+ * @param hNode [in] The node to wait for.
+ */
+XN_C_API XnStatus XN_C_DECL xnWaitOneUpdateAll(XnContext* pContext, XnNodeHandle hNode);
+
+/**
+ * @brief Updates all generators nodes in the context, once any of them have new data.
+ *
+ * @param pContext [in] OpenNI context.
+ */
+XN_C_API XnStatus XN_C_DECL xnWaitAnyUpdateAll(XnContext* pContext);
+
+/**
+ * @brief Updates all generator nodes in the context, without any waiting. If a node has new data,
+ * it will be updated.
+ *
+ * @param pContext [in] OpenNI context.
+ */
+XN_C_API XnStatus XN_C_DECL xnWaitNoneUpdateAll(XnContext* pContext);
+
+/**
+ * @brief Make sure all generators are generating data.
+ *
+ * @param pContext [in] OpenNI context.
+ */
+XN_C_API XnStatus XN_C_DECL xnStartGeneratingAll(XnContext* pContext);
+
+/**
+ * @brief Stop all generators from generating data.
+ *
+ * @param pContext [in] OpenNI context.
+ */
+XN_C_API XnStatus XN_C_DECL xnStopGeneratingAll(XnContext* pContext);
+
+/**
+ * @brief Sets the global mirror flag. This will set all current existing nodes' mirror state, and also
+ * affect future created nodes. The default mirror flag is FALSE.
+ *
+ * @param pContext [in] OpenNI context.
+ * @param bMirror [in] New Mirror state.
+ */
+XN_C_API XnStatus XN_C_DECL xnSetGlobalMirror(XnContext* pContext, XnBool bMirror);
+
+/**
+ * @brief Gets the global mirror flag.
+ *
+ * @param pContext [in] OpenNI context.
+ */
+XN_C_API XnBool XN_C_DECL xnGetGlobalMirror(XnContext* pContext);
+
+/**
+ * @brief Gets the global error state of the context. If one of the nodes in the context is in error state,
+ * that state will be returned. If more than one node is in error state, XN_STATUS_MULTIPLE_NODES_ERROR
+ * is returned. An application can query each node error state by calling @ref xnGetNodeErrorState().
+ *
+ * @param pContext [in] OpenNI context.
+ */
+XN_C_API XnStatus XN_C_DECL xnGetGlobalErrorState(XnContext* pContext);
+
+/**
+ * @brief Registers a callback function to global error state changes.
+ *
+ * @param pContext [in] OpenNI context.
+ * @param handler [in] A pointer to a function that will be called when global error state changes.
+ * @param pCookie [in] A user cookie that will be passed to the callback function.
+ * @param phCallback [out] Optional. Will be filled with a handle to be passed to @ref xnUnregisterFromGlobalErrorStateChange().
+ */
+XN_C_API XnStatus XN_C_DECL xnRegisterToGlobalErrorStateChange
+ (XnContext* pContext, XnErrorStateChangedHandler handler,
+ void* pCookie, XnCallbackHandle* phCallback);
+
+/**
+ * @brief Unregisters a callback function which was registered using @ref xnRegisterToGlobalErrorStateChange().
+ *
+ * @param pContext [in] OpenNI context.
+ * @param hCallback [in] The handle to the callback returned from @ref xnRegisterToGlobalErrorStateChange().
+ */
+XN_C_API void XN_C_DECL xnUnregisterFromGlobalErrorStateChange
+ (XnContext* pContext, XnCallbackHandle hCallback);
+
+/**
+* @brief Registers a callback function to 'Node Creation' event. This event is raised whenever node are created.
+*
+* @param pContext [in] OpenNI context.
+* @param handler [in] A pointer to a function that will be called when a new node is created.
+* @param pCookie [in] A user cookie that will be passed to the callback function.
+* @param phCallback [out] Optional. Will be filled with a handle to be passed to @ref xnUnregisterFromNodeCreation().
+*/
+XN_C_API XnStatus XN_C_DECL xnRegisterToNodeCreation
+ (XnContext* pContext, XnNodeCreationHandler handler,
+ void* pCookie, XnCallbackHandle* phCallback);
+
+/**
+ * @brief Unregisters a callback function which was registered using @ref xnRegisterToNodeCreation().
+ *
+ * @param pContext [in] OpenNI context.
+ * @param hCallback [in] The handle to the callback returned from @ref xnRegisterToNodeCreation().
+ */
+XN_C_API void XN_C_DECL xnUnregisterFromNodeCreation
+ (XnContext* pContext, XnCallbackHandle hCallback);
+
+/**
+* @brief Registers a callback function to 'Node Destruction' event. This event is raised whenever a node is destroyed.
+*
+* @param pContext [in] OpenNI context.
+* @param handler [in] A pointer to a function that will be called when a node is destroyed.
+* @param pCookie [in] A user cookie that will be passed to the callback function.
+* @param phCallback [out] Optional. Will be filled with a handle to be passed to @ref xnUnregisterFromNodeDestruction().
+*/
+XN_C_API XnStatus XN_C_DECL xnRegisterToNodeDestruction
+ (XnContext* pContext, XnNodeDestructionHandler handler,
+ void* pCookie, XnCallbackHandle* phCallback);
+
+/**
+ * @brief Unregisters a callback function which was registered using @ref xnRegisterToNodeDestruction().
+ *
+ * @param pContext [in] OpenNI context.
+ * @param hCallback [in] The handle to the callback returned from @ref xnRegisterToNodeDestruction().
+ */
+XN_C_API void XN_C_DECL xnUnregisterFromNodeDestruction
+ (XnContext* pContext, XnCallbackHandle hCallback);
+
+/// @}
+
+/** @} */
+
+#endif // __XN_CONTEXT_H__
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnCppWrapper.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnCppWrapper.h
new file mode 100644
index 00000000..1984be3d
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnCppWrapper.h
@@ -0,0 +1,10100 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef __XN_CPP_WRAPPER_H__
+#define __XN_CPP_WRAPPER_H__
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include <XnOpenNI.h>
+#include <XnCodecIDs.h>
+
+//---------------------------------------------------------------------------
+// Types
+//---------------------------------------------------------------------------
+namespace xn
+{
+ //---------------------------------------------------------------------------
+ // Forward Declarations
+ //---------------------------------------------------------------------------
+ class ProductionNode;
+ class EnumerationErrors;
+ class NodeInfo;
+ class NodeInfoList;
+ class Context;
+ class Query;
+ class Generator;
+
+ /**
+ * @ingroup cppref
+ * @defgroup cppref_glb_ev_hndlrs Global Event Handlers
+ */
+
+ /**
+ * @ingroup cppref
+ * @defgroup cppref_graph_mgmt Managing the Production Graph
+ */
+
+ /**
+ * @ingroup cppref
+ * @defgroup cppref_meta_data Meta-Data Objects (Frame Objects)
+ */
+
+ /**
+ * @ingroup cppref
+ * @defgroup cppref_prd_func Production Nodes Functionality
+ */
+
+ /**
+ * @ingroup cppref
+ * @defgroup cppref_misc Misc
+ */
+
+ //---------------------------------------------------------------------------
+ // Types
+ //---------------------------------------------------------------------------
+
+ /**
+ * @ingroup cppref_glb_ev_hndlrs
+ * Type definition to define event handlers for the 'State Change' event.
+ *
+ * @param [in] node Node issuing the event.
+ * @param [in] pCookie User cookie passed on registration.
+ *
+ * <b>Remarks</b>
+ *
+ * The 'State Change' event can be invoked by a number of OpenNI objects.
+ * For example, this event is invoked by the @ref xn::ErrorStateCapability "ErrorStateCapability"
+ * object whenever a node's error state changes. As another example, this event is
+ * also invoked by the @ref xn::MirrorCapability "MirrorCapability" object whenever a node's
+ * mirror configuration has been changed.
+ *
+ * <b>Example:</b>
+ *
+ * The following is an example of a callback method that follows that signature:
+ *
+ @code
+ void XN_CALLBACK_TYPE OnEvent(ProductionNode& node, void* pCookie)
+ {
+ }
+ @endcode
+ */
+ typedef void (XN_CALLBACK_TYPE* StateChangedHandler)(ProductionNode& node, void* pCookie);
+
+ //---------------------------------------------------------------------------
+ // Internal stuff
+ //---------------------------------------------------------------------------
+ typedef XnStatus (*_XnRegisterStateChangeFuncPtr)(XnNodeHandle hNode, XnStateChangedHandler handler, void* pCookie, XnCallbackHandle* phCallback);
+ typedef void (*_XnUnregisterStateChangeFuncPtr)(XnNodeHandle hNode, XnCallbackHandle hCallback);
+
+ static XnStatus _RegisterToStateChange(_XnRegisterStateChangeFuncPtr xnFunc, XnNodeHandle hNode, StateChangedHandler handler, void* pCookie, XnCallbackHandle& hCallback);
+ static void _UnregisterFromStateChange(_XnUnregisterStateChangeFuncPtr xnFunc, XnNodeHandle hNode, XnCallbackHandle hCallback);
+
+ //---------------------------------------------------------------------------
+ // Some Utilities
+ //---------------------------------------------------------------------------
+ /**
+ * @ingroup cppref_misc
+ * <b>Purpose:</b> The Version class provides functionality for accessing the OpenNI version information.
+ */
+ class Version
+ {
+ public:
+ Version(const XnVersion& version) : m_version(version) {}
+ Version(XnUInt8 nMajor, XnUInt8 nMinor, XnUInt16 nMaintenance, XnUInt32 nBuild)
+ {
+ m_version.nMajor = nMajor;
+ m_version.nMinor = nMinor;
+ m_version.nMaintenance = nMaintenance;
+ m_version.nBuild = nBuild;
+ }
+
+ bool operator==(const Version& other) const
+ {
+ return (xnVersionCompare(&m_version, &other.m_version) == 0);
+ }
+ bool operator!=(const Version& other) const
+ {
+ return (xnVersionCompare(&m_version, &other.m_version) != 0);
+ }
+ bool operator<(const Version& other) const
+ {
+ return (xnVersionCompare(&m_version, &other.m_version) < 0);
+ }
+ bool operator<=(const Version& other) const
+ {
+ return (xnVersionCompare(&m_version, &other.m_version) <= 0);
+ }
+ bool operator>(const Version& other) const
+ {
+ return (xnVersionCompare(&m_version, &other.m_version) > 0);
+ }
+ bool operator>=(const Version& other) const
+ {
+ return (xnVersionCompare(&m_version, &other.m_version) >= 0);
+ }
+
+ static Version Current()
+ {
+ XnVersion version;
+ xnGetVersion(&version);
+ return Version(version);
+ }
+
+ XnUInt8 Major() const { return m_version.nMajor; }
+ XnUInt8 Minor() const { return m_version.nMinor; }
+ XnUInt16 Maintenance() const { return m_version.nMaintenance; }
+ XnUInt32 Build() const { return m_version.nBuild; }
+
+ XnUInt8& Major() { return m_version.nMajor; }
+ XnUInt8& Minor() { return m_version.nMinor; }
+ XnUInt16& Maintenance() { return m_version.nMaintenance; }
+ XnUInt32& Build() { return m_version.nBuild; }
+
+ const XnVersion* GetUnderlying() const { return &m_version; }
+ XnVersion* GetUnderlying() { return &m_version; }
+
+ private:
+ XnVersion m_version;
+ };
+
+ //---------------------------------------------------------------------------
+ // Meta Data
+ //---------------------------------------------------------------------------
+
+ /**
+ * @ingroup cppref_meta_data
+ * <b>Purpose:</b> The OutputMetaData class provides functionality for supporting fast
+ * cached data access to many types of generator nodes.
+ *
+ * <b>Remarks:</b>
+ *
+ * The OutputMetaData class is the most basic OpenNI metadata class, whose main properties
+ * include <code>Timestamp</code>, <code>FrameID</code>, and <code>DataSize</code>.
+ * This class is never instantiated; it is used a base class to help build the hierarchy.
+ *
+ * An instance of this class hold a @ref glos_frame_object "frame object".
+ * The frame object is a snapshot of the generated data at a certain point in time.
+ */
+ class OutputMetaData
+ {
+ public:
+ /**
+ * Ctor. Intended for use by other MetaData objects.
+ *
+ * @param [in] ppData A pointer to the data member of the meta data object.
+ */
+ inline OutputMetaData(const XnUInt8** ppData) : m_ppData(ppData), m_nAllocatedSize(0), m_pAllocatedData(NULL)
+ {
+ xnOSMemSet(&m_output, 0, sizeof(XnOutputMetaData));
+ }
+
+ /**
+ * Dtor. Frees any allocated data.
+ */
+ virtual ~OutputMetaData() { Free(); }
+
+ /**
+ * Returns the timestamp of the @ref glos_frame_object "frame object" saved in this object.
+ */
+ inline XnUInt64 Timestamp() const { return m_output.nTimestamp; }
+
+ /**
+ * Returns the timestamp of the @ref glos_frame_object "frame object" saved in this object.
+ */
+ inline XnUInt64& Timestamp() { return m_output.nTimestamp; }
+
+ /**
+ * Returns the frame ID of the @ref glos_frame_object "frame object" saved in this object.
+ * Frame IDs are sequential unique numbers starting with 1.
+ */
+ inline XnUInt32 FrameID() const { return m_output.nFrameID; }
+
+ /**
+ * Returns the frame ID of the @ref glos_frame_object "frame object" saved in this object.
+ * Frame IDs are sequential unique numbers starting with 1.
+ */
+ inline XnUInt32& FrameID() { return m_output.nFrameID; }
+
+ /**
+ * @brief Returns the size, in bytes, of the data of the @ref glos_frame_object "frame object" saved in this object.
+ *
+ * <b>Remarks</b>
+ *
+ * For map metadata, this value equals to
+ * @ref xn::MapMetaData::XRes "XRes()" * @ref xn::MapMetaData::YRes "YRes()" * @ref xn::MapMetaData::BytesPerPixel "BytesPerPixel()".
+ */
+ inline XnUInt32 DataSize() const { return m_output.nDataSize; }
+
+ /**
+ * @brief Returns the size, in bytes, of the data of the @ref glos_frame_object "frame object" saved in this object.
+ *
+ * <b>Remarks</b>
+ *
+ * For map metadata, this value equals to
+ * @ref xn::MapMetaData::XRes "XRes()" * @ref xn::MapMetaData::YRes "YRes()" * @ref xn::MapMetaData::BytesPerPixel "BytesPerPixel()".
+ */
+ inline XnUInt32& DataSize() { return m_output.nDataSize; }
+
+ /**
+ * Returns whether this node's frame data was updated by the most recent call to
+ * any @ref conc_updating_data "'WaitXUpdateAll()'" function, e.g., @ref xn::Context::WaitAnyUpdateAll().
+ */
+ inline XnBool IsDataNew() const { return m_output.bIsNew; }
+
+ /**
+ * Returns whether this node's frame data was updated by the most recent call to
+ * any @ref conc_updating_data "'WaitXUpdateAll()'" function, e.g., @ref xn::Context::WaitAnyUpdateAll().
+ */
+ inline XnBool& IsDataNew() { return m_output.bIsNew; }
+
+ /**
+ * Gets the C object that is wrapped by this object.
+ */
+ inline const XnOutputMetaData* GetUnderlying() const { return &m_output; }
+ /**
+ * Gets the C object that is wrapped by this object.
+ */
+ inline XnOutputMetaData* GetUnderlying() { return &m_output; }
+
+ /**
+ * Gets a pointer to the data of the @ref glos_frame_object "frame object"
+ * saved in this object.
+ */
+ inline const XnUInt8* Data() const { return *m_ppData; }
+ /**
+ * Gets a pointer to the data of the @ref glos_frame_object "frame object"
+ * saved in this object.
+ */
+ inline const XnUInt8*& Data() { return *m_ppData; }
+
+ /**
+ * Gets a pointer to the writable buffer (see @ref conc_meta_data).
+ */
+ inline XnUInt8* WritableData()
+ {
+ MakeDataWritable();
+ return m_pAllocatedData;
+ }
+
+ /**
+ * @brief Allocates a writable buffer. If a previous buffer was allocated it will
+ * be freed (or reused if possible).
+ *
+ * Also see @ref conc_meta_data.
+ *
+ * @param [in] nBytes The requested size for the buffer, in bytes.
+ */
+ XnStatus AllocateData(XnUInt32 nBytes)
+ {
+ if (nBytes > m_nAllocatedSize)
+ {
+ // reallocate
+ XnUInt8* pData = (XnUInt8*)xnOSMallocAligned(nBytes, XN_DEFAULT_MEM_ALIGN);
+ XN_VALIDATE_ALLOC_PTR(pData);
+
+ // allocation succeeded, replace
+ Free();
+ m_pAllocatedData = pData;
+ m_nAllocatedSize = nBytes;
+ }
+
+ DataSize() = nBytes;
+ *m_ppData = m_pAllocatedData;
+
+ return XN_STATUS_OK;
+ }
+
+ /**
+ * Frees the writable buffer, if one was allocated.
+ */
+ void Free()
+ {
+ if (m_nAllocatedSize != 0)
+ {
+ xnOSFreeAligned(m_pAllocatedData);
+ m_pAllocatedData = NULL;
+ m_nAllocatedSize = 0;
+ }
+ }
+
+ /**
+ * Creates a writable copy of the data, and stores it instead of the original (read-only) data.
+ * Also see @ref conc_meta_data.
+ */
+ XnStatus MakeDataWritable()
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ // check data isn't already writable
+ if (Data() != m_pAllocatedData || DataSize() > m_nAllocatedSize)
+ {
+ const XnUInt8* pOrigData = *m_ppData;
+
+ nRetVal = AllocateData(DataSize());
+ XN_IS_STATUS_OK(nRetVal);
+
+ if (pOrigData != NULL)
+ {
+ xnOSMemCopy(m_pAllocatedData, pOrigData, DataSize());
+ }
+ else
+ {
+ xnOSMemSet(m_pAllocatedData, 0, DataSize());
+ }
+ }
+
+ return (XN_STATUS_OK);
+ }
+
+ protected:
+ XnUInt8* m_pAllocatedData;
+
+ private:
+ XnOutputMetaData m_output;
+
+ const XnUInt8** m_ppData;
+ XnUInt32 m_nAllocatedSize;
+ };
+
+ /**
+ * @ingroup cppref_meta_data
+ * The MapMetaData class is a base class for providing the fast data access functionality
+ * for the @ref glos_frame_object "frame object" saved in metadata. This functionality
+ * is applicable to all generator nodes that have an associated metadata object.
+ *
+ * MapMetaData is the next metadata class in the metadata hierarchy after the OutputMetaData
+ * class.
+ *
+ * The MapMetaData class - like OutputMetaData - is never instantiated;
+ * it is a base class of the OpenNI metadata class hierarchy.
+ */
+ class MapMetaData : public OutputMetaData
+ {
+ public:
+ /**
+ * Ctor. Intended for use by inheriting classes.
+ *
+ * @param [in] format Pixel Format
+ * @param [in] ppData A pointer to the data member of the meta data object
+ */
+ inline MapMetaData(XnPixelFormat format, const XnUInt8** ppData) : OutputMetaData(ppData)
+ {
+ xnOSMemSet(&m_map, 0, sizeof(XnMapMetaData));
+ m_map.pOutput = OutputMetaData::GetUnderlying();
+ m_map.PixelFormat = format;
+ }
+
+ /**
+ * Gets the frame X resolution of the @ref glos_frame_object "frame object" saved in this object.
+ * The X resolution is the actual number of columns in the frame after any required cropping has
+ * been applied.
+ */
+ inline XnUInt32 XRes() const { return m_map.Res.X; }
+ /**
+ * Gets the frame X resolution of the @ref glos_frame_object "frame object" saved in this object.
+ * The X resolution is the actual number of columns in the frame after any required cropping has
+ * been applied.
+ */
+ inline XnUInt32& XRes() { return m_map.Res.X; }
+
+ /**
+ * Gets the frame Y resolution of the @ref glos_frame_object "frame object" saved in this object.
+ * The Y resolution is the actual number of rows in the frame after any required cropping has
+ * been applied.
+ */
+ inline XnUInt32 YRes() const { return m_map.Res.Y; }
+ /**
+ * Gets the frame Y resolution of the @ref glos_frame_object "frame object" saved in this object.
+ * The Y resolution is the actual number of rows in the frame after any required cropping has
+ * been applied.
+ */
+ inline XnUInt32& YRes() { return m_map.Res.Y; }
+
+ /**
+ * Gets the cropping area X offset of the @ref glos_frame_object "frame object" saved in this object.
+ * This is the horizontal offset, measured in units of pixel columns, of the buffer within the field of view.
+ *
+ * <b>Remarks</b>
+ *
+ * The X offset is 0 if cropping is disabled (see @ref XnCropping).
+ */
+ inline XnUInt32 XOffset() const { return m_map.Offset.X; }
+ /**
+ * Gets the cropping area X offset of the @ref glos_frame_object "frame object" saved in this object.
+ * This is the horizontal offset, measured in units of pixel columns, of the buffer within the field of view.
+ *
+ * <b>Remarks</b>
+ *
+ * The X offset is 0 if cropping is disabled (see @ref XnCropping).
+ */
+ inline XnUInt32& XOffset() { return m_map.Offset.X; }
+
+ /**
+ * Gets the cropping area Y offset of the @ref glos_frame_object "frame object" saved in this object.
+ * This is the vertical offset, measured in units of pixel rows, of the buffer within the field of view.
+ *
+ * <b>Remarks</b>
+ *
+ * The Y offset is 0 if cropping is disabled (see @ref XnCropping).
+ */
+ inline XnUInt32 YOffset() const { return m_map.Offset.Y; }
+ /**
+ * Gets the cropping area Y offset of the @ref glos_frame_object "frame object" saved in this object.
+ * This is the vertical offset, measured in units of pixel rows, of the buffer within the field of view.
+ *
+ * <b>Remarks</b>
+ *
+ * The Y offset is 0 if cropping is disabled (see @ref XnCropping).
+ */
+ inline XnUInt32& YOffset() { return m_map.Offset.Y; }
+
+ /**
+ * Gets the number of columns in the full frame (entire field-of-view, ignoring
+ * cropping).
+ */
+ inline XnUInt32 FullXRes() const { return m_map.FullRes.X; }
+
+
+ /**
+ * Gets the number of columns in the full frame (entire field-of-view, ignoring
+ * cropping).
+ */
+ inline XnUInt32& FullXRes() { return m_map.FullRes.X; }
+
+ /**
+ * Gets the number of rows in the full frame (entire field-of-view, ignoring cropping).
+ */
+ inline XnUInt32 FullYRes() const { return m_map.FullRes.Y; }
+ /**
+ * Gets the number of rows in the full frame (entire field-of-view, ignoring cropping).
+ */
+ inline XnUInt32& FullYRes() { return m_map.FullRes.Y; }
+
+ /**
+ * Gets the FPS in which frame was generated.
+ */
+ inline XnUInt32 FPS() const { return m_map.nFPS; }
+ /**
+ * Gets the FPS in which frame was generated.
+ */
+ inline XnUInt32& FPS() { return m_map.nFPS; }
+
+ /**
+ * Gets the pixel format of the pixel-map.
+ */
+ inline XnPixelFormat PixelFormat() const { return m_map.PixelFormat; }
+
+ /**
+ * Gets the C object that is wrapped by this object.
+ */
+ inline const XnMapMetaData* GetUnderlying() const { return &m_map; }
+ /**
+ * Gets the C object that is wrapped by this object.
+ */
+ inline XnMapMetaData* GetUnderlying() { return &m_map; }
+
+ /**
+ * Gets the number of bytes each pixel occupies.
+ */
+ inline XnUInt32 BytesPerPixel() const
+ {
+ switch (PixelFormat())
+ {
+ case XN_PIXEL_FORMAT_RGB24:
+ return sizeof(XnRGB24Pixel);
+ case XN_PIXEL_FORMAT_YUV422:
+ return sizeof(XnYUV422DoublePixel)/2;
+ case XN_PIXEL_FORMAT_GRAYSCALE_8_BIT:
+ return sizeof(XnGrayscale8Pixel);
+ case XN_PIXEL_FORMAT_GRAYSCALE_16_BIT:
+ return sizeof(XnGrayscale16Pixel);
+ case XN_PIXEL_FORMAT_MJPEG:
+ return 2;
+ default:
+ XN_ASSERT(FALSE);
+ return 0;
+ }
+ }
+
+ /**
+ * @copybrief xn::OutputMetaData::AllocateData
+ *
+ * @param [in] nXRes The number of required columns in the map.
+ * @param [in] nYRes The number of required rows in the map.
+ */
+ XnStatus AllocateData(XnUInt32 nXRes, XnUInt32 nYRes)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ XnUInt32 nSize = nXRes * nYRes * BytesPerPixel();
+ nRetVal = OutputMetaData::AllocateData(nSize);
+ XN_IS_STATUS_OK(nRetVal);
+
+ FullXRes() = XRes() = nXRes;
+ FullYRes() = YRes() = nYRes;
+ XOffset() = YOffset() = 0;
+
+ return (XN_STATUS_OK);
+ }
+
+ /**
+ * Changes dimensions of the pixel-map.
+ *
+ * @param [in] nXRes Number of columns in the map
+ * @param [in] nYRes Number of rows in the map
+ * @param [in] pExternalBuffer Optional. An external buffer to be used. If NULL is passed,
+ * a buffer will be allocated.
+ */
+ XnStatus ReAdjust(XnUInt32 nXRes, XnUInt32 nYRes, const XnUInt8* pExternalBuffer)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ if (pExternalBuffer == NULL)
+ {
+ nRetVal = AllocateData(nXRes, nYRes);
+ XN_IS_STATUS_OK(nRetVal);
+ }
+ else
+ {
+ FullXRes() = XRes() = nXRes;
+ FullYRes() = YRes() = nYRes;
+ XOffset() = YOffset() = 0;
+ Data() = pExternalBuffer;
+ DataSize() = nXRes * nYRes * BytesPerPixel();
+ }
+
+ return (XN_STATUS_OK);
+ }
+
+ protected:
+ XnPixelFormat& PixelFormatImpl() { return m_map.PixelFormat; }
+
+ private:
+ // block copy ctor and assignment operator
+ MapMetaData& operator=(const MapMetaData&);
+ inline MapMetaData(const MapMetaData& other);
+
+ // Members
+ XnMapMetaData m_map;
+ };
+
+ /**
+ * @ingroup cppref_meta_data
+ * The Map Wrapper classes are light wrappers for @ref glos_frame_object maps (from metadata classes). These wrapper classes
+ * provide small data-focused objects for simplified data access to frame objects generated by the generator nodes.
+ *
+ * @tparam _pixelType The data type of a single pixel in this map
+ */
+ template<class _pixelType>
+ class Map
+ {
+ public:
+ inline Map(_pixelType*& pData, XnUInt32& nXRes, XnUInt32 &nYRes) :
+ m_pData(pData), m_nXRes(nXRes), m_nYRes(nYRes)
+ {}
+
+ /**
+ * Gets the frame X resolution. The X resolution is the actual number of columns in the frame after any required cropping has been applied.
+ *
+ * <b>Remarks</b>
+ *
+ * This is the same as @ref xn::MapMetaData::XRes "MapMetaData::XRes()".
+ */
+ inline XnUInt32 XRes() const { return m_nXRes; }
+ /**
+ * Gets the frame Y resolution. The Y resolution is the actual number of rows in the frame after any required cropping has been applied.
+ *
+ * <b>Remarks</b>
+ *
+ * This is the same as @ref xn::MapMetaData::YRes "MapMetaData::YRes()".
+ */
+ inline XnUInt32 YRes() const { return m_nYRes; }
+
+ /**
+ * Gets a single pixel of the frame map by indexing a map as a one-dimensional array.
+ *
+ * @param [in] nIndex The position of the pixel in the buffer
+ *
+ * @returns A pixel of type <code>_pixelType</code>.
+ *
+ * <b>Remarks</b>
+ *
+ * Indexing a map in this way can give improved speed in some situations.
+ */
+ inline const _pixelType& operator[](XnUInt32 nIndex) const
+ {
+ XN_ASSERT(nIndex < (m_nXRes * m_nYRes));
+ return m_pData[nIndex];
+ }
+ /**
+ * Gets a single pixel of the frame map by indexing a map as a one-dimensional array.
+ *
+ * @param [in] nIndex The position of the pixel in the buffer
+ *
+ * @returns A pixel of type <code>_pixelType</code>.
+ *
+ * <b>Remarks</b>
+ *
+ * Indexing a map in this way can give improved speed in some situations.
+ */
+ inline _pixelType& operator[](XnUInt32 nIndex)
+ {
+ XN_ASSERT(nIndex < (m_nXRes *m_nYRes));
+ return m_pData[nIndex];
+ }
+
+ /**
+ * Gets a single pixel of the frame map by its X and Y coordinates.
+ *
+ * @param [in] x The horizontal position of the pixel (from left to right)
+ * @param [in] y The vertical position of the pixel in the buffer (from top to bottom)
+ *
+ * @returns A pixel of type <code>_pixelType</code>.
+ */
+ inline const _pixelType& operator()(XnUInt32 x, XnUInt32 y) const
+ {
+ XN_ASSERT(x < m_nXRes && y < m_nYRes);
+ return m_pData[y*m_nXRes + x];
+ }
+ /**
+ * Gets a single pixel of the frame map by its X and Y coordinates.
+ *
+ * @param [in] x The horizontal position of the pixel (from left to right)
+ * @param [in] y The vertical position of the pixel in the buffer (from top to bottom)
+ *
+ * @returns A pixel of type <code>_pixelType</code>.
+ */
+ inline _pixelType& operator()(XnUInt32 x, XnUInt32 y)
+ {
+ XN_ASSERT(x < m_nXRes && y < m_nYRes);
+ return m_pData[y*m_nXRes + x];
+ }
+
+ private:
+ /* block copy ctor and assignment operator */
+ Map(const Map& other);
+ Map& operator=(const Map&);
+
+ _pixelType*& m_pData;
+ XnUInt32& m_nXRes;
+ XnUInt32& m_nYRes;
+ };
+
+ /** @ingroup cppref_meta_data
+ * @{
+ */
+ /** Declares a @ref xn::Map "Map" class with pixel of type XnDepthPixel */
+ typedef Map<XnDepthPixel> DepthMap;
+ /** Declares a @ref xn::Map "Map" class with pixel of type XnUInt8 */
+ typedef Map<XnUInt8> ImageMap;
+ /** Declares a @ref xn::Map "Map" class with pixel of type XnRGB24Pixel */
+ typedef Map<XnRGB24Pixel> RGB24Map;
+ /** Declares a @ref xn::Map "Map" class with pixel of type XnGrayscale16Pixel */
+ typedef Map<XnGrayscale16Pixel> Grayscale16Map;
+ /** Declares a @ref xn::Map "Map" class with pixel of type XnGrayscale8Pixel */
+ typedef Map<XnGrayscale8Pixel> Grayscale8Map;
+ /** Declares a @ref xn::Map "Map" class with pixel of type XnIRPixel */
+ typedef Map<XnIRPixel> IRMap;
+ /** Declares a @ref xn::Map "Map" class with pixel of type XnLabel */
+ typedef Map<XnLabel> LabelMap;
+ /** @} */
+
+ /**
+ * @ingroup cppref_meta_data
+ *
+ * For saving the @ref glos_frame_object "frame object" (data and configuration) from
+ * the @ref xn::DepthGenerator "DepthGenerator" node. This @ref glos_frame_object "frame
+ * object" is a snapshot of the DepthGenerator's generated depth map and its associated
+ * configuration information at a certain point in time. This saved @ref glos_frame_object
+ * "frame object" provides fast and easy access to the DepthGenerator node's data and
+ * configuration information.
+ *
+ * It is important to get a good understanding of the purpose and design of the OpenNI
+ * metadata objects. For a comprehensive overview of OpenNI metadata objects, see @ref
+ * conc_meta_data.
+ *
+ * The DepthGenerator node generates depth data of the FOV. This is the
+ * Z-coordinate of the X-Y-Z coordinate of each point. The Z-axis is the distance, in
+ * millimeters from the sensor plane.
+ * A smaller depth value indicates a scene point that is a <i>closer</i> to the sensor,
+ * and a larger depth value indicates a scene point that is <i>further away</i> from
+ * the sensor. A zero depth value indicates that the DepthGenerator node did not succeed
+ * in obtaining a valid depth reading.
+ *
+ * DepthMetaData's @ref xn::DepthMetaData::Data() method provides the actual depth
+ * data. This method returns the pointer to the first depth pixel in the map.
+ *
+ * The pixel format of depth map is XnDepthPixel, i.e. 16-bit values.
+ *
+ * DepthMetaData provides the <code>ZRes</code> property to contain the depth resolution.
+ * This is the maximum value of a pixel (plus one).
+ *
+ * DepthMetaData is similar to ImageMetaData; they are both metadata for a type of map.
+ */
+ class DepthMetaData : public MapMetaData
+ {
+ public:
+ /**
+ * Ctor.
+ */
+ inline DepthMetaData() :
+ MapMetaData(XN_PIXEL_FORMAT_GRAYSCALE_16_BIT, (const XnUInt8**)&m_depth.pData),
+ m_depthMap(const_cast<XnDepthPixel*&>(m_depth.pData), MapMetaData::GetUnderlying()->Res.X, MapMetaData::GetUnderlying()->Res.Y),
+ m_writableDepthMap((XnDepthPixel*&)m_pAllocatedData, MapMetaData::GetUnderlying()->Res.X, MapMetaData::GetUnderlying()->Res.Y)
+ {
+ xnOSMemSet(&m_depth, 0, sizeof(XnDepthMetaData));
+ m_depth.pMap = MapMetaData::GetUnderlying();
+ }
+
+ /**
+ * @brief Shallow-Copies a DepthMetaData object.
+ *
+ * @param [in] other source object.
+ *
+ * @remarks Note that the data buffer is not copied, and that both object will point to the same buffer.
+ */
+ inline void InitFrom(const DepthMetaData& other)
+ {
+ xnCopyDepthMetaData(&m_depth, &other.m_depth);
+ }
+
+ /**
+ * Shallow copies another @ref DepthMetaData object, and then @ref ReAdjust "readjusts
+ * it".
+ *
+ * @param [in] other Source object
+ * @param [in] nXRes Requested number of columns in the map
+ * @param [in] nYRes Requested number of rows in the map
+ * @param [in] pExternalBuffer Optional. An external buffer matching requested resolution.
+ * If NULL, A buffer will be allocated.
+ */
+ inline XnStatus InitFrom(const DepthMetaData& other, XnUInt32 nXRes, XnUInt32 nYRes, const XnDepthPixel* pExternalBuffer)
+ {
+ InitFrom(other);
+ return ReAdjust(nXRes, nYRes, pExternalBuffer);
+ }
+
+ /**
+ * Performs a deep-copy of another metadata object (including duplication of the
+ * data buffer).
+ *
+ * @param [in] other source object
+ */
+ XnStatus CopyFrom(const DepthMetaData& other)
+ {
+ // copy props
+ InitFrom(other);
+ // and make a copy of the data (this will allocate and copy data)
+ return MakeDataWritable();
+ }
+
+ /**
+ * @copydoc xn::MapMetaData::ReAdjust
+ */
+ XnStatus ReAdjust(XnUInt32 nXRes, XnUInt32 nYRes, const XnDepthPixel* pExternalBuffer = NULL)
+ {
+ return MapMetaData::ReAdjust(nXRes, nYRes, (const XnUInt8*)pExternalBuffer);
+ }
+
+ /**
+ * Gets the maximum depth (depth resolution) that the DepthGenerator node can produce.
+ * This is the same as the resolution of the depth axis
+ * (i.e., @ref DepthGenerator::GetDeviceMaxDepth() + 1).
+ */
+ inline XnDepthPixel ZRes() const { return m_depth.nZRes; }
+ /**
+ * Gets the maximum depth (depth resolution) that the DepthGenerator node can produce.
+ * This is the same as the resolution of the depth axis
+ * (i.e., @ref DepthGenerator::GetDeviceMaxDepth() + 1).
+ */
+ inline XnDepthPixel& ZRes() { return m_depth.nZRes; }
+
+ /**
+ * @brief Returns the depth map.
+ *
+ * <b>Remarks</b>
+ *
+ * This method returns a pointer to the first depth pixel in the map. The depth
+ * map is implemented as a row-major order compact layout of pixels in the map.
+ *
+ * The pixel format of the map is XnDepthPixel, i.e. 16-bit integer values.
+ *
+ * This method is reimplemented from the @ref xn::OutputMetaData class.
+ */
+ inline const XnDepthPixel* Data() const { return (const XnDepthPixel*)MapMetaData::Data(); }
+ /**
+ * @brief Returns the depth map.
+ *
+ * <b>Remarks</b>
+ *
+ * This method returns a pointer to the first depth pixel in the map. The depth
+ * map is implemented as a row-major order compact layout of pixels in the map.
+ *
+ * The pixel format of the map is XnDepthPixel, i.e. 16-bit integer values.
+ *
+ * This method is reimplemented from the @ref xn::OutputMetaData class.
+ */
+ inline const XnDepthPixel*& Data() { return (const XnDepthPixel*&)MapMetaData::Data(); }
+
+
+ /**
+ * @copydoc xn::OutputMetaData::WritableData
+ */
+ inline XnDepthPixel* WritableData() { return (XnDepthPixel*)MapMetaData::WritableData(); }
+
+ /**
+ * Gets a light object wrapping the depth map
+ */
+ inline const xn::DepthMap& DepthMap() const { return m_depthMap; }
+ /**
+ * Gets a light object wrapping the writable depth map
+ */
+ inline xn::DepthMap& WritableDepthMap()
+ {
+ MakeDataWritable();
+ return m_writableDepthMap;
+ }
+
+ /**
+ * Gets the value of a single pixel of the frame map by its index in the array.
+ *
+ * @param [in] nIndex The index of the pixel in the buffer.
+ */
+ inline const XnDepthPixel& operator[](XnUInt32 nIndex) const
+ {
+ XN_ASSERT(nIndex < (XRes()*YRes()));
+ return Data()[nIndex];
+ }
+
+ /**
+ * Gets the value of a single pixel of the frame map by its X and Y coordinates.
+ *
+ * @param [in] x X-coordinate of the pixel in the map
+ * @param [in] y Y-coordinate of the pixel in the map
+ */
+ inline const XnDepthPixel& operator()(XnUInt32 x, XnUInt32 y) const
+ {
+ XN_ASSERT(x < XRes() && y < YRes());
+ return Data()[y*XRes() + x];
+ }
+
+ /**
+ * @copydoc xn::OutputMetaData::GetUnderlying
+ */
+ inline const XnDepthMetaData* GetUnderlying() const { return &m_depth; }
+ /**
+ * @copydoc xn::OutputMetaData::GetUnderlying
+ */
+ inline XnDepthMetaData* GetUnderlying() { return &m_depth; }
+
+ private:
+ // block copy ctor and assignment operator (because we can't return errors in those)
+ DepthMetaData(const DepthMetaData& other);
+ DepthMetaData& operator=(const DepthMetaData&);
+
+ XnDepthMetaData m_depth;
+ const xn::DepthMap m_depthMap;
+ xn::DepthMap m_writableDepthMap;
+ };
+
+ /**
+ * @ingroup cppref_meta_data
+ *
+ * For saving the @ref glos_frame_object "frame object" (data and configuration) from
+ * the @ref xn::DepthGenerator "DepthGenerator" node. This @ref glos_frame_object "frame
+ * object" is a snapshot of the DepthGenerator's generated depth map and its associated
+ * configuration information at a certain point in time. This saved @ref glos_frame_object
+ * "frame object" provides fast and easy access to the DepthGenerator node's data and
+ * configuration information.
+ *
+ * It is important to get a good understanding of the purpose and design of the OpenNI
+ * metadata objects. For a comprehensive overview of OpenNI metadata objects, see @ref
+ * conc_meta_data.
+ *
+ * The ImageMetaData object provides a number of different methods to get the image
+ * as a different format. You must use the 'Get Data' method most appropriate for the
+ * data format of the latest available frame. For example, if you requested the ImageGenerator
+ * node to generate RGB24 format you must use the @ref RGB24Data() method to get the
+ * data.
+ *
+ * Each of the 'Get Data' methods gets the image as a pointer to the first pixel
+ * in the image map. From the address of that first pixel you can access all the pixels.
+ *
+ * Depending on the format, the pixels are different in size. This means that image
+ * maps are a different size.
+ */
+ class ImageMetaData : public MapMetaData
+ {
+ public:
+ inline ImageMetaData() :
+ MapMetaData(XN_PIXEL_FORMAT_RGB24, &m_image.pData),
+ m_imageMap(const_cast<XnUInt8*&>(m_image.pData), MapMetaData::GetUnderlying()->Res.X, MapMetaData::GetUnderlying()->Res.Y),
+ m_writableImageMap((XnUInt8*&)m_pAllocatedData, MapMetaData::GetUnderlying()->Res.X, MapMetaData::GetUnderlying()->Res.Y),
+ m_rgb24Map((XnRGB24Pixel*&)m_image.pData, MapMetaData::GetUnderlying()->Res.X, MapMetaData::GetUnderlying()->Res.Y),
+ m_writableRgb24Map((XnRGB24Pixel*&)m_pAllocatedData, MapMetaData::GetUnderlying()->Res.X, MapMetaData::GetUnderlying()->Res.Y),
+ m_gray16Map((XnGrayscale16Pixel*&)m_image.pData, MapMetaData::GetUnderlying()->Res.X, MapMetaData::GetUnderlying()->Res.Y),
+ m_writableGray16Map((XnGrayscale16Pixel*&)m_pAllocatedData, MapMetaData::GetUnderlying()->Res.X, MapMetaData::GetUnderlying()->Res.Y),
+ m_gray8Map((XnGrayscale8Pixel*&)m_image.pData, MapMetaData::GetUnderlying()->Res.X, MapMetaData::GetUnderlying()->Res.Y),
+ m_writableGray8Map((XnGrayscale8Pixel*&)m_pAllocatedData, MapMetaData::GetUnderlying()->Res.X, MapMetaData::GetUnderlying()->Res.Y)
+ {
+ xnOSMemSet(&m_image, 0, sizeof(XnImageMetaData));
+ m_image.pMap = MapMetaData::GetUnderlying();
+ }
+
+ /**
+ * @brief Shallow-copies an ImageMetaData object.
+ *
+ * @param [in] other source object.
+ *
+ * @remarks Note that the data buffer is not copied, and that both object will point to the same buffer.
+ */
+ inline void InitFrom(const ImageMetaData& other)
+ {
+ xnCopyImageMetaData(&m_image, &other.m_image);
+ }
+
+ /**
+ * Shallow copies another @ref ImageMetaData object, and then @ref ReAdjust "readjusts"
+ * it.
+ *
+ * @param [in] other Source object
+ * @param [in] nXRes Requested number of columns in the map
+ * @param [in] nYRes Requested number of rows in the map
+ * @param [in] format Requested pixel format
+ * @param [in] pExternalBuffer Optional. An external buffer matching requested resolution.
+ * If NULL, A buffer will be allocated.
+ */
+ inline XnStatus InitFrom(const ImageMetaData& other, XnUInt32 nXRes, XnUInt32 nYRes, XnPixelFormat format, const XnUInt8* pExternalBuffer)
+ {
+ InitFrom(other);
+ XnStatus nRetVal = ReAdjust(nXRes, nYRes, format, pExternalBuffer);
+ XN_IS_STATUS_OK(nRetVal);
+ PixelFormat() = format;
+ return XN_STATUS_OK;
+ }
+
+ /**
+ * @copybrief xn::OutputMetaData::AllocateData
+ *
+ * @param [in] nXRes Requested number of columns in the map
+ * @param [in] nYRes Requested number of rows in the map
+ * @param [in] format Requested pixel format
+ */
+ inline XnStatus AllocateData(XnUInt32 nXRes, XnUInt32 nYRes, XnPixelFormat format)
+ {
+ XnPixelFormat origFormat = PixelFormat();
+ PixelFormat() = format;
+ XnStatus nRetVal = MapMetaData::AllocateData(nXRes, nYRes);
+ if (nRetVal != XN_STATUS_OK)
+ {
+ PixelFormat() = origFormat;
+ return (nRetVal);
+ }
+
+ return XN_STATUS_OK;
+ }
+
+ /**
+ * Performs a deep-copy of another metadata object (including duplication of the data buffer)
+ *
+ * @param [in] other source object
+ */
+ inline XnStatus CopyFrom(const ImageMetaData& other)
+ {
+ // copy props
+ xnCopyImageMetaData(&m_image, &other.m_image);
+ // and make a copy of the data (this will allocate and copy data)
+ return MakeDataWritable();
+ }
+
+ /**
+ * @copybrief xn::MapMetaData::ReAdjust
+ *
+ * @param [in] nXRes Requested number of columns in the map
+ * @param [in] nYRes Requested number of rows in the map
+ * @param [in] format Requested pixel format
+ * @param [in] pExternalBuffer Optional. An external buffer to be used. If NULL
+ * is passed, a buffer will be allocated.
+ */
+ XnStatus ReAdjust(XnUInt32 nXRes, XnUInt32 nYRes, XnPixelFormat format, const XnUInt8* pExternalBuffer = NULL)
+ {
+ XnPixelFormat origFormat = PixelFormat();
+ PixelFormat() = format;
+ XnStatus nRetVal = MapMetaData::ReAdjust(nXRes, nYRes, pExternalBuffer);
+ if (nRetVal != XN_STATUS_OK)
+ {
+ PixelFormat() = origFormat;
+ return (nRetVal);
+ }
+
+ return XN_STATUS_OK;
+ }
+
+ /**
+ * @brief Gets the frame's pixel color format used in this image map. This is the
+ * format of the @ref glos_frame_object "frame object" saved in this object.
+ *
+ * <b>Remarks</b>
+ *
+ * Knowing the pixel format of the image map helps you to enumerate over the map
+ * and process its data.
+ *
+ * Reimplemented from @ref xn::MapMetaData.
+ */
+ inline XnPixelFormat PixelFormat() const { return MapMetaData::PixelFormat(); }
+ /**
+ * @brief Gets the frame's pixel color format used in this image map. This is the
+ * format of the @ref glos_frame_object "frame object" saved in this object.
+ *
+ * <b>Remarks</b>
+ *
+ * Knowing the pixel format of the image map helps you to enumerate over the map
+ * and process its data.
+ */
+ inline XnPixelFormat& PixelFormat() { return MapMetaData::PixelFormatImpl(); }
+
+ /**
+ * @copydoc MapMetaData::WritableData
+ */
+ inline XnUInt8* WritableData() { return MapMetaData::WritableData(); }
+
+ /**
+ * @brief Gets a pointer to the first pixel of the image in @ref xn::XnRGB24Pixel "RGB24" format.
+ * RGB24 format represents each pixel as one byte for red, one byte for green, and one byte for blue.
+ */
+ inline const XnRGB24Pixel* RGB24Data() const { return (const XnRGB24Pixel*)MapMetaData::Data(); }
+ /**
+ * @brief Gets a pointer to the first pixel of the image in @ref xn::XnRGB24Pixel "RGB24" format.
+ * RGB24 format represents each pixel as one byte for red, one byte for green, and one byte for blue.
+ */
+ inline const XnRGB24Pixel*& RGB24Data() { return (const XnRGB24Pixel*&)MapMetaData::Data(); }
+ /**
+ * @copydoc MapMetaData::WritableData
+ */
+ inline XnRGB24Pixel* WritableRGB24Data() { return (XnRGB24Pixel*)MapMetaData::WritableData(); }
+
+ /**
+ * @brief Gets a pointer to the first pixel of the image in @ref xn::XnYUV422DoublePixel "YUV422" format.
+ * YUV422 is a type of compression with a single Y byte followed by a U byte, then another Y byte and then a V byte: YUY'V.
+ * These four values represent two pixels: YUV and Y'UV.
+ */
+ inline const XnYUV422DoublePixel* YUV422Data() const { return (const XnYUV422DoublePixel*)MapMetaData::Data(); }
+ /**
+ * @brief Gets a pointer to the first pixel of the image in @ref xn::XnYUV422DoublePixel "YUV422" format.
+ * YUV422 is a type of compression with a single Y byte followed by a U byte, then another Y byte and then a V byte: YUY'V.
+ * These four values represent two pixels: YUV and Y'UV.
+ */
+ inline const XnYUV422DoublePixel*& YUV422Data() { return (const XnYUV422DoublePixel*&)MapMetaData::Data(); }
+ /**
+ * @copydoc MapMetaData::WritableData
+ */
+ inline XnYUV422DoublePixel* WritableYUV422Data() { return (XnYUV422DoublePixel*)MapMetaData::WritableData(); }
+
+ /**
+ * @brief Gets a pointer to the first pixel of the image in Grayscale8 format.
+ * Grayscale8 represents each pixel as an 8-bit (1 byte) gray scale.
+ */
+ inline const XnGrayscale8Pixel* Grayscale8Data() const { return (const XnGrayscale8Pixel*)MapMetaData::Data(); }
+ /**
+ * @brief Gets a pointer to the first pixel of the image in Grayscale8 format.
+ * Grayscale8 represents each pixel as an 8-bit (1-byte) gray scale.
+ */
+ inline const XnGrayscale8Pixel*& Grayscale8Data() { return (const XnGrayscale8Pixel*&)MapMetaData::Data(); }
+ /**
+ * @copydoc MapMetaData::WritableData
+ */
+ inline XnGrayscale8Pixel* WritableGrayscale8Data() { return (XnGrayscale8Pixel*)MapMetaData::WritableData(); }
+
+ /**
+ * @brief Gets a pointer to the first pixel of the image in Grayscale16 format.
+ * Grayscale16 represents each pixel as a 16-bit (2-byte) gray scale.
+ */
+ inline const XnGrayscale16Pixel* Grayscale16Data() const { return (const XnGrayscale16Pixel*)MapMetaData::Data(); }
+ /**
+ * @brief Gets a pointer to the first pixel of the image in Grayscale16 format.
+ * Grayscale16 represents each pixel as a 16-bit (2-byte) gray scale.
+ */
+ inline const XnGrayscale16Pixel*& Grayscale16Data() { return (const XnGrayscale16Pixel*&)MapMetaData::Data(); }
+ /**
+ * @copydoc MapMetaData::WritableData
+ */
+ inline XnGrayscale16Pixel* WritableGrayscale16Data() { return (XnGrayscale16Pixel*)MapMetaData::WritableData(); }
+
+ /**
+ * @brief Gets a light object wrapping the image map.
+ */
+ inline const xn::ImageMap& ImageMap() const { return m_imageMap; }
+ /**
+ * Gets a light object wrapping the writable image-map
+ */
+ inline xn::ImageMap& WritableImageMap() { MakeDataWritable(); return m_writableImageMap; }
+
+ /**
+ * @brief Gets a light wrapper object for wrapping the image map as RGB24 format.
+ * RGB24 format represents each pixel as one byte for red, one byte for green, and
+ * one byte for blue.
+ */
+ inline const xn::RGB24Map& RGB24Map() const { return m_rgb24Map; }
+ /**
+ * @copydoc xn::ImageMetaData::WritableImageMap
+ */
+ inline xn::RGB24Map& WritableRGB24Map() { MakeDataWritable(); return m_writableRgb24Map; }
+
+ /**
+ * @brief Gets a light wrapper object wrapping the image map as Grayscale8 format.
+ */
+ inline const xn::Grayscale8Map& Grayscale8Map() const { return m_gray8Map; }
+ /**
+ * @copydoc xn::ImageMetaData::WritableImageMap
+ */
+ inline xn::Grayscale8Map& WritableGrayscale8Map() { MakeDataWritable(); return m_writableGray8Map; }
+
+ /**
+ * @brief Gets a light wrapper object wrapping the frame's image map as Grayscale16
+ * format.
+ */
+ inline const xn::Grayscale16Map& Grayscale16Map() const { return m_gray16Map; }
+ /**
+ * @copydoc xn::ImageMetaData::WritableImageMap
+ */
+ inline xn::Grayscale16Map& WritableGrayscale16Map() { MakeDataWritable(); return m_writableGray16Map; }
+
+ /**
+ * @copydoc xn::OutputMetaData::GetUnderlying
+ */
+ inline const XnImageMetaData* GetUnderlying() const { return &m_image; }
+ /**
+ * @copydoc xn::OutputMetaData::GetUnderlying
+ */
+ inline XnImageMetaData* GetUnderlying() { return &m_image; }
+
+ private:
+ // block copy ctor and assignment operator
+ ImageMetaData(const ImageMetaData& other);
+ ImageMetaData& operator=(const ImageMetaData&);
+
+ XnImageMetaData m_image;
+ const xn::ImageMap m_imageMap;
+ xn::ImageMap m_writableImageMap;
+ const xn::RGB24Map m_rgb24Map;
+ xn::RGB24Map m_writableRgb24Map;
+ const xn::Grayscale16Map m_gray16Map;
+ xn::Grayscale16Map m_writableGray16Map;
+ const xn::Grayscale8Map m_gray8Map;
+ xn::Grayscale8Map m_writableGray8Map;
+ };
+
+ /**
+ * @ingroup cppref_meta_data
+ *
+ * <b>Purpose:</b> For saving the @ref glos_frame_object "frame object" (data and configuration)
+ * from an xn::IRGenerator node. This @ref glos_frame_object "frame object" is a snapshot
+ * of the generated infra-red map data and its associated configuration information
+ * at a certain point in time. This saved @ref glos_frame_object "frame object" provides
+ * fast and easy access to the IRGenerator node's data and configuration information.
+ */
+ class IRMetaData : public MapMetaData
+ {
+ public:
+ inline IRMetaData() :
+ MapMetaData(XN_PIXEL_FORMAT_GRAYSCALE_16_BIT, (const XnUInt8**)&m_ir.pData),
+ m_irMap(const_cast<XnIRPixel*&>(m_ir.pData), MapMetaData::GetUnderlying()->Res.X, MapMetaData::GetUnderlying()->Res.Y),
+ m_writableIRMap((XnIRPixel*&)m_pAllocatedData, MapMetaData::GetUnderlying()->Res.X, MapMetaData::GetUnderlying()->Res.Y)
+ {
+ xnOSMemSet(&m_ir, 0, sizeof(XnIRMetaData));
+ m_ir.pMap = MapMetaData::GetUnderlying();
+ }
+
+ /**
+ * @brief Shallow-Copies an IRMetaData object.
+ *
+ * @param [in] other source object.
+ *
+ * @remarks Note that the data buffer is not copied, and that both object will point to the same buffer.
+ */
+ inline void InitFrom(const IRMetaData& other)
+ {
+ xnCopyIRMetaData(&m_ir, &other.m_ir);
+ }
+
+ /**
+ * Shallow copies another IRMetaData object, and then @ref ReAdjust it.
+ *
+ * @param [in] other source object
+ * @param [in] nXRes requested number of columns in the map
+ * @param [in] nYRes requested number of rows in the map
+ * @param [in] pExternalBuffer Optional. An external buffer matching requested resolution. If NULL,
+ * A buffer will be allocated.
+ */
+ inline XnStatus InitFrom(const IRMetaData& other, XnUInt32 nXRes, XnUInt32 nYRes, const XnIRPixel* pExternalBuffer)
+ {
+ InitFrom(other);
+ return ReAdjust(nXRes, nYRes, pExternalBuffer);
+ }
+
+ /**
+ * Performs a deep-copy of another metadata object (including duplication of the data buffer)
+ *
+ * @param [in] other source object
+ */
+ XnStatus CopyFrom(const IRMetaData& other)
+ {
+ // copy props
+ xnCopyIRMetaData(&m_ir, &other.m_ir);
+ // and make a copy of the data (this will allocate and copy data)
+ return MakeDataWritable();
+ }
+
+ /**
+ * @copydoc MapMetaData::ReAdjust
+ */
+ XnStatus ReAdjust(XnUInt32 nXRes, XnUInt32 nYRes, const XnIRPixel* pExternalBuffer = NULL)
+ {
+ return MapMetaData::ReAdjust(nXRes, nYRes, (const XnUInt8*)pExternalBuffer);
+ }
+
+ /**
+ * @brief Returns the IR map.
+ *
+ * <b>Remarks</b>
+ *
+ * This method returns a pointer to the first IR pixel in the map. The IR
+ * map is implemented as a row-major order compact layout of pixels in the map.
+ *
+ * The pixel format of the map is XnIRPixel, i.e. 16-bit integer values.
+ *
+ * This method is reimplemented from the @ref xn::OutputMetaData class.
+ */
+ inline const XnIRPixel* Data() const { return (const XnIRPixel*)MapMetaData::Data(); }
+ /**
+ * @brief Returns the IR map.
+ *
+ * <b>Remarks</b>
+ *
+ * This method returns a pointer to the first IR pixel in the map. The IR
+ * map is implemented as a row-major order compact layout of pixels in the map.
+ *
+ * The pixel format of the map is XnIRPixel, i.e. 16-bit integer values.
+ *
+ * This method is reimplemented from the @ref xn::OutputMetaData class.
+ */
+ inline const XnIRPixel*& Data() { return (const XnIRPixel*&)MapMetaData::Data(); }
+ /**
+ * @copydoc OutputMetaData::WritableData
+ */
+ inline XnIRPixel* WritableData() { return (XnIRPixel*)MapMetaData::WritableData(); }
+
+ /**
+ * Gets the value of a single pixel of the frame map by its index in the array.
+ *
+ * @param [in] nIndex The index of the pixel in the buffer.
+ */
+ inline const XnIRPixel& operator[](XnUInt32 nIndex) const
+ {
+ XN_ASSERT(nIndex < (XRes()*YRes()));
+ return Data()[nIndex];
+ }
+
+ /**
+ * Gets the value of a single pixel of the frame map by its X and Y coordinates.
+ *
+ * @param [in] x X-coordinate of the pixel in the map
+ * @param [in] y Y-coordinate of the pixel in the map
+ */
+ inline const XnIRPixel& operator()(XnUInt32 x, XnUInt32 y) const
+ {
+ XN_ASSERT(x < XRes() && y < YRes());
+ return Data()[y*XRes() + x];
+ }
+
+ /**
+ * @brief Gets a fast, light object wrapping the IR map.
+ * <b>Remarks</b>
+ *
+ * The Map Wrapper classes are light wrappers for generated maps saved as @ref glos_frame_object
+ * "frame objects" in metadata. These wrapper classes provide small data-focused
+ * objects for simplified data access to frame objects.
+ */
+ inline const xn::IRMap& IRMap() const { return m_irMap; }
+ /**
+ * @brief Gets a fast, light object wrapping the writable IR map.
+ * <b>Remarks</b>
+ *
+ * The Map Wrapper classes are light wrappers for generated maps saved as @ref glos_frame_object
+ * "frame objects" in metadata. These wrapper classes provide small data-focused
+ * objects for simplified data access to frame objects.
+ */
+ inline xn::IRMap& WritableIRMap() { MakeDataWritable(); return m_writableIRMap; }
+
+ /**
+ * @copydoc OutputMetaData::GetUnderlying
+ */
+ inline const XnIRMetaData* GetUnderlying() const { return &m_ir; }
+ /**
+ * @copydoc OutputMetaData::GetUnderlying
+ */
+ inline XnIRMetaData* GetUnderlying() { return &m_ir; }
+
+ private:
+ // block copy ctor and assignment operator
+ IRMetaData(const IRMetaData& other);
+ IRMetaData& operator=(const IRMetaData&);
+
+ XnIRMetaData m_ir;
+ const xn::IRMap m_irMap;
+ xn::IRMap m_writableIRMap;
+ };
+
+ /**
+ * @ingroup cppref_meta_data
+ * For saving the audio data from the @ref xn::AudioGenerator node.
+ * This saved metadata object provides fast and easy access to the AudioGenerator node's
+ * data and configuration information.
+ */
+ class AudioMetaData : public OutputMetaData
+ {
+ public:
+ XN_PRAGMA_START_DISABLED_WARNING_SECTION(XN_UNALIGNED_ADDRESS_WARNING_ID);
+ inline AudioMetaData() : OutputMetaData(&m_audio.pData)
+ {
+ xnOSMemSet(&m_audio, 0, sizeof(XnAudioMetaData));
+ m_audio.pOutput = OutputMetaData::GetUnderlying();
+ }
+
+ XN_PRAGMA_STOP_DISABLED_WARNING_SECTION;
+
+ /**
+ * @brief Shallow-Copies an AudioMetaData object.
+ *
+ * @param [in] other source object.
+ *
+ * @remarks Note that the data buffer is not copied, and that both object will point to the same buffer.
+ */
+ inline void InitFrom(const AudioMetaData& other)
+ {
+ xnCopyAudioMetaData(&m_audio, &other.m_audio);
+ }
+
+ /**
+ * @brief Gets the number of channels in each sample. This is a packet configuration setting associated with the saved audio metadata object.
+ */
+ inline XnUInt8 NumberOfChannels() const { return m_audio.Wave.nChannels; }
+ /**
+ * @brief Gets the number of channels in each sample. This is a packet configuration setting associated with the saved audio metadata object.
+ */
+ inline XnUInt8& NumberOfChannels() { return m_audio.Wave.nChannels; }
+
+ /**
+ * @brief Gets the rate at which the audio interface was sampled. This is a packet configuration setting associated with the saved audio metadata object.
+ */
+ inline XnUInt32 SampleRate() const { return m_audio.Wave.nSampleRate; }
+ /**
+ * @brief Gets the rate at which the audio interface was sampled. This is a packet configuration setting associated with the saved audio metadata object.
+ */
+ inline XnUInt32& SampleRate() { return m_audio.Wave.nSampleRate; }
+
+ /**
+ * @brief Gets the number of bits per channel in a sample. This is a packet configuration setting associated with the saved audio metadata object.
+ */
+ inline XnUInt16 BitsPerSample() const { return m_audio.Wave.nBitsPerSample; }
+ /**
+ * @brief Gets the number of bits per channel in a sample. This is a packet configuration setting associated with the saved audio metadata object.
+ */
+ inline XnUInt16& BitsPerSample() { return m_audio.Wave.nBitsPerSample; }
+
+ /**
+ * @copydoc OutputMetaData::GetUnderlying
+ */
+ inline const XnAudioMetaData* GetUnderlying() const { return &m_audio; }
+ /**
+ * @copydoc OutputMetaData::GetUnderlying
+ */
+ inline XnAudioMetaData* GetUnderlying() { return &m_audio; }
+
+ private:
+ // block copy ctor and assignment operator
+ AudioMetaData(const AudioMetaData& other);
+ AudioMetaData& operator=(const AudioMetaData&);
+
+ XnAudioMetaData m_audio;
+ };
+
+ /**
+ * @ingroup cppref_meta_data
+ * Saves the @ref glos_frame_object "frame object" (data and configuration)
+ * from the @ref xn::SceneAnalyzer node. This @ref glos_frame_object "frame object"
+ * is a snapshot of the generated scene data and its associated configuration information
+ * at a certain point in time. This metadata provides fast and easy access to the SceneAnalyzer
+ * node's saved frame object.
+ */
+ class SceneMetaData : public MapMetaData
+ {
+ public:
+ inline SceneMetaData() :
+ MapMetaData(XN_PIXEL_FORMAT_GRAYSCALE_16_BIT, (const XnUInt8**)&m_scene.pData),
+ m_labelMap(const_cast<XnLabel*&>(m_scene.pData), MapMetaData::GetUnderlying()->Res.X, MapMetaData::GetUnderlying()->Res.Y),
+ m_writableLabelMap((XnLabel*&)m_pAllocatedData, MapMetaData::GetUnderlying()->Res.X, MapMetaData::GetUnderlying()->Res.Y)
+ {
+ xnOSMemSet(&m_scene, 0, sizeof(XnSceneMetaData));
+ m_scene.pMap = MapMetaData::GetUnderlying();
+ }
+
+ /**
+ * @brief Shallow-Copies an SceneMetaData object.
+ *
+ * @param [in] other source object.
+ *
+ * @remarks Note that the data buffer is not copied, and that both object will point to the same buffer.
+ */
+ inline void InitFrom(const SceneMetaData& other)
+ {
+ xnCopySceneMetaData(&m_scene, &other.m_scene);
+ }
+
+ /**
+ * Shallow copies another SceneMetaData object, and then @ref ReAdjust it.
+ *
+ * @param [in] other source object
+ * @param [in] nXRes requested number of columns in the map
+ * @param [in] nYRes requested number of rows in the map
+ * @param [in] pExternalBuffer Optional. An external buffer matching requested resolution. If NULL,
+ * A buffer will be allocated.
+ */
+ inline XnStatus InitFrom(const SceneMetaData& other, XnUInt32 nXRes, XnUInt32 nYRes, const XnLabel* pExternalBuffer)
+ {
+ InitFrom(other);
+ return ReAdjust(nXRes, nYRes, pExternalBuffer);
+ }
+
+ /**
+ * Performs a deep-copy of another metadata object (including duplication of the data buffer)
+ *
+ * @param [in] other source object
+ */
+ XnStatus CopyFrom(const SceneMetaData& other)
+ {
+ // copy props
+ xnCopySceneMetaData(&m_scene, &other.m_scene);
+ // and make a copy of the data (this will allocate and copy data)
+ return MakeDataWritable();
+ }
+
+ /**
+ * @copydoc DepthMetaData::ReAdjust
+ */
+ XnStatus ReAdjust(XnUInt32 nXRes, XnUInt32 nYRes, const XnLabel* pExternalBuffer = NULL)
+ {
+ return MapMetaData::ReAdjust(nXRes, nYRes, (const XnUInt8*)pExternalBuffer);
+ }
+
+ /**
+ * @brief Returns the scene map.
+ *
+ * <b>Remarks</b>
+ *
+ * This method returns a pointer to the first scene pixel in the map. The scene
+ * map is implemented as a row-major order compact layout of pixels in the map.
+ *
+ * The pixel format of the map is XnLabel, i.e. 16-bit integer values, where every
+ * user has a distinct label.
+ *
+ * This method is reimplemented from the @ref xn::OutputMetaData class.
+ */
+ inline const XnLabel* Data() const { return (const XnLabel*)MapMetaData::Data(); }
+ /**
+ * @brief Returns the scene map.
+ *
+ * <b>Remarks</b>
+ *
+ * This method returns a pointer to the first scene pixel in the map. The scene
+ * map is implemented as a row-major order compact layout of pixels in the map.
+ *
+ * The pixel format of the map is XnLabel, i.e. 16-bit integer values, where every
+ * user has a distinct label.
+ *
+ * This method is reimplemented from the @ref xn::OutputMetaData class.
+ */
+ inline const XnLabel*& Data() { return (const XnLabel*&)MapMetaData::Data(); }
+
+ /**
+ * @copydoc OutputMetaData::WritableData
+ */
+ inline XnLabel* WritableData() { return (XnLabel*)MapMetaData::WritableData(); }
+
+ /**
+ * Gets a light object wrapping the label map
+ */
+ inline const xn::LabelMap& LabelMap() const { return m_labelMap; }
+ /**
+ * Gets a light object wrapping the writable label map
+ */
+ inline xn::LabelMap& WritableLabelMap() { MakeDataWritable(); return m_writableLabelMap; }
+
+ /**
+ * Gets the label of a single pixel of the frame map by its index in the array.
+ *
+ * @param [in] nIndex The index of the pixel in the buffer.
+ *
+ * <b>Remarks</b>
+ *
+ * The values are of type @ref XnLabel. Each pixel's value labels it according to
+ * user.
+ */
+ inline const XnLabel& operator[](XnUInt32 nIndex) const
+ {
+ XN_ASSERT(nIndex < (XRes()*YRes()));
+ return Data()[nIndex];
+ }
+
+ /**
+ * Gets the label of a single pixel of the frame map by its X and Y positions.
+ *
+ * @param [in] x X-coordinate of the pixel in the map
+ * @param [in] y Y-coordinate of the pixel in the map
+ *
+ * <b>Remarks</b>
+ *
+ * The values are of type @ref XnLabel. Each pixel's value labels it according to
+ * user.
+ */
+ inline const XnLabel& operator()(XnUInt32 x, XnUInt32 y) const
+ {
+ XN_ASSERT(x < XRes() && y < YRes());
+ return (*this)[y*XRes() + x];
+ }
+
+ /**
+ * @copydoc OutputMetaData::GetUnderlying
+ */
+ inline const XnSceneMetaData* GetUnderlying() const { return &m_scene; }
+ /**
+ * @copydoc OutputMetaData::GetUnderlying
+ */
+ inline XnSceneMetaData* GetUnderlying() { return &m_scene; }
+
+ private:
+ // block copy ctor and assignment operator
+ SceneMetaData(const SceneMetaData& other);
+ SceneMetaData& operator=(const SceneMetaData&);
+
+ XnSceneMetaData m_scene;
+ const xn::LabelMap m_labelMap;
+ xn::LabelMap m_writableLabelMap;
+ };
+
+ //---------------------------------------------------------------------------
+ // NodeWrapper
+ //---------------------------------------------------------------------------
+
+ /**
+ * @ingroup cppref_prd_func
+ * <b>Purpose:</b> The NodeWrapper class is the base class for all OpenNI production
+ * node classes in C++, for example, the @ref xn::ProductionNode class and the @ref
+ * xn::Generator class.
+ *
+ * The NodeWrapper class is the C++ API wrapper around the OpenNI C XnNodeHandle API.
+ *
+ * <b>Remarks:</b>
+ *
+ * A fundamental OpenNI concept that is critical to understand about nodes and node
+ * creation is that all C++ objects are "smart pointers" to the actual nodes. The reason
+ * why OpenNI is designed this way is so that the same node can be used to produce data
+ * (or provide information) for more than just one (dependant) node or for more than
+ * just one software component.
+ *
+ * When instantiating an object of this class, it doesn't point to any actual node. In order
+ * to create an actual node, use one of the <code>Create()</code> methods (e.g. @ref DepthGenerator::Create()).
+ */
+ class NodeWrapper
+ {
+ public:
+ friend class Context;
+
+ /**
+ * Ctor
+ *
+ * @param [in] hNode A node handle.
+ */
+ inline NodeWrapper(XnNodeHandle hNode) : m_hNode(NULL), m_hShuttingDownCallback(NULL)
+ {
+ SetHandle(hNode);
+ }
+
+ inline NodeWrapper(const NodeWrapper& other) : m_hNode(NULL), m_hShuttingDownCallback(NULL)
+ {
+ SetHandle(other.GetHandle());
+ }
+
+ inline NodeWrapper& operator=(const NodeWrapper& other)
+ {
+ SetHandle(other.GetHandle());
+ return *this;
+ }
+
+ inline ~NodeWrapper()
+ {
+ SetHandle(NULL);
+ }
+
+ inline operator XnNodeHandle() const { return GetHandle(); }
+
+ /**
+ * Gets the underlying C handle.
+ */
+ inline XnNodeHandle GetHandle() const { return m_hNode; }
+
+ /**
+ * Checks if two node references point to the same actual node
+ *
+ * @param [in] other Another object
+ */
+ inline XnBool operator==(const NodeWrapper& other)
+ {
+ return (GetHandle() == other.GetHandle());
+ }
+
+ /**
+ * Checks if two node references do <i>not</i> point to the same actual node.
+ *
+ * @param [in] other Another object
+ */
+ inline XnBool operator!=(const NodeWrapper& other)
+ {
+ return (GetHandle() != other.GetHandle());
+ }
+
+ /** @brief
+ * This method checks that this object points to an <i>actual</i> node (that has
+ * been 'created') and does not point to NULL.
+ *
+ * Returns TRUE if the object points to a node, i.e., the node has been 'created';
+ * FALSE otherwise.
+ *
+ * <b>Remarks</b>
+ *
+ * This method is a very important for managing nodes in the production graph. This
+ * check is concerned with the stage before actually creating the node, i.e., before
+ * invoking the node's <code>Create()</code> method.
+ */
+ inline XnBool IsValid() const { return (GetHandle() != NULL); }
+
+ /*
+ * @brief Gets the instance name of a node. Unless the application made a specific
+ * request for a specific name, the name will be of the form: "Depth1", "Image2", etc.
+ */
+ const XnChar* GetName() const {return xnGetNodeName(GetHandle()); }
+
+ /**
+ * @copybrief xnProductionNodeAddRef
+ * For full details and usage, see @ref xnProductionNodeAddRef
+ */
+ inline XnStatus AddRef() { return xnProductionNodeAddRef(GetHandle()); }
+
+ /**
+ * Unreference a production node, decreasing its reference count by 1. If the reference count reaches
+ * zero, the node will be destroyed.
+ */
+ inline void Release()
+ {
+ SetHandle(NULL);
+ }
+
+
+ /**
+ * Replaces the object being pointed.
+ */
+ inline void SetHandle(XnNodeHandle hNode)
+ {
+ if (m_hNode == hNode)
+ {
+ // Optimization: do nothing
+ return;
+ }
+
+ // check currently held node. If we're holding a node, release it
+ if (m_hNode != NULL)
+ {
+ XnContext* pContext = xnGetRefContextFromNodeHandle(m_hNode);
+ xnContextUnregisterFromShutdown(pContext, m_hShuttingDownCallback);
+ xnContextRelease(pContext);
+ xnProductionNodeRelease(m_hNode);
+ }
+
+ // check new node handle, if it points to a node, add ref to it
+ if (hNode != NULL)
+ {
+ XnStatus nRetVal = xnProductionNodeAddRef(hNode);
+ XN_ASSERT(nRetVal == XN_STATUS_OK);
+ XN_REFERENCE_VARIABLE(nRetVal);
+
+ XnContext* pContext = xnGetRefContextFromNodeHandle(hNode);
+
+ nRetVal = xnContextRegisterForShutdown(pContext, ContextShuttingDownCallback, this, &m_hShuttingDownCallback);
+ XN_ASSERT(nRetVal == XN_STATUS_OK);
+
+ xnContextRelease(pContext);
+ }
+
+ m_hNode = hNode;
+ }
+
+ inline void TakeOwnership(XnNodeHandle hNode)
+ {
+ SetHandle(hNode);
+
+ if (hNode != NULL)
+ {
+ xnProductionNodeRelease(hNode);
+ }
+ }
+
+ /** @cond */
+ inline XnStatus XN_API_DEPRECATED("Please use AddRef() instead.") Ref() { return AddRef(); }
+ inline void XN_API_DEPRECATED("Please use Release() instead.") Unref() { Release(); }
+ /** @endcond */
+
+ private:
+ XnNodeHandle m_hNode;
+ XnCallbackHandle m_hShuttingDownCallback;
+
+ static void XN_CALLBACK_TYPE ContextShuttingDownCallback(XnContext* /*pContext*/, void* pCookie)
+ {
+ NodeWrapper* pThis = (NodeWrapper*)pCookie;
+ pThis->m_hNode = NULL;
+ }
+ };
+
+ //---------------------------------------------------------------------------
+ // Node Info
+ //---------------------------------------------------------------------------
+
+ /**
+ * @ingroup cppref_graph_mgmt
+ * <b>Purpose:</b> This class provides functionality for getting information about a
+ * @ref node_alternative "node alternative". A @ref node_alternative is either an existing
+ * node, or a not-yet instantiated alternative.
+ *
+ * <b>Remarks:</b>
+ *
+ * Each instantiated node has a NodeInfo object and it can be accessed through the @ref
+ * xn::ProductionNode::GetInfo() method.
+ */
+ class NodeInfo
+ {
+ public:
+ /**
+ * Ctor
+ *
+ * @param [in] pInfo The C object to wrap
+ */
+ NodeInfo(XnNodeInfo* pInfo) : m_pNeededNodes(NULL), m_bOwnerOfNode(FALSE)
+ {
+ SetUnderlyingObject(pInfo);
+ }
+
+ /**
+ * Copy Ctor
+ *
+ * @param [in] other An object to copy from.
+ */
+ NodeInfo(const NodeInfo& other) : m_pNeededNodes(NULL), m_bOwnerOfNode(FALSE)
+ {
+ SetUnderlyingObject(other.m_pInfo);
+ }
+
+ /**
+ * Dtor
+ */
+ ~NodeInfo()
+ {
+ SetUnderlyingObject(NULL);
+ }
+
+ /**
+ * Assignment operator
+ *
+ * @param [in] other another object
+ */
+ inline NodeInfo& operator=(const NodeInfo& other)
+ {
+ SetUnderlyingObject(other.m_pInfo);
+ return *this;
+ }
+
+ /**
+ * Gets the underlying C object
+ */
+ inline operator XnNodeInfo*()
+ {
+ return m_pInfo;
+ }
+
+ /**
+ * @brief Sets the instance name of the NodeInfo object. The name can only be set <i>before the instance is created</i>.
+ *
+ * @param [in] strName Name to give to this instance.
+ */
+ inline XnStatus SetInstanceName(const XnChar* strName)
+ {
+ return xnNodeInfoSetInstanceName(m_pInfo, strName);
+ }
+
+ /**
+ * @brief Gets the description of a node alternative.
+ *
+ * <b>Remarks</b>
+ *
+ * When you instantiate a production node object -- for example a DepthGenerator
+ * -- you cannot access it's NodeInfo object until after <code>Create()</code>
+ * has been called.
+ *
+ * However - you can also get NodeInfo objects by enumeration, for example, from
+ * the @ref xn::Context::EnumerateProductionTrees() "EnumerateProductionTrees()"
+ * method.
+ */
+ inline const XnProductionNodeDescription& GetDescription() const
+ {
+ return *xnNodeInfoGetDescription(m_pInfo);
+ }
+
+ /**
+ * @brief Gets the instance name of a node alternative.
+ *
+ * <b>Remarks</b>
+ *
+ * When you instantiate a DepthGenerator object, for example, you cannot access
+ * it's NodeInfo object until after its <code>Create()</code> method has been called.
+ *
+ * However - you can also get NodeInfo objects by enumeration, for example, from
+ * the EnumerateProductionTrees() method.
+ */
+ inline const XnChar* GetInstanceName() const
+ {
+ return xnNodeInfoGetInstanceName(m_pInfo);
+ }
+
+ /**
+ * @brief Gets the creation information of the node alternative.
+ *
+ * <b>Remarks</b>
+ *
+ * A node's creation information is a way for a node implementation to have two
+ * distinct instances of the same node class, that is two nodes.
+ * For example, a Device node implementation can use this field for the name of
+ * the device it represents, so that if two sensors are connected, each will have
+ * a different value here.
+ */
+ inline const XnChar* GetCreationInfo() const
+ {
+ return xnNodeInfoGetCreationInfo(m_pInfo);
+ }
+
+ /*
+ * @brief Gets the list of dependant nodes for this node alternative.
+ * These are any other node alternatives that the node is dependant on.
+ */
+ inline NodeInfoList& GetNeededNodes() const;
+
+ /**
+ * Gets a reference to the node instance represented by this node alternative.
+ *
+ * @param node [in/out] The production node to be pointing to the node.
+ *
+ * @returns an error if this node info object does not point to an actual node.
+ */
+ inline XnStatus GetInstance(ProductionNode& node) const;
+
+ /**
+ * @copybrief xnNodeInfoGetAdditionalData
+ * For full details and usage, see @ref xnNodeInfoGetAdditionalData
+ */
+ inline const void* GetAdditionalData() const
+ {
+ return xnNodeInfoGetAdditionalData(m_pInfo);
+ }
+
+ /**
+ * @copybrief xnNodeInfoGetTreeStringRepresentation
+ * For full details and usage, see @ref xnNodeInfoGetTreeStringRepresentation
+ */
+ inline XnStatus GetTreeStringRepresentation(XnChar* csResultBuffer, XnUInt32 nBufferSize) const
+ {
+ return xnNodeInfoGetTreeStringRepresentation(m_pInfo, csResultBuffer, nBufferSize);
+ }
+
+ private:
+ inline void SetUnderlyingObject(XnNodeInfo* pInfo);
+
+ XnNodeInfo* m_pInfo;
+ mutable NodeInfoList* m_pNeededNodes;
+ XnBool m_bOwnerOfNode; // backwards compatibility
+ friend class Context;
+ };
+
+ //---------------------------------------------------------------------------
+ // Query
+ //---------------------------------------------------------------------------
+
+ /**
+ * @ingroup cppref_graph_mgmt
+ *
+ * <b>Purpose:</b> Represents a query, containing filters regarding node info objects.
+ * Note that the relation between the filters is an AND relation.
+ *
+ * <b>Usage: </b> Instantiate a Query object and then use the provided methods to set
+ * up the filter conditions.
+ *
+ * <b>Remarks:</b>
+ * The Query class provides a mechanism for searching and returning NodeInfo objects
+ * from a list while filtering them according to a filter argument. The relation between
+ * the filters is an AND relationship.
+ *
+ * The mechanism works by instantiating a Query object and then using the provided methods
+ * to set up the filter conditions. The Query object is then used by a number of methods
+ * that search for nodes, e.g., the Create() method.
+ */
+ class Query
+ {
+ public:
+ inline Query() : m_bAllocated(TRUE)
+ {
+ xnNodeQueryAllocate(&m_pQuery);
+ }
+
+ inline Query(XnNodeQuery* pNodeQuery) : m_bAllocated(FALSE), m_pQuery(pNodeQuery)
+ {
+ }
+
+ ~Query()
+ {
+ if (m_bAllocated)
+ {
+ xnNodeQueryFree(m_pQuery);
+ }
+ }
+
+ /**
+ * Gets the underlying C object
+ */
+ inline const XnNodeQuery* GetUnderlyingObject() const { return m_pQuery; }
+ inline XnNodeQuery* GetUnderlyingObject() { return m_pQuery; }
+
+ /**
+ * @brief Sets in the Query object the vendor name to search for.
+ * @param [in] strVendor Vendor Name.
+ */
+ inline XnStatus SetVendor(const XnChar* strVendor)
+ {
+ return xnNodeQuerySetVendor(m_pQuery, strVendor);
+ }
+
+ /**
+ * @brief Sets in the Query object the implementation name to search for.
+ * The same vendor might have more than one implementation, for example,
+ * two @ref xn::DepthGenerator "DepthGenerators" "SensorV2" and "EEDepthGenerator".
+ * This is not the same as the instance name.
+ *
+ * @param [in] strName Implementation name.
+ */
+ inline XnStatus SetName(const XnChar* strName)
+ {
+ return xnNodeQuerySetName(m_pQuery, strName);
+ }
+
+ /**
+ * @brief Sets in the Query object the minimum required version allowed for the @ref node_alternative.
+ */
+ inline XnStatus SetMinVersion(const XnVersion& minVersion)
+ {
+ return xnNodeQuerySetMinVersion(m_pQuery, &minVersion);
+ }
+
+ /**
+ * @brief Sets in the Query object the minimum required version allowed for the @ref node_alternative.
+ */
+ inline XnStatus SetMinVersion(const Version& minVersion)
+ {
+ return xnNodeQuerySetMinVersion(m_pQuery, minVersion.GetUnderlying());
+ }
+
+ /**
+ * @brief Sets in the Query object the maximum required version allowed for the node alternative.
+ */
+ inline XnStatus SetMaxVersion(const XnVersion& maxVersion)
+ {
+ return xnNodeQuerySetMaxVersion(m_pQuery, &maxVersion);
+ }
+
+ /**
+ * @brief Sets in the Query object the maximum required version allowed for the node alternative.
+ */
+ inline XnStatus SetMaxVersion(const Version& maxVersion)
+ {
+ return xnNodeQuerySetMaxVersion(m_pQuery, maxVersion.GetUnderlying());
+ }
+
+ /**
+ * @brief Sets in the Query object a capability that the @ref node_alternative must support.
+ *
+ * @param [in] strNeededCapability Name of the capability that the @ref node_alternative
+ * must support.
+ *
+ * <b>Remarks</b>
+ *
+ * Note that for checking if a capability is supported, the node must be created
+ * if it's not an already existing node. This operation might take a bit longer
+ * than usual.
+ */
+ inline XnStatus AddSupportedCapability(const XnChar* strNeededCapability)
+ {
+ return xnNodeQueryAddSupportedCapability(m_pQuery, strNeededCapability);
+ }
+
+ /**
+ * @brief Sets in the Query object a MapOutput mode that the @ref node_alternative must support.
+ *
+ * @param [in] MapOutputMode Map output mode. Each field of the mode can be set to
+ * (-1), meaning results will not be filtered by this field.
+ *
+ * @remark Note that for checking if a capability is supported, the node must be created
+ * if it's not an already existing node. This operation might take a bit longer
+ * than usual.
+ */
+ inline XnStatus AddSupportedMapOutputMode(const XnMapOutputMode& MapOutputMode)
+ {
+ return xnNodeQueryAddSupportedMapOutputMode(m_pQuery, &MapOutputMode);
+ }
+
+ /**
+ * @copybrief xnNodeQuerySetSupportedMinUserPositions
+ * For full details and usage, see @ref xnNodeQuerySetSupportedMinUserPositions
+ */
+ inline XnStatus SetSupportedMinUserPositions(const XnUInt32 nCount)
+ {
+ return xnNodeQuerySetSupportedMinUserPositions(m_pQuery, nCount);
+ }
+
+ /**
+ * @brief Sets in the Query object that the query will return only existing nodes,
+ * i.e., nodes that have been created, in other words their <code>Create()</code> method has been called.
+ *
+ * @param [in] bExistingNode TRUE to return only existing nodes, FALSE otherwise.
+ *
+ * <b>Remarks</b>
+ *
+ * Note that there are many ways to create nodes, not just by their @ref create_method
+ * "Create() method".
+ */
+ inline XnStatus SetExistingNodeOnly(XnBool bExistingNode)
+ {
+ return xnNodeQuerySetExistingNodeOnly(m_pQuery, bExistingNode);
+ }
+
+ /**
+ * @brief Sets in the Query object that a specified node must be a dependant of the named node type.
+ * @param [in] strInstanceName Name of the needed node.
+ */
+ inline XnStatus AddNeededNode(const XnChar* strInstanceName)
+ {
+ return xnNodeQueryAddNeededNode(m_pQuery, strInstanceName);
+ }
+
+ /**
+ * @brief Sets the creation information field of the Query object. This relates to the creation information of the @ref xn::NodeInfo class.
+ * @param [in] strCreationInfo Creation information to set in the Query object.
+ */
+ inline XnStatus SetCreationInfo(const XnChar* strCreationInfo)
+ {
+ return xnNodeQuerySetCreationInfo(m_pQuery, strCreationInfo);
+ }
+
+ private:
+ XnNodeQuery* m_pQuery;
+ XnBool m_bAllocated;
+ };
+
+ //---------------------------------------------------------------------------
+ // Node Info List
+ //---------------------------------------------------------------------------
+
+ /**
+ * @ingroup cppref_graph_mgmt
+ * A NodeInfoList object contains a list of @ref NodeInfo objects.
+ */
+ class NodeInfoList
+ {
+ public:
+ /**
+ * Represents an iterator over a @ref NodeInfoList list.
+ */
+ class Iterator
+ {
+ public:
+ friend class NodeInfoList;
+
+ /**
+ * Returns whether the iterator points to the same location as another iterator.
+ *
+ * @param [in] other Another iterator
+ *
+ * <b>Remarks</b>
+ *
+ * This method can be used for checking if the two iterators are pointing to
+ * the same NodeInfo object.
+ *
+ * Note that the two iterators can also both point to NULL.
+ */
+ XnBool operator==(const Iterator& other) const
+ {
+ return m_it.pCurrent == other.m_it.pCurrent;
+ }
+
+ /**
+ * Returns whether the iterator points to a different location than another
+ * iterator.
+ *
+ * @param [in] other Another iterator
+ */
+ XnBool operator!=(const Iterator& other) const
+ {
+ return m_it.pCurrent != other.m_it.pCurrent;
+ }
+
+ /**
+ * Moves the iterator to the next object. If the end of the list was reached,
+ * the iterator will now be equal to @ref NodeInfoList::End().
+ */
+ inline Iterator& operator++()
+ {
+ UpdateInternalObject(xnNodeInfoListGetNext(m_it));
+ return *this;
+ }
+
+ /**
+ * Returns an iterator pointing at the next object. If the end of the list was
+ * reached, that iterator will now be equal to @ref NodeInfoList::End().
+ */
+ inline Iterator operator++(int)
+ {
+ XnNodeInfoListIterator curr = m_it;
+ UpdateInternalObject(xnNodeInfoListGetNext(m_it));
+ return Iterator(curr);
+ }
+
+ /**
+ * Moves the iterator to the previous object.
+ */
+ inline Iterator& operator--()
+ {
+ UpdateInternalObject(xnNodeInfoListGetPrevious(m_it));
+ return *this;
+ }
+
+ /**
+ * Returns an iterator pointing at the previous object.
+ */
+ inline Iterator operator--(int)
+ {
+ XnNodeInfoListIterator curr = m_it;
+ UpdateInternalObject(xnNodeInfoListGetPrevious(m_it));
+ return Iterator(curr);
+ }
+
+ /**
+ * Gets the @ref NodeInfo object pointed by the iterator.
+ */
+ inline NodeInfo operator*()
+ {
+ return m_Info;
+ }
+
+ private:
+ inline Iterator(XnNodeInfoListIterator it) : m_Info(NULL)
+ {
+ UpdateInternalObject(it);
+ }
+
+ inline void UpdateInternalObject(XnNodeInfoListIterator it)
+ {
+ m_it = it;
+ if (xnNodeInfoListIteratorIsValid(it))
+ {
+ XnNodeInfo* pInfo = xnNodeInfoListGetCurrent(it);
+ m_Info = NodeInfo(pInfo);
+ }
+ else
+ {
+ m_Info = NodeInfo(NULL);
+ }
+ }
+
+ NodeInfo m_Info;
+ XnNodeInfoListIterator m_it;
+ };
+
+ /**
+ * Creates a new @ref NodeInfoList object.
+ */
+ inline NodeInfoList()
+ {
+ xnNodeInfoListAllocate(&m_pList);
+ m_bAllocated = TRUE;
+ }
+
+ /**
+ * Creates a new @ref NodeInfoList object by wrapping a C @ref XnNodeInfoList object.
+ * Note that this list will not be freed upon destruction.
+ *
+ * @param [in] pList The list to wrap.
+ */
+ inline NodeInfoList(XnNodeInfoList* pList) : m_pList(pList), m_bAllocated(FALSE) {}
+
+ inline ~NodeInfoList()
+ {
+ FreeImpl();
+ }
+
+ /**
+ * Gets the underlying C object.
+ */
+ inline XnNodeInfoList* GetUnderlyingObject() const { return m_pList; }
+
+ /**
+ * Replaces the underlying object, taking ownership of the object (meaning, it
+ * will be freed upon destruction).
+ *
+ * @param [in] pList The list to wrap.
+ */
+ inline void ReplaceUnderlyingObject(XnNodeInfoList* pList)
+ {
+ FreeImpl();
+ m_pList = pList;
+ m_bAllocated = TRUE;
+ }
+
+ /**
+ * @copybrief xnNodeInfoListAdd
+ * For full details and usage, see @ref xnNodeInfoListAdd
+ */
+ inline XnStatus Add(XnProductionNodeDescription& description, const XnChar* strCreationInfo, NodeInfoList* pNeededNodes)
+ {
+ XnNodeInfoList* pList = (pNeededNodes == NULL) ? NULL : pNeededNodes->GetUnderlyingObject();
+ return xnNodeInfoListAdd(m_pList, &description, strCreationInfo, pList);
+ }
+
+ /**
+ * @copybrief xnNodeInfoListAddEx
+ * For full details and usage, see @ref xnNodeInfoListAddEx
+ */
+ inline XnStatus AddEx(XnProductionNodeDescription& description, const XnChar* strCreationInfo, NodeInfoList* pNeededNodes, const void* pAdditionalData, XnFreeHandler pFreeHandler)
+ {
+ XnNodeInfoList* pList = (pNeededNodes == NULL) ? NULL : pNeededNodes->GetUnderlyingObject();
+ return xnNodeInfoListAddEx(m_pList, &description, strCreationInfo, pList, pAdditionalData, pFreeHandler);
+ }
+
+ /**
+ * @copybrief xnNodeInfoListAddNode
+ * For full details and usage, see @ref xnNodeInfoListAddNode
+ */
+ inline XnStatus AddNode(NodeInfo& info)
+ {
+ return xnNodeInfoListAddNode(m_pList, info);
+ }
+
+ /**
+ * @copybrief xnNodeInfoListAddNodeFromList
+ * For full details and usage, see @ref xnNodeInfoListAddNodeFromList
+ */
+ inline XnStatus AddNodeFromAnotherList(Iterator& it)
+ {
+ return xnNodeInfoListAddNodeFromList(m_pList, it.m_it);
+ }
+
+ /**
+ * Returns an iterator to the beginning of the list. If the list
+ * is empty, that iterator will be equal to @ref NodeInfoList::End().
+ */
+ inline Iterator Begin() const
+ {
+ return Iterator(xnNodeInfoListGetFirst(m_pList));
+ }
+
+ /**
+ * Returns an iterator marking the end of the list.
+ * This iterator does not point to a valid item.
+ */
+ inline Iterator End() const
+ {
+ XnNodeInfoListIterator it = { NULL };
+ return Iterator(it);
+ }
+
+ /**
+ * Returns an iterator to the reverse beginning of the list. If the list
+ * is empty, that iterator will be equal to @ref NodeInfoList::REnd().
+ */
+ inline Iterator RBegin() const
+ {
+ return Iterator(xnNodeInfoListGetLast(m_pList));
+ }
+
+ /**
+ * Returns an iterator marking the reverse end of the list.
+ * This iterator does not point to a valid item.
+ */
+ inline Iterator REnd() const
+ {
+ XnNodeInfoListIterator it = { NULL };
+ return Iterator(it);
+ }
+
+ /**
+ * @copybrief xnNodeInfoListRemove
+ * For full details and usage, see @ref xnNodeInfoListRemove
+ */
+ inline XnStatus Remove(Iterator& it)
+ {
+ return xnNodeInfoListRemove(m_pList, it.m_it);
+ }
+
+ /**
+ * @copybrief xnNodeInfoListClear
+ * For full details and usage, see @ref xnNodeInfoListClear
+ */
+ inline XnStatus Clear()
+ {
+ return xnNodeInfoListClear(m_pList);
+ }
+
+ /**
+ * @copybrief xnNodeInfoListAppend
+ * For full details and usage, see @ref xnNodeInfoListAppend
+ */
+ inline XnStatus Append(NodeInfoList& other)
+ {
+ return xnNodeInfoListAppend(m_pList, other.GetUnderlyingObject());
+ }
+
+ /**
+ * @brief Checks if the list NodeInfoList object is empty.
+ */
+ inline XnBool IsEmpty()
+ {
+ return xnNodeInfoListIsEmpty(m_pList);
+ }
+
+ /**
+ * @copybrief xnNodeQueryFilterList
+ * For full details and usage, see @ref xnNodeQueryFilterList
+ */
+ inline XnStatus FilterList(Context& context, Query& query);
+
+ private:
+ inline void FreeImpl()
+ {
+ if (m_bAllocated)
+ {
+ xnNodeInfoListFree(m_pList);
+ m_bAllocated = FALSE;
+ m_pList = NULL;
+ }
+ }
+
+ XnNodeInfoList* m_pList;
+ XnBool m_bAllocated;
+ };
+
+ //---------------------------------------------------------------------------
+ // Production Nodes Functionality
+ //---------------------------------------------------------------------------
+
+ /**
+ * @ingroup cppref_prd_func
+ * Base class for all capabilities.
+ */
+ class Capability : public NodeWrapper
+ {
+ public:
+ /**
+ * Ctor
+ *
+ * @param [in] hNode The node handle
+ */
+ Capability(XnNodeHandle hNode) : NodeWrapper(hNode) {}
+ Capability(const NodeWrapper& node) : NodeWrapper(node) {}
+ };
+
+ /**
+ * @ingroup cppref_prd_func
+ * <b>Purpose:</b> The Error State capability lets a node report that it has entered
+ * an error state, and so might not function correctly.
+ *
+ * <b>Usage:</b> Do not instantiate directly. Instead, use @ref ProductionNode::GetErrorStateCap()
+ * to obtain an instance.
+ *
+ * <b>Remarks:</b>
+ *
+ * An application can use the @ref GetErrorState() method to get the error state of
+ * a node at any time, and it can also register a callback function to be called whenever
+ * the error state changes.
+ *
+ * The error state of a node is represented using @ref XnStatus. A value of @ref XN_STATUS_OK
+ * means the node is OK. Any other value represents some sort of error situation in
+ * the node.
+ *
+ * <b>Event: 'Error State Change'</b>
+ *
+ * Signals that the @ref holder_node "holder node"'s error state has changed.
+ *
+ * This is the same value that can be obtained by the @ref GetErrorState() method.
+ *
+ * This event can be used by the application to get a signal as soon as any error occurs
+ * in the @ref holder_node "holder node". By handling all the error states of all nodes,
+ * the application can use this event to respond immediately to any error situation.
+ *
+ * Use @ref RegisterToErrorStateChange() and @ref UnregisterFromErrorStateChange() for using this event.
+ *
+ * Instead of registering to the error state callback of all the nodes in the context,
+ * an application may register to the 'Global Error State Change' event - see @ref context_global_error_event.
+ */
+ class ErrorStateCapability : public Capability
+ {
+ public:
+ /**
+ * Ctor
+ *
+ * @param [in] hNode Node handle
+ */
+ ErrorStateCapability(XnNodeHandle hNode) : Capability(hNode) {}
+ ErrorStateCapability(const NodeWrapper& node) : Capability(node) {}
+
+ /**
+ * @brief Gets the current error state of the holding node.
+ */
+ inline XnStatus GetErrorState() const
+ {
+ return xnGetNodeErrorState(GetHandle());
+ }
+
+ /**
+ * @brief Registers an event handler for the 'Error State Change' event.
+ *
+ * @param [in] handler Callback function to be invoked when the event is raised.
+ * @param [in] pCookie User's cookie, to be delivered to the callback.
+ * @param [out] hCallback Handle to the callback. To be used for unregistering the callback.
+ *
+ * For full details and usage of the parameters, see @ref reg_to_events.
+ */
+ inline XnStatus RegisterToErrorStateChange(StateChangedHandler handler, void* pCookie, XnCallbackHandle& hCallback)
+ {
+ return _RegisterToStateChange(xnRegisterToNodeErrorStateChange, GetHandle(), handler, pCookie, hCallback);
+ }
+
+ /**
+ * @brief Unregisters the event handler for the 'Error State Change' event.
+ *
+ * @param [in] hCallback Handle received from registration.
+ *
+ * For full details and usage of the parameter, see @ref unreg_from_events .
+ */
+ inline void UnregisterFromErrorStateChange(XnCallbackHandle hCallback)
+ {
+ _UnregisterFromStateChange(xnUnregisterFromNodeErrorStateChange, GetHandle(), hCallback);
+ }
+ };
+
+ /**
+ * @ingroup cppref_prd_func
+ * Allows access to general integer capabilities functions - see @ref general_int for
+ * additional details.
+ */
+ class GeneralIntCapability : public Capability
+ {
+ public:
+ /**
+ * Ctor
+ *
+ * @param [in] hNode Node handle
+ * @param [in] strCap Name of the capability
+ */
+ GeneralIntCapability(XnNodeHandle hNode, const XnChar* strCap) : Capability(hNode), m_strCap(strCap) {}
+ GeneralIntCapability(const NodeWrapper& node, const XnChar* strCap) : Capability(node), m_strCap(strCap) {}
+
+ /**
+ * @copybrief xnGetGeneralIntRange
+ * For full details and usage, see @ref xnGetGeneralIntRange
+ */
+ inline void GetRange(XnInt32& nMin, XnInt32& nMax, XnInt32& nStep, XnInt32& nDefault, XnBool& bIsAutoSupported) const
+ {
+ xnGetGeneralIntRange(GetHandle(), m_strCap, &nMin, &nMax, &nStep, &nDefault, &bIsAutoSupported);
+ }
+
+ /**
+ * @copybrief xnGetGeneralIntValue
+ * For full details and usage, see @ref xnGetGeneralIntValue
+ */
+ inline XnInt32 Get()
+ {
+ XnInt32 nValue;
+ xnGetGeneralIntValue(GetHandle(), m_strCap, &nValue);
+ return nValue;
+ }
+
+ /**
+ * @copybrief xnSetGeneralIntValue
+ * For full details and usage, see @ref xnSetGeneralIntValue
+ */
+ inline XnStatus Set(XnInt32 nValue)
+ {
+ return xnSetGeneralIntValue(GetHandle(), m_strCap, nValue);
+ }
+
+ /**
+ * @brief Registers an event handler for the 'Value Change' event.
+ *
+ * @param [in] handler Callback function to be invoked when the event is raised.
+ * @param [in] pCookie User's cookie, to be delivered to the callback.
+ * @param [out] hCallback Handle to the callback to be used for unregistering it.
+ *
+ * For full details and usage of the parameters, see @ref reg_to_events.
+ */
+ XnStatus RegisterToValueChange(StateChangedHandler handler, void* pCookie, XnCallbackHandle& hCallback);
+
+ /**
+ * @brief Unregisters the event handler for the 'Value Change' event.
+ *
+ * @param [in] hCallback Handle received from registration.
+ *
+ * For full details and usage of the parameter, see @ref unreg_from_events .
+ */
+ void UnregisterFromValueChange(XnCallbackHandle hCallback);
+
+ private:
+ const XnChar* m_strCap;
+ };
+
+ /**
+ * @ingroup cppref_prd_func
+ * <b>Purpose:</b> The ProductionNode class is a base class for all production nodes
+ * and generator nodes. As such, the ProductionNode class is the fundamental base class
+ * of the entire OpenNI interface for building and accessing the production graph.
+ *
+ * <b>Usage:</b> Base class for all production nodes; not usually instantiated.
+ *
+ * <b>Class Overview:</b>
+ *
+ * The OpenNI Production Graph is comprised entirely of production nodes of one type
+ * or another. The ProductionNode class itself exposes a very limited functionality
+ * set. This is the most basic and common functionality set of all the nodes in the
+ * graph.
+ *
+ * All types of core generator nodes are derived from this ProductionNode class, for
+ * example, the @ref xn::DepthGenerator node and the @ref xn::Device node. Each node
+ * type has its own set of methods that it supports.
+ *
+ * Two of the most important methods provided by the ProductionNode class are @ref IsCapabilitySupported()
+ * and @ref GetContext(), both described further below.
+ *
+ * <b>Capabilities Mechanism:</b>
+ *
+ * In addition to being the base class for all core generator nodes, the ProductionNode
+ * class also provides key support for the OpenNI capabilities mechanism. OpenNI defines
+ * core functionality which is always supported by all node implementations of a specific node
+ * type. Additional optional functionality is also defined by OpenNI and exposed
+ * as "capabilities".
+ * The ProductionNode class provides the @ref IsCapabilitySupported() method to check
+ * if this specific implementation supports a certain capability.
+ *
+ * For a comprehensive overview to the Capabilities mechanism see @ref conc_capabilities
+ * "Capabilities Mechanism".
+ */
+ class ProductionNode : public NodeWrapper
+ {
+ public:
+ /**
+ * Ctor
+ *
+ * @param [in] hNode Node handle
+ */
+ inline ProductionNode(XnNodeHandle hNode = NULL) : NodeWrapper(hNode) {}
+ inline ProductionNode(const NodeWrapper& other) : NodeWrapper(other) {}
+
+ /**
+ * @brief Gets information about the node.
+ *
+ * <b>Remarks</b>
+ *
+ * This method returns a @ref xn::NodeInfo object containing information such as
+ * the node description and the identities of dependent nodes.
+ */
+ inline NodeInfo GetInfo() const { return NodeInfo(xnGetNodeInfo(GetHandle())); }
+
+ /**
+ * @copybrief xnAddNeededNode
+ * For full details and usage, see @ref xnAddNeededNode
+ */
+ inline XnStatus AddNeededNode(ProductionNode& needed)
+ {
+ return xnAddNeededNode(GetHandle(), needed.GetHandle());
+ }
+
+ /**
+ * @copybrief xnRemoveNeededNode
+ * For full details and usage, see @ref xnRemoveNeededNode
+ */
+ inline XnStatus RemoveNeededNode(ProductionNode& needed)
+ {
+ return xnRemoveNeededNode(GetHandle(), needed.GetHandle());
+ }
+
+ /**
+ * @brief Gets the node's context.
+ *
+ * @param [out] context The node's context.
+ *
+ * <b>Remarks</b>
+ *
+ * This method is useful for applications that have to take into account the
+ * possibility of multiple contexts. Using this method, the application can access
+ * all other nodes and other resources within the same context.
+ */
+ inline void GetContext(Context& context) const;
+
+ /**
+ * @brief Gets the node's context
+ *
+ * <b>Remarks</b>
+ *
+ * This method is useful for applications that have to take into account the
+ * possibility of multiple contexts. Using this method, the application can access
+ * all other nodes and other resources within the same context.
+ */
+ inline Context GetContext() const;
+
+ /**
+ * @brief Returns whether a production node supports a specific capability.
+ *
+ * @param [in] strCapabilityName The capability name to check.
+ *
+ * <b>Remarks</b>
+ *
+ * The application specifies the capability by supplying the capability's name in
+ * the <i>strCapabilityName</i> parameter. Before attempting to access any capability
+ * this method should be used to check that this node actually supports this capability.
+ */
+ inline XnBool IsCapabilitySupported(const XnChar* strCapabilityName) const
+ {
+ return xnIsCapabilitySupported(GetHandle(), strCapabilityName);
+ }
+
+ /**
+ * @copybrief xnSetIntProperty
+ * For full details and usage, see @ref xnSetIntProperty
+ */
+ inline XnStatus SetIntProperty(const XnChar* strName, XnUInt64 nValue)
+ {
+ return xnSetIntProperty(GetHandle(), strName, nValue);
+ }
+
+ /**
+ * @copybrief xnSetRealProperty
+ * For full details and usage, see @ref xnSetRealProperty
+ */
+ inline XnStatus SetRealProperty(const XnChar* strName, XnDouble dValue)
+ {
+ return xnSetRealProperty(GetHandle(), strName, dValue);
+ }
+
+ /**
+ * @copybrief xnSetStringProperty
+ * For full details and usage, see @ref xnSetStringProperty
+ */
+ inline XnStatus SetStringProperty(const XnChar* strName, const XnChar* strValue)
+ {
+ return xnSetStringProperty(GetHandle(), strName, strValue);
+ }
+
+ /**
+ * @copybrief xnSetGeneralProperty
+ * For full details and usage, see @ref xnSetGeneralProperty
+ */
+ inline XnStatus SetGeneralProperty(const XnChar* strName, XnUInt32 nBufferSize, const void* pBuffer)
+ {
+ return xnSetGeneralProperty(GetHandle(), strName, nBufferSize, pBuffer);
+ }
+
+ /**
+ * @copybrief xnGetIntProperty
+ * For full details and usage, see @ref xnGetIntProperty
+ */
+ inline XnStatus GetIntProperty(const XnChar* strName, XnUInt64& nValue) const
+ {
+ return xnGetIntProperty(GetHandle(), strName, &nValue);
+ }
+
+ /**
+ * @copybrief xnGetRealProperty
+ * For full details and usage, see @ref xnGetRealProperty
+ */
+ inline XnStatus GetRealProperty(const XnChar* strName, XnDouble &dValue) const
+ {
+ return xnGetRealProperty(GetHandle(), strName, &dValue);
+ }
+
+ /**
+ * @copybrief xnGetStringProperty
+ * For full details and usage, see @ref xnGetStringProperty
+ */
+ inline XnStatus GetStringProperty(const XnChar* strName, XnChar* csValue, XnUInt32 nBufSize) const
+ {
+ return xnGetStringProperty(GetHandle(), strName, csValue, nBufSize);
+ }
+
+ /**
+ * @copybrief xnGetGeneralProperty
+ * For full details and usage, see @ref xnGetGeneralProperty
+ */
+ inline XnStatus GetGeneralProperty(const XnChar* strName, XnUInt32 nBufferSize, void* pBuffer) const
+ {
+ return xnGetGeneralProperty(GetHandle(), strName, nBufferSize, pBuffer);
+ }
+
+ /**
+ * @copybrief xnLockNodeForChanges
+ * For full details and usage, see @ref xnLockNodeForChanges
+ */
+ inline XnStatus LockForChanges(XnLockHandle* phLock)
+ {
+ return xnLockNodeForChanges(GetHandle(), phLock);
+ }
+
+ /**
+ * @copybrief xnUnlockNodeForChanges
+ * For full details and usage, see @ref xnUnlockNodeForChanges
+ */
+ inline void UnlockForChanges(XnLockHandle hLock)
+ {
+ xnUnlockNodeForChanges(GetHandle(), hLock);
+ }
+
+ /**
+ * @copybrief xnLockedNodeStartChanges
+ * For full details and usage, see @ref xnLockedNodeStartChanges
+ */
+ inline XnStatus LockedNodeStartChanges(XnLockHandle hLock)
+ {
+ return xnLockedNodeStartChanges(GetHandle(), hLock);
+ }
+
+ /**
+ * @copybrief xnLockedNodeEndChanges
+ * For full details and usage, see @ref xnLockedNodeEndChanges
+ */
+ inline void LockedNodeEndChanges(XnLockHandle hLock)
+ {
+ xnLockedNodeEndChanges(GetHandle(), hLock);
+ }
+
+ /**
+ * @brief Gets an @ref xn::ErrorStateCapability object for accessing the functionality
+ * of the Error State capability.
+ *
+ * <b>Remarks:</b>
+ * The application is responsible for first checking if @ref XN_CAPABILITY_ERROR_STATE
+ * is supported by calling @ref xn::ProductionNode::IsCapabilitySupported().
+ */
+ inline const ErrorStateCapability GetErrorStateCap() const
+ {
+ return ErrorStateCapability(GetHandle());
+ }
+
+ /**
+ * @brief Gets an @ref xn::ErrorStateCapability object for accessing the functionality
+ * of the Error State capability.
+ *
+ * <b>Remarks:</b>
+ * The application is responsible for first checking if @ref XN_CAPABILITY_ERROR_STATE
+ * is supported by calling @ref xn::ProductionNode::IsCapabilitySupported()
+ */
+ inline ErrorStateCapability GetErrorStateCap()
+ {
+ return ErrorStateCapability(GetHandle());
+ }
+
+ /**
+ * @brief Gets an @ref GeneralIntCapability object for accessing the capability
+ * functionality.
+ *
+ * <b>Remarks:</b>
+ *
+ * It is the application responsibility to check first if the capability is supported
+ * by calling @ref IsCapabilitySupported().
+ *
+ * @param [in] strCapability Name of the capability to get
+ */
+ inline GeneralIntCapability GetGeneralIntCap(const XnChar* strCapability)
+ {
+ return GeneralIntCapability(GetHandle(), strCapability);
+ }
+ };
+
+ /**
+ * @ingroup cppref_prd_func
+ * <b>Purpose:</b> The DeviceIdentificationCapability object allows an application to
+ * receive some device-specific information about a hardware device, like its serial
+ * number and its model name.
+ *
+ * <b>Usage:</b> Do not instantiate directly. Instead, use @ref Device::GetIdentificationCap()
+ * to obtain an instance.
+ */
+ class DeviceIdentificationCapability : public Capability
+ {
+ public:
+ /**
+ * Ctor
+ *
+ * @param [in] hNode Node handle
+ */
+ DeviceIdentificationCapability(XnNodeHandle hNode) : Capability(hNode) {}
+ DeviceIdentificationCapability(const NodeWrapper& node) : Capability(node) {}
+
+ /**
+ * @brief Gets the name of the device holding this capability object.
+ *
+ * @param [in] strBuffer Buffer to accept the device information.
+ * @param [in,out] nBufferSize Size of the buffer.
+ *
+ * @retval XN_STATUS_OK Operation succeeded.
+ * @retval XN_STATUS_OUTPUT_BUFFER_OVERFLOW The size of the buffer is not sufficient.
+ */
+ inline XnStatus GetDeviceName(XnChar* strBuffer, XnUInt32 nBufferSize)
+ {
+ return xnGetDeviceName(GetHandle(), strBuffer, &nBufferSize);
+ }
+
+ /**
+ * @brief Gets the vendor-specific name of the device holding this capability object.
+ *
+ * @param [in] strBuffer Buffer to accept the device information.
+ * @param [in,out] nBufferSize Size of the buffer.
+ *
+ * @retval XN_STATUS_OK Operation succeeded.
+ * @retval XN_STATUS_OUTPUT_BUFFER_OVERFLOW The size of the buffer is not sufficient.
+ */
+ inline XnStatus GetVendorSpecificData(XnChar* strBuffer, XnUInt32 nBufferSize)
+ {
+ return xnGetVendorSpecificData(GetHandle(), strBuffer, &nBufferSize);
+ }
+
+ /**
+ * @brief Gets the vendor-specific name of the device holding this capability object.
+ *
+ * @param [in] strBuffer Buffer to accept the serial number
+ * @param [in,out] nBufferSize Size of the buffer.
+ *
+ * @retval XN_STATUS_OK Operation succeeded.
+ * @retval XN_STATUS_OUTPUT_BUFFER_OVERFLOW The size of the buffer is not sufficient.
+ */
+ inline XnStatus GetSerialNumber(XnChar* strBuffer, XnUInt32 nBufferSize)
+ {
+ return xnGetSerialNumber(GetHandle(), strBuffer, &nBufferSize);
+ }
+ };
+
+ /**
+ * @ingroup cppref_prd_func
+ * <b>Purpose:</b> A smart pointer to a device node in the
+ * production graph of a context.
+ *
+ * The device node represents a physical hardware device
+ * currently connected in the system and used for generating data.
+ * The Device node represents the hardware device by providing, for example,
+ * the device's model name, serial number, and some vendor-specific data.
+ * The Device node itself does not generate data.
+ *
+ * <b>Capabilities:</b> @ref DeviceIdentificationCapability
+ */
+ class Device : public ProductionNode
+ {
+ public:
+ inline Device(XnNodeHandle hNode = NULL) : ProductionNode(hNode) {}
+ inline Device(const NodeWrapper& other) : ProductionNode(other) {}
+
+ /**
+ * @brief Creates a Device node from available @ref node_alternative "production node alternatives".
+ *
+ * <b>Remarks</b>
+ *
+ * See @ref create_method "Concepts: the Create() Method" for a detailed description
+ * of the operation of this method.
+ */
+ inline XnStatus Create(Context& context, Query* pQuery = NULL, EnumerationErrors* pErrors = NULL);
+
+ /**
+ * Gets a @ref DeviceIdentificationCapability object for accessing device identification
+ * functionality.
+ *
+ * <b>Remarks</b>
+ *
+ * If this node supports this method then the node can identify which device is
+ * being used right now, for example, its name, serial number, and specific
+ * vendors can place specific data.
+ *
+ * It is the application's responsibility to check first if @ref XN_CAPABILITY_DEVICE_IDENTIFICATION
+ * is supported by calling @ref IsCapabilitySupported().
+ */
+ inline DeviceIdentificationCapability GetIdentificationCap()
+ {
+ return DeviceIdentificationCapability(GetHandle());
+ }
+ };
+
+ /**
+ * @ingroup cppref_prd_func
+ *
+ * <b>Purpose:</b> Applying the MirrorCapability to a node allows enabling the Mirroring
+ * mode on a per node basis. Compare this with enabling the Global Mirror, which applies
+ * mirroring to any node supporting the Mirroring capability. To understand mirroring
+ * see the Overview below.
+ *
+ * <b>Usage:</b> Do not instantiate directly. Instead, use @ref Generator::GetMirrorCap()
+ * to obtain an instance.
+ *
+ * <b>Remarks:</b>
+ *
+ * When you stand facing the sensor device, and the image is processed directly,
+ * the sensor "sees" your left hand at your right-hand side, and your right hand
+ * at your left-hand side.
+ *
+ * If your movements are used to control an avatar, and that avatar is facing you then
+ * the avatar on the screen is opposite: your right hand is facing the left of the avatar
+ * on the screen, and your left hand is facing the right of the avatar.
+ *
+ * The effect of applying and enabling the Mirroring capability on a node makes all
+ * the data replace right with left, and left with right.
+ *
+ * Thus, if mirroring is <i>disabled</i> (default), then when you raise your right hand,
+ * the avatar on the screen opposite you correspondingly also raises its own right hand,
+ * this being to the left of yourself.
+ *
+ * If mirroring is <i>enabled</i>, when you raise your right hand on the screen the
+ * avatar opposite you mirrors you by raising its hand on your right, which is the avatar's
+ * <i>left</i> hand.
+ *
+ * Enabling mirroring is useful when the avatar is facing the player. Disabling mirroring
+ * is useful when the player sees the avatar from behind (for example in third person
+ * shooters or to see yourself kicking a football).
+ *
+ * Changing the GlobalMirror flag affects mirroring in all existing nodes and in all
+ * nodes to be created in the future - see @ref Context::SetGlobalMirror().
+ *
+ * <b>Event: 'Mirror Change'</b>
+ *
+ * Signals that the @ref holder_node "holder node"'s mirror configuration has been changed (also see @ref event_cmn_conf).
+ *
+ * Use @ref RegisterToMirrorChange() and @ref UnregisterFromMirrorChange() for using this event.
+ *
+ * Calling the @ref SetMirror() method raises this event.
+ */
+ class MirrorCapability : public Capability
+ {
+ public:
+ inline MirrorCapability(XnNodeHandle hNode) : Capability(hNode) {}
+ MirrorCapability(const NodeWrapper& node) : Capability(node) {}
+
+ /**
+ * @brief Sets the current mirror configuration of the @ref holder_node "holder node",
+ * enabling or disabling mirroring. This configuration is used for generating the next frame.
+ *
+ * @param [in] bMirror TRUE for mirroring output, FALSE otherwise.
+ */
+ inline XnStatus SetMirror(XnBool bMirror)
+ {
+ return xnSetMirror(GetHandle(), bMirror);
+ }
+
+ /**
+ * @brief Gets the current mirroring configuration of the @ref holder_node "holder node". This configuration is used for generating the next frame.
+ */
+ inline XnBool IsMirrored() const
+ {
+ return xnIsMirrored(GetHandle());
+ }
+
+ /**
+ * @brief Registers an event handler for the 'Mirror Change' event.
+ *
+ * @param [in] handler Callback function to be invoked when the event is raised.
+ * @param [in] pCookie User's cookie, to be delivered to the callback.
+ * @param [out] hCallback Handle to the callback to be used for unregistering it.
+ *
+ * For full details and usage of the parameters, see @ref reg_to_events.
+ */
+ inline XnStatus RegisterToMirrorChange(StateChangedHandler handler, void* pCookie, XnCallbackHandle& hCallback)
+ {
+ return _RegisterToStateChange(xnRegisterToMirrorChange, GetHandle(), handler, pCookie, hCallback);
+ }
+
+ /**
+ * @brief Unregisters the event handler for the 'Mirror Change' event.
+ *
+ * @param [in] hCallback Handle received from registration.
+ *
+ * For full details and usage of the parameter, see @ref unreg_from_events .
+ */
+ inline void UnregisterFromMirrorChange(XnCallbackHandle hCallback)
+ {
+ _UnregisterFromStateChange(xnUnregisterFromMirrorChange, GetHandle(), hCallback);
+ }
+ };
+
+ /**
+ * @ingroup cppref_prd_func
+ *
+ * <b>Purpose:</b> The AlternativeViewPoint capability enables any type of map generator
+ * (depth, image, or IR) to transform its data to appear as if the sensor is placed
+ * in another location. The other location is represented by a second production node,
+ * usually representing another sensor.
+ *
+ * <b>Usage:</b> Do not instantiate directly. Instead, use @ref Generator::GetAlternativeViewPointCap()
+ * to obtain an instance.
+ *
+ * <b>Remarks:</b>
+ *
+ * This capability provides a solution for the situation where you want to impose
+ * color over depth, but there is then the problem that the two sensing media (transducers)
+ * are looking in slightly different directions. This capability superimposes the two
+ * sensing media of one sensor.
+ *
+ * Other uses are also possible.
+ *
+ * @note The AlternativeViewPoint capability has nothing to do with the actual physical
+ * position of a sensor. You could move the location of the sensor itself, but this
+ * will not change the current viewpoint.
+ *
+ * <b>Event: 'Viewpoint Change' </b>
+ *
+ * Signals that the @ref holder_node "holder node"'s viewpoint has changed (also see @ref event_cmn_conf).
+ *
+ * Use @ref RegisterToViewPointChange() and @ref UnregisterFromViewPointChange() for using this event.
+ *
+ * Calling the @ref SetViewPoint() or @ref ResetViewPoint() methods raises this event.
+ */
+ class AlternativeViewPointCapability : public Capability
+ {
+ public:
+ inline AlternativeViewPointCapability(XnNodeHandle hNode) : Capability(hNode) {}
+ AlternativeViewPointCapability(const NodeWrapper& node) : Capability(node) {}
+
+ /**
+ * @brief Checks if the generator node holding this capability can change its output to appear
+ * as if the sensor was placed at the viewpoint of another specific @ref xn::ProductionNode
+ * "production node".
+ *
+ * @param [in] otherNode Other production node, whose viewpoint against which this
+ * node's viewpoint is being checked.
+ *
+ * <b>Remarks</b>
+ *
+ * This is not the same as @ref xn::ProductionNode::IsCapabilitySupported(). Although
+ * the node implementation supports this capability, it may nevertheless support only
+ * the viewpoints of nodes of some specific sensors and not of other specific sensors.
+ */
+ inline XnBool IsViewPointSupported(ProductionNode& otherNode) const
+ {
+ return xnIsViewPointSupported(GetHandle(), otherNode.GetHandle());
+ }
+
+ /**
+ * @brief Sets the current viewpoint of the holding generator node to look as if it
+ * is placed at a different generator location. All further generated output will appear
+ * as if the sensor was placed at the different location.
+ *
+ * @param [in] otherNode Viewpoint to be set.
+ */
+ inline XnStatus SetViewPoint(ProductionNode& otherNode)
+ {
+ return xnSetViewPoint(GetHandle(), otherNode.GetHandle());
+ }
+
+ /**
+ * @brief Sets the viewpoint of the holding generator node to its normal viewpoint.
+ */
+ inline XnStatus ResetViewPoint()
+ {
+ return xnResetViewPoint(GetHandle());
+ }
+
+ /**
+ * @brief Returns whether the @ref holder_node "holder node"'s viewpoint is the same
+ * viewpoint as that of another specified node. Thus, this method is somewhat of an equality operator.
+ *
+ * @param [in] otherNode Other node, whose viewpoint is used for comparison with
+ * the viewpoint of this node.
+ */
+ inline XnBool IsViewPointAs(ProductionNode& otherNode) const
+ {
+ return xnIsViewPointAs(GetHandle(), otherNode.GetHandle());
+ }
+
+ /**
+ * @brief Registers a handler for the 'Viewpoint Change' event (see the above overview to this class).
+ *
+ * @param [in] handler Callback function to be invoked when the event is raised.
+ * @param [in] pCookie User's cookie, to be delivered to the callback.
+ * @param [out] hCallback Handle to the callback to be used for unregistering it.
+ *
+ * For full details and usage of the parameters, see @ref reg_to_events.
+ */
+ inline XnStatus RegisterToViewPointChange(StateChangedHandler handler, void* pCookie, XnCallbackHandle& hCallback)
+ {
+ return _RegisterToStateChange(xnRegisterToViewPointChange, GetHandle(), handler, pCookie, hCallback);
+ }
+
+ /**
+ * @brief Unregisters the event handler for the the 'Viewpoint Change' event.
+ *
+ * @param [in] hCallback Handle received from registration.
+ *
+ * For full details and usage of the parameter, see @ref unreg_from_events .
+ */
+ inline void UnregisterFromViewPointChange(XnCallbackHandle hCallback)
+ {
+ _UnregisterFromStateChange(xnUnregisterFromViewPointChange, GetHandle(), hCallback);
+ }
+ };
+
+ /**
+ * @ingroup cppref_prd_func
+ * <b>Purpose:</b> The Frame Sync capability allows frame synchronization between two
+ * @ref xn::Generator "generator" nodes producing frame data. This lets the two sensors
+ * output their frames at the same time. This allows smaller latency between two maps
+ * of the same scene, for example, a depth map and an image map.
+ *
+ * <b>Usage:</b> Do not instantiate directly. Instead, use @ref Generator::GetFrameSyncCap()
+ * to obtain an instance.
+ *
+ * <b>Event: 'Frame Sync Change'</b>
+ *
+ * Signals that the @ref holder_node "holder node"'s frame synchronization setting has
+ * been changed. That is, this setting has changed from activated to deactivated, or
+ * from deactivated to activated, or the frame synchronization has been changed and
+ * is now synchronized with a different 'other node'.
+ *
+ * Use @ref RegisterToFrameSyncChange() and @ref UnregisterFromFrameSyncChange() for using this event.
+ *
+ * Calling the @ref FrameSyncWith() or @ref StopFrameSyncWith() methods raises this event.
+ */
+ class FrameSyncCapability : public Capability
+ {
+ public:
+ inline FrameSyncCapability(XnNodeHandle hNode) : Capability(hNode) {}
+ FrameSyncCapability(const NodeWrapper& node) : Capability(node) {}
+
+ /**
+ * @brief Returns whether the generator node holding this capability can
+ * synchronize frames with the other specified node.
+ *
+ * @param [in] other Specifies the other node to be checked whether it can
+ * frame-sync with the node holding this capability.
+ * @returns TRUE if frame-sync to the other node is supported; FALSE otherwise.
+ */
+ inline XnBool CanFrameSyncWith(Generator& other) const;
+
+ /**
+ * @brief Activates frame synchronization with the other generator node.
+ *
+ * @param [in] other Specifies the other node to be frame sync-ed with the node
+ * holding this capability.
+ */
+ inline XnStatus FrameSyncWith(Generator& other);
+
+ /**
+ * @brief Removes the frame sync between the node holding this capability and the specified other node.
+ * @param [in] other Specifies the other node from which to remove the frame sync.
+ */
+ inline XnStatus StopFrameSyncWith(Generator& other);
+
+ /**
+ * @brief Returns whether a frame sync has been applied between the node holding this capability and
+ * another specified node.
+ * @param [in] other Specifies the other node for checking whether frame sync has
+ * been applied.
+ */
+ inline XnBool IsFrameSyncedWith(Generator& other) const;
+
+ /**
+ * @brief Registers an event handler for the 'Frame Sync Change' event.
+ *
+ * @param [in] handler Callback function to be invoked when the event is raised.
+ * @param [in] pCookie User's cookie, to be delivered to the callback.
+ * @param [out] hCallback Handle to the callback to be used for unregistering it.
+ *
+ * For full details and usage of the parameters, see @ref reg_to_events.
+ */
+ inline XnStatus RegisterToFrameSyncChange(StateChangedHandler handler, void* pCookie, XnCallbackHandle& hCallback)
+ {
+ return _RegisterToStateChange(xnRegisterToFrameSyncChange, GetHandle(), handler, pCookie, hCallback);
+ }
+
+ /**
+ * @brief Unregisters the 'Frame Sync Change' event handler.
+ *
+ * @param [in] hCallback Handle received from registration.
+ *
+ * For full details and usage of the parameter, see @ref unreg_from_events .
+ */
+ inline void UnregisterFromFrameSyncChange(XnCallbackHandle hCallback)
+ {
+ _UnregisterFromStateChange(xnUnregisterFromFrameSyncChange, GetHandle(), hCallback);
+ }
+ };
+
+ /**
+ * @ingroup cppref_prd_func
+ * <b>Purpose:</b> A generator node produces some type of data. This is in addition
+ * to the node's basic characteristic, as a derivative of the @ref xn::ProductionNode
+ * class, i.e., that it represents a logical entity in the OpenNI @ref prod_graph "Production
+ * Graph".
+ *
+ * <b>Usage summary</b>: Immediate base class for all generator types. It itself is
+ * not usually instantiated.
+ *
+ * <b>Class Overview:</b>
+ *
+ * Each generator can be in Generating state or Non-Generating state. The application makes
+ * the node enter Generating state by calling the @ref xn::Generator::StartGenerating()
+ * method.
+ *
+ * When a generator node is created, by default it is in Non-Generating state, so it
+ * does not generate data.
+ *
+ * Generators have a default configuration (for example the FOV resolution) and an application
+ * can change the default configuration before actual data generation starts.
+ *
+ * Once the application has completed configuring the generator node, the application
+ * can cause the node to start generating data.
+ *
+ * Typically, the application will configure the generator only in the configuration
+ * stage, i.e., in Non-Generating state. The application can usually also configure
+ * the node while generating data, however configuration might then take longer and
+ * the application could also lose some frames of data. For example, if the application
+ * changes the resolution while in the Configuration stage (Non-Generating state), the
+ * resolution change occurs immediately; but if the application changes the configuration
+ * while the generator is generating data, the resolution change can take up to a few
+ * seconds to occur.
+ *
+ * <b>Data Storage:</b>
+ *
+ * Each call to an @ref conc_updating_data "'Update Data'" method updates the generator
+ * node's application buffer, making the latest data available for applications to access.
+ * After a call to an @ref conc_updating_data "'Update Data'" method, all subsequent
+ * calls to @ref GetData() will return exactly the same data until you call @ref conc_updating_data
+ * "'Update Data'" again. The @ref conc_updating_data "'Update Data'" method can be
+ * the generator node's own @ref WaitAndUpdateData() method or one of the Context's
+ * @ref conc_updating_data "'WaitXUpdateAll'" methods.
+ *
+ * <b>Getting the Generated Data:</b>
+ *
+ * Generator nodes will not output data to make it available for getting, until the
+ * application calls the node's WaitAndUpdateData() method (see below) or one of the
+ * context's @ref conc_updating_data "'WaitXUpdateAll'" methods.
+ *
+ * @ref conc_updating_data__sample_code_cmn
+ */
+ class Generator : public ProductionNode
+ {
+ public:
+ /**
+ * Ctor
+ *
+ * @param [in] hNode Node handle
+ */
+ inline Generator(XnNodeHandle hNode = NULL) : ProductionNode(hNode) {}
+ inline Generator(const NodeWrapper& other) : ProductionNode(other) {}
+
+ /**
+ * @brief Enters the node into Generating state.
+ *
+ * Enters the node into Generating state. In this state the node generates new frames.
+ *
+ * After the application has called this method it can call an @ref conc_updating_data
+ * "'Update Data'" method, e.g., @ref xn::Generator::WaitAndUpdateData(), to make
+ * a new frame available for getting. The application can then get the data (for
+ * example, using a metadata GetData() method, or some other mechanism depending
+ * on the type of node).
+ *
+ * <b>Remarks:</b>
+ *
+ * On entering the node into Generating state, OpenNI enters also all dependent
+ * nodes into Generating state. For example, if a UserGenerator node depends on
+ * data input from a DepthGenerator node, and the UserGenerator node is entered
+ * into Generating state, then OpenNI will enter also the DepthGenerator node into
+ * Generating state.
+ */
+ inline XnStatus StartGenerating()
+ {
+ return xnStartGenerating(GetHandle());
+ }
+
+ /**
+ * @brief Returns whether the node is currently in Generating state.
+ */
+ inline XnBool IsGenerating() const
+ {
+ return xnIsGenerating(GetHandle());
+ }
+
+ /**
+ * @brief Makes the node leave Generating state (enters Non-Generating state).
+ *
+ * <b>Remarks:</b>
+ *
+ * If the node has metadata, after calling this method the data is still available
+ * as a saved @ref glos_frame_object "frame object" in the metadata object.
+ */
+ inline XnStatus StopGenerating()
+ {
+ return xnStopGenerating(GetHandle());
+ }
+
+ /**
+ * @brief Registers an event handler for the 'Generation State Change' event.
+ *
+ * Registers a callback function to be called when generation starts or
+ * stops, i.e., when the generation state toggles between generating and not
+ * generating.
+ *
+ * @param [in] handler Callback function to be invoked when the event is raised.
+ * @param [in] pCookie User's cookie, to be delivered to the callback.
+ * @param [out] hCallback Handle to the callback to be used for unregistering it.
+ *
+ * For full details and usage of the parameters, see @ref reg_to_events.
+ */
+ inline XnStatus RegisterToGenerationRunningChange(StateChangedHandler handler, void* pCookie, XnCallbackHandle &hCallback)
+ {
+ return _RegisterToStateChange(xnRegisterToGenerationRunningChange, GetHandle(), handler, pCookie, hCallback);
+ }
+
+ /**
+ * @brief Unregisters the 'Generation State Change' event handler.
+ *
+ * @param [in] hCallback Handle received from registration.
+ *
+ * For full details and usage of the parameter, see @ref unreg_from_events .
+ */
+ inline void UnregisterFromGenerationRunningChange(XnCallbackHandle hCallback)
+ {
+ _UnregisterFromStateChange(xnUnregisterFromGenerationRunningChange, GetHandle(), hCallback);
+ }
+
+ /**
+ * @brief Registers an event handler for the 'New Data Available' event.
+ *
+ * The 'New Data Available' event is raised whenever a generator node has new data available. The new
+ * data is available for updating, but can not yet be accessed by the application. The application
+ * needs to call @ref conc_updating_data "'Update Data'" to gain access to that new data.
+ *
+ * @param [in] handler Callback function to be invoked when the event is raised.
+ * @param [in] pCookie User's cookie, to be delivered to the callback.
+ * @param [out] hCallback Handle to the callback to be used for unregistering it.
+ *
+ * For full details and usage of the parameters, see @ref reg_to_events.
+ */
+ inline XnStatus RegisterToNewDataAvailable(StateChangedHandler handler, void* pCookie, XnCallbackHandle &hCallback)
+ {
+ return _RegisterToStateChange(xnRegisterToNewDataAvailable, GetHandle(), handler, pCookie, hCallback);
+ }
+
+ /**
+ * @brief Unregisters the event handler for the 'New Data Available' event.
+ *
+ * @param [in] hCallback Handle received from registration.
+ *
+ * For full details and usage of the parameter, see @ref unreg_from_events .
+ */
+ inline void UnregisterFromNewDataAvailable(XnCallbackHandle hCallback)
+ {
+ _UnregisterFromStateChange(xnUnregisterFromNewDataAvailable, GetHandle(), hCallback);
+ }
+
+ /**
+ * @brief Returns whether the node has new data available.
+ * The new data is available for updating, but can not yet be accessed by the application. The application
+ * needs to call @ref conc_updating_data "'Update Data'" to gain access to that new data.
+ *
+ * @param [out] pnTimestamp [Optional] If new data is available (TRUE is returned from the method),
+ * this param will hold the timestamp of that new data.
+ */
+ inline XnBool IsNewDataAvailable(XnUInt64* pnTimestamp = NULL) const
+ {
+ return xnIsNewDataAvailable(GetHandle(), pnTimestamp);
+ }
+
+ /**
+ * @brief Updates the generator node to the latest available data, first waiting for the node to have new data available.
+ *
+ * <b>Remarks:</b>
+ *
+ * This method requests from OpenNI to cause the node to update its application buffers
+ * with new data, if it has new data available.
+ *
+ * At this stage the generator node has "generated" new data. This method returns a
+ * success status. The application can now read the newly generated data.
+ *
+ * An error situation is defined as: after a preset timeout, the node has not yet notified
+ * OpenNI it has new data available. On error, the method stops waiting and returns
+ * an error status.
+ *
+ * @retval XN_STATUS_INVALID_OPERATION This production node is not a generator.
+ * @retval XN_STATUS_WAIT_DATA_TIMEOUT No new data available within 2 seconds.
+ */
+ inline XnStatus WaitAndUpdateData()
+ {
+ return xnWaitAndUpdateData(GetHandle());
+ }
+
+ /**
+ * Returns whether this node's frame data was updated by the most recent call to
+ * any @ref conc_updating_data "'WaitXUpdateAll()'" function, e.g., @ref xn::Context::WaitAnyUpdateAll().
+ */
+ inline XnBool IsDataNew() const
+ {
+ return xnIsDataNew(GetHandle());
+ }
+
+ /**
+ * @brief Gets the @ref frame_data "frame data" from the generator node. This is
+ * the latest data that the generator node has generated.
+ *
+ * <b>Remarks:</b>
+ *
+ * This method gets the data directly from the Generator node; not from the metadata
+ * object.
+ *
+ * Compare this method with the Data() method of the @ref xn::OutputMetaData object,
+ * where the latter gets the data from the metadata object.
+ * GetData() returns the same data as the GetMetaData().Data() method. However,
+ * using the GetData() method is slightly more costly.
+ *
+ * The application usually should not use this method, but call each generator own
+ * data access methods, e.g. DepthGenerator::GetDepthMap().
+ */
+ inline const void* GetData()
+ {
+ return xnGetData(GetHandle());
+ }
+
+ /**
+ * @brief Gets the data size of the @ref frame_data "frame data".
+ * This method gets the data size directly from the Generator node.
+ *
+ * <b>Remarks:</b>
+ *
+ * The size of the data is returned as a number of bytes.
+ *
+ * Compare this method with the DataSize() method of the @ref xn::OutputMetaData
+ * object, where the latter gets the data from the metadata object.
+ * GetDataSize() returns the same data as the GetMetaData().DataSize() method. However,
+ * using the GetDataSize() method is slightly more costly.
+ */
+ inline XnUInt32 GetDataSize() const
+ {
+ return xnGetDataSize(GetHandle());
+ }
+
+ /**
+ * @brief Gets the frame timestamp from the <b>Generator</b> node
+ * This method gets the timestamp directly from the Generator node.
+ *
+ * <b>Remarks:</b>
+ *
+ * The time is returned in microseconds.
+ *
+ * Compare this method with the <b>GetTimestamp()</b> method of the @ref xn::OutputMetaData
+ * object, where the latter gets the data from the metadata object.
+ * <b>GetTimestamp()</b> returns the same data as the GetMetaData().GetTimestamp()
+ * method. However, using the <b>GetTimestamp()</b> method is slightly more costly.
+ */
+ inline XnUInt64 GetTimestamp() const
+ {
+ return xnGetTimestamp(GetHandle());
+ }
+
+ /**
+ * @brief Gets the frame ID of the current frame data from the Generator node.
+ *
+ * <b>Remarks:</b>
+ *
+ * This method gets the frame ID directly from the Generator node.
+ *
+ * Compare this method with the <b>GetFrameID()</b> method of the @ref xn::OutputMetaData
+ * object, where the latter gets the data from the metadata object.
+ * <b>GetFrameID()</b> returns the same data as the GetMetaData().GetFrameID() method.
+ * However, using the <b>GetFrameID()</b> method is slightly more costly.
+ */
+ inline XnUInt32 GetFrameID() const
+ {
+ return xnGetFrameID(GetHandle());
+ }
+
+ /**
+ * @brief Gets a @ref MirrorCapability object for accessing Mirror functionality.
+ *
+ * <b>Remarks:</b>
+ *
+ * It is the application's responsibility to check first if @ref XN_CAPABILITY_MIRROR
+ * is supported by calling @ref xn::ProductionNode::IsCapabilitySupported().
+ */
+ inline const MirrorCapability GetMirrorCap() const
+ {
+ return MirrorCapability(GetHandle());
+ }
+
+ /**
+ * @brief Gets a @ref MirrorCapability object for accessing Mirror functionality.
+ *
+ * <b>Remarks:</b>
+ *
+ * It is the application's responsibility to check first if @ref XN_CAPABILITY_MIRROR
+ * is supported by calling @ref xn::ProductionNode::IsCapabilitySupported().
+ */
+ inline MirrorCapability GetMirrorCap()
+ {
+ return MirrorCapability(GetHandle());
+ }
+
+ /**
+ * Gets an @ref AlternativeViewPointCapability object for accessing Alternative
+ * Viewpoint functionality.
+ *
+ * <b>Remarks:</b>
+ *
+ * It is the application's responsibility to check first if
+ * @ref XN_CAPABILITY_ALTERNATIVE_VIEW_POINT is supported
+ * by calling @ref xn::Generator::IsCapabilitySupported().
+ */
+ inline const AlternativeViewPointCapability GetAlternativeViewPointCap() const
+ {
+ return AlternativeViewPointCapability(GetHandle());
+ }
+
+ /**
+ * Gets an @ref AlternativeViewPointCapability object for accessing Alternative
+ * Viewpoint functionality.
+ *
+ * <b>Remarks:</b>
+ *
+ * It is the application's responsibility to check first if
+ * @ref XN_CAPABILITY_ALTERNATIVE_VIEW_POINT is supported
+ * by calling @ref xn::Generator::IsCapabilitySupported().
+ */
+ inline AlternativeViewPointCapability GetAlternativeViewPointCap()
+ {
+ return AlternativeViewPointCapability(GetHandle());
+ }
+
+ /**
+ * Gets an @ref FrameSyncCapability object for accessing Frame Sync functionality.
+ *
+ * <b>Remarks:</b>
+ *
+ * It is the application's responsibility to check first if
+ * @ref XN_CAPABILITY_FRAME_SYNC is supported
+ * by calling @ref xn::Generator::IsCapabilitySupported().
+ */
+ inline const FrameSyncCapability GetFrameSyncCap() const
+ {
+ return FrameSyncCapability(GetHandle());
+ }
+
+ /**
+ * Gets an @ref FrameSyncCapability object for accessing Frame Sync functionality.
+ *
+ * <b>Remarks:</b>
+ *
+ * It is the application's responsibility to check first if
+ * @ref XN_CAPABILITY_FRAME_SYNC is supported
+ * by calling @ref xn::Generator::IsCapabilitySupported().
+ */
+ inline FrameSyncCapability GetFrameSyncCap()
+ {
+ return FrameSyncCapability(GetHandle());
+ }
+ };
+
+ /**
+ * @ingroup cppref_prd_func
+ * <b>Purpose:</b> To create and manage a Recorder node.
+ *
+ * <b>Usage: </b> Instatiate and create a Recorder node.
+ *
+ * <b>Data output:</b> Records to a specified destination medium the frames of data
+ * from each node that was added to the Recorder node.
+ *
+ * <b>Remarks:</b>
+ *
+ * Recordings are a powerful debug tool. A recording enables a full capture of data
+ * generation and the ability to later play it back by 'regeneration' so that applications
+ * can simulate an exact replica of the situation to be debugged.
+ *
+ * OpenNI supports recordings of the production nodes in the production graph, both
+ * the entire configuration of each node, and all data streamed from a node.
+ *
+ * OpenNI has a framework for recording data and for playing it back (using mock nodes).
+ * It also comes with the nimRecorder module, which defines a new file format (".ONI")
+ * - and implements a Recorder node and a Player node for this format.
+ *
+ * If a recorder exists while generating, the @ref conc_updating_data "'WaitXUpdateAll'"
+ * functions automatically record the data from all nodes added to this recorder.
+ *
+ * To record, an application creates a Recorder node, and set its destination - the
+ * file name to which it should write. The application must add to the Recorder node
+ * every production node that it wants to record. When adding a node to the recorder,
+ * the Recorder stores its configuration. It also registers to every possible event
+ * of the node, so that when any configuration change takes place, it is also recorded.
+ *
+ * Once all required nodes are added, the application can read data from the nodes and
+ * record it. Recording of data can be achieved either by explicitly calling the @ref
+ * xn::Recorder::Record() function, or by using one of the @ref conc_updating_data "'Update
+ * All'" functions.
+ *
+ * Applications that initialize OpenNI using an XML file can easily record their session
+ * without any change to the code. All that is required is that they create an additional
+ * node in the XML file for the recorder, add nodes to it, and when the application
+ * calls one of the 'WaitXUpdateAll' functions, recording will occur. see @ref xmlscripts
+ * for explanation on how to do that.
+ *
+ * Recordings are played back by using the services of the Player class.
+ */
+ class Recorder : public ProductionNode
+ {
+ public:
+ /**
+ * Ctor
+ *
+ * @param [in] hNode A node handle
+ */
+ inline Recorder(XnNodeHandle hNode = NULL) : ProductionNode(hNode) {}
+ inline Recorder(const NodeWrapper& other) : ProductionNode(other) {}
+
+ /**
+ * @brief Creates a Recorder node.
+ *
+ * @param [in] context The context in which to create the Recorder node.
+ * @param [in] strFormatName Optional. The name of the format the recorded file
+ * will be in. If NULL, file will be in ONI format.
+ */
+ inline XnStatus Create(Context& context, const XnChar* strFormatName = NULL);
+
+ /**
+ * @brief Specifies to where the recorder must send its recording. Typically this is a disk file of a particular file type.
+ *
+ * @param [in] destType The type of medium to record to. Currently only XN_RECORD_MEDIUM_FILE
+ * is supported.
+ * @param [in] strDest Recording destination. If destType is XN_RECORD_MEDIUM_FILE,
+ * this specifies a file name.
+ */
+ inline XnStatus SetDestination(XnRecordMedium destType, const XnChar* strDest)
+ {
+ return xnSetRecorderDestination(GetHandle(), destType, strDest);
+ }
+
+ /**
+ * @brief Gets the destination medium for the Recorder node to record to.
+ *
+ * @param [out] destType The type of medium to record to. Currently only XN_RECORD_MEDIUM_FILE
+ * is supported.
+ * @param [out] strDest Recording destination. If destType is XN_RECORD_MEDIUM_FILE,
+ * this specifies a file name.
+ * @param [in] nBufSize Destination buffer size.
+ */
+ inline XnStatus GetDestination(XnRecordMedium& destType, XnChar* strDest, XnUInt32 nBufSize)
+ {
+ return xnGetRecorderDestination(GetHandle(), &destType, strDest, nBufSize);
+ }
+
+ /**
+ * @brief Adds a node to the recording setup, and starts recording data what the node generates.
+ * This method must be called for each node to be recorded with this recorder.
+ *
+ * @param [in] Node Node to add to the recording.
+ * @param [in] compression Type of compression that will be used to encode the node's
+ * data (see @ref XnCodecIDs.h). If @ref XN_CODEC_NULL
+ * is specified, a default compression will be chosen according to the node type.
+ */
+ inline XnStatus AddNodeToRecording(ProductionNode& Node, XnCodecID compression = XN_CODEC_NULL)
+ {
+ return xnAddNodeToRecording(GetHandle(), Node.GetHandle(), compression);
+ }
+
+ /**
+ * @brief Removes a node from the Recorder node and stops recording the node output.
+ * This function is called on a node that was added to recording with @ref AddNodeToRecording.
+ *
+ * @param [in] Node The node to remove from recording.
+ */
+ inline XnStatus RemoveNodeFromRecording(ProductionNode& Node)
+ {
+ return xnRemoveNodeFromRecording(GetHandle(), Node.GetHandle());
+ }
+
+ /**
+ * @brief Records one frame of data from each node that was added to the recorder with AddNodeToRecording().
+ *
+ * <b>Remarks</b>
+ *
+ * To record continually, the recorder node must be called repeatedly for each frame.
+ *
+ * It is highly recommended that an application use the 'WaitXUpdateAll' methods,
+ * and not call Generator::WaitAndUpdateData() for each generator. When working
+ * with the 'WaitXUpdateAll' methods, OpenNI will automatically call @ref Record(),
+ * and there is no need for the application to call this method.
+ */
+ inline XnStatus Record()
+ {
+ return xnRecord(GetHandle());
+ }
+ };
+
+ /**
+ * @ingroup cppref_prd_func
+ *
+ * <b>Purpose:</b> The Player class is used for creating and managing a Player node.
+ * This node plays a saved recording of an OpenNI data generation session.
+ *
+ * <b>Remarks:</b>
+ *
+ * To play a file recording, use the @ref xn::Context::OpenFileRecording() function.
+ * OpenNI will open the file, create a mock node for each node in the file, and populate
+ * it with the recorded configuration.
+ *
+ * An application may take the nodes it needs by calling the @ref xn::Context::FindExistingNode()
+ * method, and use them normally.
+ *
+ * @note Nodes created by the player are locked, and cannot be changed, as the
+ * configuration must remain according to the recorded configuration.
+ *
+ * Applications that initialize OpenNI using an XML file can easily replace their input.
+ * This means that instead of reading from a physical device, which generates data in
+ * real-time, they read from a recording by replacing the nodes in the XML file with
+ * a recording element (see @ref xmlscripts).
+ *
+ * @note It is not the Player node itself that is generating data. (Accordingly, the
+ * Player node does not provide a GetData() method.) The Player node reads data from
+ * the file, and "pushes" it into the mock nodes.
+ */
+ class Player : public ProductionNode
+ {
+ public:
+ /**
+ * Ctor
+ *
+ * @param [in] hNode Player node handle
+ */
+ inline Player(XnNodeHandle hNode = NULL) : ProductionNode(hNode) {}
+ inline Player(const NodeWrapper& other) : ProductionNode(other) {}
+
+ /**
+ * @brief Creates a player node.
+ *
+ * <b>Remarks</b>
+ *
+ * See @ref create_method "Concepts: the Create() Method" for a detailed description
+ * about the operation of this method.
+ */
+ inline XnStatus Create(Context& context, const XnChar* strFormatName);
+
+
+ /**
+ * @brief Specifies whether the player will automatically rewind to the beginning
+ * of the recording after reaching the end of the recording.
+ *
+ * @param [in] bRepeat Determines whether the player will repeat or not.
+ *
+ * If bRepeat is set to TRUE, the player will automatically
+ * rewind when reaching the end.
+ *
+ * If bRepeat is set to FALSE, the player will stop playing
+ * when reaching the end, and will raise the 'End-Of-File Reached'
+ * event. In this state, @ref IsEOF() returns TRUE, and
+ * calls to @ref ReadNext() will fail.
+ */
+ inline XnStatus SetRepeat(XnBool bRepeat)
+ {
+ return xnSetPlayerRepeat(GetHandle(), bRepeat);
+ }
+
+ /**
+ * @copybrief xnSetPlayerSource
+ * For full details and usage, see @ref xnSetPlayerSource
+ */
+ inline XnStatus SetSource(XnRecordMedium sourceType, const XnChar* strSource)
+ {
+ return xnSetPlayerSource(GetHandle(), sourceType, strSource);
+ }
+
+ /**
+ * @brief Gets the player's source, that is, the type and name of the medium
+ * that the recording is played back from.
+ *
+ * @param [out] sourceType Player's source type.
+ * @param [in] strSource Player's source.
+ * @param [in] nBufSize Size of the buffer specified by @c strSource.
+ */
+ inline XnStatus GetSource(XnRecordMedium &sourceType, XnChar* strSource, XnUInt32 nBufSize) const
+ {
+ return xnGetPlayerSource(GetHandle(), &sourceType, strSource, nBufSize);
+ }
+
+ /**
+ * @copybrief xnPlayerReadNext
+ * For full details and usage, see @ref xnPlayerReadNext
+ */
+ inline XnStatus ReadNext()
+ {
+ return xnPlayerReadNext(GetHandle());
+ }
+
+ /**
+ * @brief Moves the player to a specific time, so that playback will continue from that point onwards.
+ *
+ * @param [in] nTimeOffset Offset to move, relative to the specified origin. <br>
+ * Units in microseconds. <br> See the remark below.
+ * @param [in] origin Origin to seek from. See the remarks below.
+ *
+ * The meaning of the @c nTimeOffset parameter changes according to the origin parameter:
+ *
+ * <b>XN_PLAYER_SEEK_SET:</b> @c nTimeOffset specifies the total time passed since
+ * the beginning of the recording. This must be a positive value.
+ *
+ * <b>XN_PLAYER_SEEK_CUR:</b> @c nTimeOffset specifies a period of time to move, relative
+ * to the current player position. A positive value means to move forward, and a
+ * negative value means to move backwards.
+ *
+ * <b>XN_PLAYER_SEEK_END:</b> @c nTimeOffset specifies a period of time to move, relative
+ * to the end of the recording. This must be a negative value.
+ *
+ * <b>Remarks</b>
+ *
+ * For the built-in ONI player, this function is not currently supported and always
+ * returns XN_STATUS_NOT_IMPLEMENTED.
+ */
+ inline XnStatus SeekToTimeStamp(XnInt64 nTimeOffset, XnPlayerSeekOrigin origin)
+ {
+ return xnSeekPlayerToTimeStamp(GetHandle(), nTimeOffset, origin);
+ }
+
+ /**
+ * @brief Moves the player to a specific frame of a specific played node, e.g., an
+ * ImageGenerator node, so that playing will continue from that frame onwards.
+ *
+ * @param [in] strNodeName Name of the node.
+ * @param [in] nFrameOffset Number of frames to move, relative to the specified
+ * origin. See remarks below.
+ * @param [in] origin Origin to seek from. See remarks below.
+ *
+ * The meaning of the @c nFrameOffset parameter changes according to the origin parameter:
+ *
+ * <b>XN_PLAYER_SEEK_SET:</b> @c nFrameOffset specifies the total number of frames
+ * since the beginning of the node's recording. This must be a positive value.
+ *
+ * <b>XN_PLAYER_SEEK_CUR:</b> @c nFrameOffset specifies the number of frames to move,
+ * relative to the current frame of the specified node. A positive value means to
+ * move forward, and a negative value means to move backwards.
+ *
+ * <b>XN_PLAYER_SEEK_END:</b> @c nFrameOffset specifies the number of frames to move,
+ * relative to the end of the node's recording. This must be a negative value.
+ *
+ * You can get different results using this function for different values of strNodeName,
+ * because the frame numbers of different nodes are not necessarily in sync.
+ */
+ inline XnStatus SeekToFrame(const XnChar* strNodeName, XnInt32 nFrameOffset, XnPlayerSeekOrigin origin)
+ {
+ return xnSeekPlayerToFrame(GetHandle(), strNodeName, nFrameOffset, origin);
+ }
+
+ /**
+ * @brief Gets the current time of a player, i.e., the time passed since the beginning of the recording.
+ *
+ * @param [out] nTimestamp Retrieved timestamp. Units are in microseconds.
+ */
+ inline XnStatus TellTimestamp(XnUInt64& nTimestamp) const
+ {
+ return xnTellPlayerTimestamp(GetHandle(), &nTimestamp);
+ }
+
+ /**
+ * @brief Gets the current frame number of a specific node played by a player,
+ * i.e., the number of frames passed since the beginning of the recording
+ *
+ * @param [in] strNodeName Name of the node.
+ * @param [out] nFrame Retrieved frame number.
+ *
+ * <b>Remarks</b>
+ *
+ * Different nodes that belong to the player can have different frame numbers, because
+ * the nodes are not necessarily in synchronization.
+ */
+ inline XnStatus TellFrame(const XnChar* strNodeName, XnUInt32& nFrame) const
+ {
+ return xnTellPlayerFrame(GetHandle(), strNodeName, &nFrame);
+ }
+
+ /**
+ * @brief Gets the total number of frames a specific node has in the recording.
+ *
+ * @param [in] strNodeName Name of the node for which to retrieve the number of frames.
+ * @param [out] nFrames Retrieved number of frames.
+ *
+ */
+ inline XnStatus GetNumFrames(const XnChar* strNodeName, XnUInt32& nFrames) const
+ {
+ return xnGetPlayerNumFrames(GetHandle(), strNodeName, &nFrames);
+ }
+
+ /**
+ * @copybrief xnGetPlayerSupportedFormat
+ * For full details and usage, see @ref xnGetPlayerSupportedFormat
+ */
+ inline const XnChar* GetSupportedFormat() const
+ {
+ return xnGetPlayerSupportedFormat(GetHandle());
+ }
+
+ /**
+ * @copybrief xnEnumeratePlayerNodes
+ * For full details and usage, see @ref xnEnumeratePlayerNodes
+ */
+ inline XnStatus EnumerateNodes(NodeInfoList& list) const
+ {
+ XnNodeInfoList* pList;
+ XnStatus nRetVal = xnEnumeratePlayerNodes(GetHandle(), &pList);
+ XN_IS_STATUS_OK(nRetVal);
+
+ list.ReplaceUnderlyingObject(pList);
+
+ return (XN_STATUS_OK);
+ }
+
+ /**
+ * @brief Returns whether the player is at the end-of-file marker.
+ *
+ * <b>Remarks</b>
+ *
+ * When Repeat mode is on, this function never returns TRUE.
+ * However, the 'End of File Reached' event will be raised during rewind.
+ */
+ inline XnBool IsEOF() const
+ {
+ return xnIsPlayerAtEOF(GetHandle());
+ }
+
+ /**
+ * @brief Registers an event handler for the 'End-Of-File Reached' event.
+ *
+ * @param [in] handler Callback function to be invoked when the event is raised.
+ * @param [in] pCookie User's cookie, to be delivered to the callback.
+ * @param [out] hCallback Handle to the callback to be used for unregistering it.
+ *
+ * For full details and usage of the parameters, see @ref reg_to_events.
+ */
+ inline XnStatus RegisterToEndOfFileReached(StateChangedHandler handler, void* pCookie, XnCallbackHandle& hCallback)
+ {
+ return _RegisterToStateChange(xnRegisterToEndOfFileReached, GetHandle(), handler, pCookie, hCallback);
+ }
+
+ /**
+ * @brief Unregisters the event handler for the 'End-Of-File Reached' event.
+ *
+ * @param [in] hCallback Handle received from registration.
+ *
+ * For full details and usage of the parameter, see @ref unreg_from_events .
+ */
+ inline void UnregisterFromEndOfFileReached(XnCallbackHandle hCallback)
+ {
+ _UnregisterFromStateChange(xnUnregisterFromEndOfFileReached, GetHandle(), hCallback);
+ }
+
+ /**
+ * @brief Sets the player's playback speed, as a ratio of the rate that the recording was made at.
+ *
+ * @param [in] dSpeed The speed ratio.
+ *
+ * <b>Values: </b>
+ *
+ * @c dSpeed = 1.0 - Player will try to output frames at the same rate they were recorded
+ * (according to their timestamps).
+ *
+ * @c dSpeed > 1.0 - Fast-forward
+ *
+ * 0 < @c dSpeed < 1.0 - Slow-motion.
+ *
+ * @c dSpeed = XN_PLAYBACK_SPEED_FASTEST (0.0) - There will be no delay, and frames
+ * will be returned immediately on demand.
+ *
+ */
+ inline XnStatus SetPlaybackSpeed(XnDouble dSpeed)
+ {
+ return xnSetPlaybackSpeed(GetHandle(), dSpeed);
+ }
+
+ /**
+ * @brief Gets the playback speed.
+ * @returns Speed ratio, or -1.0 if this node is not a player.
+ */
+ inline XnDouble GetPlaybackSpeed() const
+ {
+ return xnGetPlaybackSpeed(GetHandle());
+ }
+ };
+
+ /**
+ * @ingroup cppref_prd_func
+ *
+ * <b>Purpose:</b> Provides Cropping capability for @ref MapGenerator "map generator nodes".
+ * Cropping capability restricts the size of the data frames to be generated by the
+ * MapGenerator node to a selected (cropped) area of the full field-of-view.
+ *
+ * <b>Usage:</b> Do not instantiate directly. Instead, use @ref MapGenerator::GetCroppingCap()
+ * to obtain an instance.
+ *
+ * <b>Remarks:</b>
+ *
+ * When cropping is enabled, the size of the generated map is reduced to fit a lower
+ * resolution (smaller FOV dimensions). For example, if the map generator is working
+ * in VGA resolution (640x480) and the application chooses to crop at 300x200, the next
+ * pixel row will begin after 300 pixels. Pixels outside the cropping area are not returned
+ * in the buffer - they are not blacked out; they are not returned at all. Thus, cropping
+ * is very useful for providing a performance boost.
+ *
+ * <b>Event: 'Cropping Change'</b>
+ *
+ * Signals that the @ref holder_node "holder node"'s cropping area has been changed.
+ *
+ * Use @ref RegisterToCroppingChange() and @ref UnregisterFromCroppingChange() for using this event.
+ *
+ * Calling the @ref SetCropping() method raises this event.
+ */
+ class CroppingCapability : public Capability
+ {
+ public:
+ /**
+ * Ctor
+ *
+ * @param [in] hNode Node handle
+ */
+ inline CroppingCapability(XnNodeHandle hNode) : Capability(hNode) {}
+ CroppingCapability(const NodeWrapper& node) : Capability(node) {}
+
+ /**
+ * @brief Sets the @ref holder_node "holder node"'s current cropping
+ * configuration. This configuration is used for generating the next frame.
+ *
+ * @param [in] Cropping Cropping configuration to be set.
+ *
+ * @retval XN_STATUS_INVALID_OPERATION The @ref MapGenerator node does not support
+ * the Cropping capability.
+ */
+ inline XnStatus SetCropping(const XnCropping& Cropping)
+ {
+ return xnSetCropping(GetHandle(), &Cropping);
+ }
+
+ /**
+ * @brief Gets the current cropping configuration of the @ref holder_node "holder node".
+ * This configuration is that set by @ref SetCropping(). This configuration is used
+ * for generating the next frame.
+ *
+ * @param [out] Cropping Retreived cropping configuration.
+ *
+ * @retval XN_STATUS_INVALID_OPERATION The @ref MapGenerator node does not
+ * support the Cropping capability.
+ */
+ inline XnStatus GetCropping(XnCropping& Cropping) const
+ {
+ return xnGetCropping(GetHandle(), &Cropping);
+ }
+
+ /**
+ * @brief Registers an event handler for the 'Cropping Change' event.
+ *
+ * @param [in] handler Callback function to be invoked when the event is raised.
+ * @param [in] pCookie User's cookie, to be delivered to the callback.
+ * @param [out] hCallback Handle to the callback to be used for unregistering it.
+ *
+ * For full details and usage of the parameters, see @ref reg_to_events.
+ */
+ inline XnStatus RegisterToCroppingChange(StateChangedHandler handler, void* pCookie, XnCallbackHandle& hCallback)
+ {
+ return _RegisterToStateChange(xnRegisterToCroppingChange, GetHandle(), handler, pCookie, hCallback);
+ }
+
+ /**
+ * @brief Unregisters the event handler for the 'Cropping Change' event.
+ *
+ * @param [in] hCallback Handle received from registration.
+ *
+ * For full details and usage of the parameter, see @ref unreg_from_events .
+ */
+ inline void UnregisterFromCroppingChange(XnCallbackHandle hCallback)
+ {
+ _UnregisterFromStateChange(xnUnregisterFromCroppingChange, GetHandle(), hCallback);
+ }
+ };
+
+ /**
+ * @ingroup cppref_prd_func
+ * Allows access to <b>Anti Flicker</b> capability functions. see @ref anti_flicker
+ * for additional details.
+ *
+ * <b>Usage:</b> Do not instantiate directly. Instead, use @ref MapGenerator::GetAntiFlickerCap()
+ * to obtain an instance.
+ */
+ class AntiFlickerCapability : public Capability
+ {
+ public:
+ /**
+ * Ctor
+ *
+ * @param [in] hNode Node handle
+ */
+ inline AntiFlickerCapability(XnNodeHandle hNode) : Capability(hNode) {}
+ AntiFlickerCapability(const NodeWrapper& node) : Capability(node) {}
+
+ /**
+ * @copybrief xnSetPowerLineFrequency
+ * For full details and usage, see @ref xnSetPowerLineFrequency
+ */
+ inline XnStatus SetPowerLineFrequency(XnPowerLineFrequency nFrequency)
+ {
+ return xnSetPowerLineFrequency(GetHandle(), nFrequency);
+ }
+
+ /**
+ * @copybrief xnGetPowerLineFrequency
+ * For full details and usage, see @ref xnGetPowerLineFrequency
+ */
+ inline XnPowerLineFrequency GetPowerLineFrequency()
+ {
+ return xnGetPowerLineFrequency(GetHandle());
+ }
+
+ /**
+ * @brief Registers an event handler for the 'Power Line Frequency Change' event.
+ *
+ * @param [in] handler Callback function to be invoked when the event is raised.
+ * @param [in] pCookie User's cookie, to be delivered to the callback.
+ * @param [out] hCallback Handle to the callback to be used for unregistering it.
+ *
+ * For full details and usage of the parameters, see @ref reg_to_events.
+ */
+ inline XnStatus RegisterToPowerLineFrequencyChange(StateChangedHandler handler, void* pCookie, XnCallbackHandle& hCallback)
+ {
+ return _RegisterToStateChange(xnRegisterToPowerLineFrequencyChange, GetHandle(), handler, pCookie, hCallback);
+ }
+
+ /**
+ * @brief Unregisters the event handler for the 'Power Line Frequency Change' event.
+ *
+ * @param [in] hCallback Handle received from registration.
+ *
+ * For full details and usage of the parameter, see @ref unreg_from_events .
+ */
+ inline void UnregisterFromPowerLineFrequencyChange(XnCallbackHandle hCallback)
+ {
+ _UnregisterFromStateChange(xnUnregisterFromPowerLineFrequencyChange, GetHandle(), hCallback);
+ }
+ };
+
+ /**
+ * @ingroup cppref_prd_func
+ *
+ * <b>Purpose:</b> The MapGenerator class is the base class for every generator node
+ * that produces 2D map data, for example, depth maps, color image maps, IR maps, and
+ * scene analysis maps.
+ *
+ * <b>Usage: </b> This class might be instantiated to reference any kind of map generator
+ * node (i.e., a node that derives from the MapGenerator class), however it is not intended
+ * to ever be instantiated to create any node of MapGenerator type itself.
+ *
+ * <b>Remarks:</b>
+ *
+ * Since the MapGenerator class is the base class for generator nodes that produce image
+ * maps, it provides the data structures common to all map generators: the current frame's
+ * X and Y dimensions and its frame rate.
+ *
+ * MapGenerator's two principle functions are GetMapOutputMode() and SetMapOutputMode()
+ * for controlling and checking the node's map output mode. The map output mode is the
+ * combination of the node's scene resolution and frame rate. Correspondingly, these
+ * functions read and write an @ref xn::XnMapOutputMode structure, comprising three
+ * parameters: the X and Y resolutions and the frame rate.
+ */
+ class MapGenerator : public Generator
+ {
+ public:
+ /**
+ * Ctor
+ *
+ * @param [in] hNode Node handle
+ */
+ inline MapGenerator(XnNodeHandle hNode = NULL) : Generator(hNode) {}
+ inline MapGenerator(const NodeWrapper& other) : Generator(other) {}
+
+ /**
+ * @brief Gets the number of output modes that the generator node supports.
+ *
+ * <b>Remarks</b>
+ *
+ * This is useful for allocating an array that will be passed to GetSupportedMapOutputModes().
+ */
+ inline XnUInt32 GetSupportedMapOutputModesCount() const
+ {
+ return xnGetSupportedMapOutputModesCount(GetHandle());
+ }
+
+ /**
+ * @brief Gets a list of all the output modes that the generator node supports.
+ *
+ * <b>Remarks</b>
+ *
+ * Each supported map output mode is represented by a @ref XnMapOutputMode structure
+ * comprising resolution (@c nXRes and @c nYRes) and frames rate (@c nFPS). The application
+ * then chooses one of the output modes. The size of the array that should be passed
+ * can be obtained by calling GetSupportedMapOutputModesCount().
+ */
+ inline XnStatus GetSupportedMapOutputModes(XnMapOutputMode* aModes, XnUInt32& nCount) const
+ {
+ return xnGetSupportedMapOutputModes(GetHandle(), aModes, &nCount);
+ }
+
+ /**
+ * @brief Sets the current map output mode of the generator node.
+ *
+ * <b>Remarks</b>
+ *
+ * A map output mode is contained in a @ref xn::XnMapOutputMode structure comprising
+ * the frame rate (in frames per second), and the X and Y dimensions (the number
+ * of elements in each of the X- and Y- axes).
+ *
+ * It is the application programmer's responsibility to check first if the output
+ * mode is supported by calling the @ref xn::MapGenerator::GetSupportedMapOutputModes()
+ * "GetSupportedMapOutputModes()" method.
+ */
+ inline XnStatus SetMapOutputMode(const XnMapOutputMode& OutputMode)
+ {
+ return xnSetMapOutputMode(GetHandle(), &OutputMode);
+ }
+
+ /**
+ * @brief Gets the current map output mode of the generator node. This is the
+ * map output mode that the generator node will use to generate the next data frame.
+ *
+ * <b>Remarks</b>
+ *
+ * A map output mode is the combination of the scene resolution and frame rate.
+ * It is contained in an @ref xn::XnMapOutputMode structure comprising the frame
+ * rate (in frames per second), and the X and Y dimensions (the number of elements
+ * in each of the X- and Y- axes).
+ *
+ * For the map output mode of the most recent data frame available in the node's
+ * metadata object, see the @ref xn::MapMetaData class (MapMetaData::Xres(), MapMetaData::YRes(),
+ * and MapMetaData::FPS() methods).
+ *
+ * This map output mode is the mode set by @ref SetMapOutputMode().
+ */
+ inline XnStatus GetMapOutputMode(XnMapOutputMode &OutputMode) const
+ {
+ return xnGetMapOutputMode(GetHandle(), &OutputMode);
+ }
+
+ /**
+ * @brief Gets the number of bytes per pixel for the node's map data. This mode
+ * is set by SetPixelFormat() for the next frame that the generator node generates.
+ *
+ * <b>Remarks</b>
+ *
+ * In ImageGenerator this can be set. In other generators, it's pre-defined.
+ */
+ inline XnUInt32 GetBytesPerPixel() const
+ {
+ return xnGetBytesPerPixel(GetHandle());
+ }
+
+ /**
+ * @brief Registers an event handler for the 'Map Output Mode Change' event.
+ *
+ * @param [in] handler Callback function to be invoked when the event is raised.
+ * @param [in] pCookie User's cookie, to be delivered to the callback.
+ * @param [out] hCallback Handle to the callback to be used for unregistering it.
+ *
+ * For full details and usage of the parameters, see @ref reg_to_events.
+ */
+ inline XnStatus RegisterToMapOutputModeChange(StateChangedHandler handler, void* pCookie, XnCallbackHandle& hCallback)
+ {
+ return _RegisterToStateChange(xnRegisterToMapOutputModeChange, GetHandle(), handler, pCookie, hCallback);
+ }
+
+ /**
+ * @brief Unregisters the event handler for the 'Map Output Mode Change' event.
+ *
+ * @param [in] hCallback Handle received from registration.
+ *
+ * For full details and usage of the parameter, see @ref unreg_from_events .
+ */
+ inline void UnregisterFromMapOutputModeChange(XnCallbackHandle hCallback)
+ {
+ _UnregisterFromStateChange(xnUnregisterFromMapOutputModeChange, GetHandle(), hCallback);
+ }
+
+ /**
+ * @brief Gets a @ref CroppingCapability object for accessing Cropping functionality.
+ *
+ * <b>Remarks</b>
+ *
+ * It is the application's responsibility to check first if @ref XN_CAPABILITY_CROPPING
+ * is supported by calling @ref IsCapabilitySupported().
+ */
+ inline const CroppingCapability GetCroppingCap() const
+ {
+ return CroppingCapability(GetHandle());
+ }
+
+ /**
+ * @brief Gets a @ref CroppingCapability object for accessing Cropping functionality.
+ *
+ * <b>Remarks</b>
+ *
+ * It is the application's responsibility to check first if @ref XN_CAPABILITY_CROPPING
+ * is supported by calling @ref IsCapabilitySupported().
+ */
+ inline CroppingCapability GetCroppingCap()
+ {
+ return CroppingCapability(GetHandle());
+ }
+
+ /**
+ * Gets an @ref GeneralIntCapability object for accessing Brightness functionality.
+ * It is the application responsibility to check first if @ref XN_CAPABILITY_BRIGHTNESS
+ * is supported by calling @ref IsCapabilitySupported().
+ */
+ inline GeneralIntCapability GetBrightnessCap()
+ {
+ return GeneralIntCapability(GetHandle(), XN_CAPABILITY_BRIGHTNESS);
+ }
+
+ /**
+ * Gets an @ref GeneralIntCapability object for accessing Contrast functionality.
+ * It is the application responsibility to check first if @ref XN_CAPABILITY_CONTRAST
+ * is supported by calling @ref IsCapabilitySupported().
+ */
+ inline GeneralIntCapability GetContrastCap()
+ {
+ return GeneralIntCapability(GetHandle(), XN_CAPABILITY_CONTRAST);
+ }
+
+ /**
+ * Gets an @ref GeneralIntCapability object for accessing Hue functionality.
+ * It is the application responsibility to check first if @ref XN_CAPABILITY_HUE
+ * is supported by calling @ref IsCapabilitySupported().
+ */
+ inline GeneralIntCapability GetHueCap()
+ {
+ return GeneralIntCapability(GetHandle(), XN_CAPABILITY_HUE);
+ }
+
+ /**
+ * Gets an @ref GeneralIntCapability object for accessing Saturation functionality.
+ * It is the application responsibility to check first if @ref XN_CAPABILITY_SATURATION
+ * is supported by calling @ref IsCapabilitySupported().
+ */
+ inline GeneralIntCapability GetSaturationCap()
+ {
+ return GeneralIntCapability(GetHandle(), XN_CAPABILITY_SATURATION);
+ }
+
+ /**
+ * Gets an @ref GeneralIntCapability object for accessing Sharpness functionality.
+ * It is the application responsibility to check first if @ref XN_CAPABILITY_SHARPNESS
+ * is supported by calling @ref IsCapabilitySupported().
+ */
+ inline GeneralIntCapability GetSharpnessCap()
+ {
+ return GeneralIntCapability(GetHandle(), XN_CAPABILITY_SHARPNESS);
+ }
+
+ /**
+ * Gets an @ref GeneralIntCapability object for accessing Gamma functionality.
+ * It is the application responsibility to check first if @ref XN_CAPABILITY_GAMMA
+ * is supported by calling @ref IsCapabilitySupported().
+ */
+ inline GeneralIntCapability GetGammaCap()
+ {
+ return GeneralIntCapability(GetHandle(), XN_CAPABILITY_GAMMA);
+ }
+
+ /**
+ * Gets an @ref GeneralIntCapability object for accessing WhiteBalance functionality.
+ * It is the application responsibility to check first if @ref XN_CAPABILITY_COLOR_TEMPERATURE
+ * is supported by calling @ref IsCapabilitySupported().
+ */
+ inline GeneralIntCapability GetWhiteBalanceCap()
+ {
+ return GeneralIntCapability(GetHandle(), XN_CAPABILITY_COLOR_TEMPERATURE);
+ }
+
+ /**
+ * Gets an @ref GeneralIntCapability object for accessing BacklightCompensation functionality.
+ * It is the application responsibility to check first if @ref XN_CAPABILITY_BACKLIGHT_COMPENSATION
+ * is supported by calling @ref IsCapabilitySupported().
+ */
+ inline GeneralIntCapability GetBacklightCompensationCap()
+ {
+ return GeneralIntCapability(GetHandle(), XN_CAPABILITY_BACKLIGHT_COMPENSATION);
+ }
+
+ /**
+ * Gets an @ref GeneralIntCapability object for accessing Gain functionality.
+ * It is the application responsibility to check first if @ref XN_CAPABILITY_GAIN
+ * is supported by calling @ref IsCapabilitySupported().
+ */
+ inline GeneralIntCapability GetGainCap()
+ {
+ return GeneralIntCapability(GetHandle(), XN_CAPABILITY_GAIN);
+ }
+
+ /**
+ * Gets an @ref GeneralIntCapability object for accessing Pan functionality.
+ * It is the application responsibility to check first if @ref XN_CAPABILITY_PAN
+ * is supported by calling @ref IsCapabilitySupported().
+ */
+ inline GeneralIntCapability GetPanCap()
+ {
+ return GeneralIntCapability(GetHandle(), XN_CAPABILITY_PAN);
+ }
+
+ /**
+ * Gets an @ref GeneralIntCapability object for accessing Tilt functionality.
+ * It is the application responsibility to check first if @ref XN_CAPABILITY_TILT
+ * is supported by calling @ref IsCapabilitySupported().
+ */
+ inline GeneralIntCapability GetTiltCap()
+ {
+ return GeneralIntCapability(GetHandle(), XN_CAPABILITY_TILT);
+ }
+
+ /**
+ * Gets an @ref GeneralIntCapability object for accessing Roll functionality.
+ * It is the application responsibility to check first if @ref XN_CAPABILITY_ROLL
+ * is supported by calling @ref IsCapabilitySupported().
+ */
+ inline GeneralIntCapability GetRollCap()
+ {
+ return GeneralIntCapability(GetHandle(), XN_CAPABILITY_ROLL);
+ }
+
+ /**
+ * Gets an @ref GeneralIntCapability object for accessing Zoom functionality.
+ * It is the application responsibility to check first if @ref XN_CAPABILITY_ZOOM
+ * is supported by calling @ref IsCapabilitySupported().
+ */
+ inline GeneralIntCapability GetZoomCap()
+ {
+ return GeneralIntCapability(GetHandle(), XN_CAPABILITY_ZOOM);
+ }
+
+ /**
+ * Gets an @ref GeneralIntCapability object for accessing Exposure functionality.
+ * It is the application responsibility to check first if @ref XN_CAPABILITY_EXPOSURE
+ * is supported by calling @ref IsCapabilitySupported().
+ */
+ inline GeneralIntCapability GetExposureCap()
+ {
+ return GeneralIntCapability(GetHandle(), XN_CAPABILITY_EXPOSURE);
+ }
+
+ /**
+ * Gets an @ref GeneralIntCapability object for accessing Iris functionality.
+ * It is the application responsibility to check first if @ref XN_CAPABILITY_IRIS
+ * is supported by calling @ref IsCapabilitySupported().
+ */
+ inline GeneralIntCapability GetIrisCap()
+ {
+ return GeneralIntCapability(GetHandle(), XN_CAPABILITY_IRIS);
+ }
+
+ /**
+ * Gets an @ref GeneralIntCapability object for accessing Focus functionality.
+ * It is the application responsibility to check first if @ref XN_CAPABILITY_FOCUS
+ * is supported by calling @ref IsCapabilitySupported().
+ */
+ inline GeneralIntCapability GetFocusCap()
+ {
+ return GeneralIntCapability(GetHandle(), XN_CAPABILITY_FOCUS);
+ }
+
+ /**
+ * Gets an @ref GeneralIntCapability object for accessing Low Light Compensation functionality.
+ * It is the application responsibility to check first if @ref XN_CAPABILITY_LOW_LIGHT_COMPENSATION
+ * is supported by calling @ref IsCapabilitySupported().
+ */
+ inline GeneralIntCapability GetLowLightCompensationCap()
+ {
+ return GeneralIntCapability(GetHandle(), XN_CAPABILITY_LOW_LIGHT_COMPENSATION);
+ }
+
+ /**
+ * Gets an @ref AntiFlickerCapability object for accessing Anti Flicker functionality.
+ * It is the application responsibility to check first if @ref XN_CAPABILITY_ANTI_FLICKER
+ * is supported by calling @ref IsCapabilitySupported().
+ */
+ inline AntiFlickerCapability GetAntiFlickerCap()
+ {
+ return AntiFlickerCapability(GetHandle());
+ }
+ };
+
+ /**
+ * @ingroup cppref_prd_func
+ * Allows access to <b>User Position</b> capability functions. see @ref userpos for
+ * additional details.
+ *
+ * <b>Usage:</b> Do not instantiate directly. Instead, use @ref DepthGenerator::GetUserPositionCap()
+ * to obtain an instance.
+ */
+ class UserPositionCapability : public Capability
+ {
+ public:
+ /**
+ * Ctor
+ *
+ * @param [in] hNode Node handle
+ */
+ inline UserPositionCapability(XnNodeHandle hNode = NULL) : Capability(hNode) {}
+ UserPositionCapability(const NodeWrapper& node) : Capability(node) {}
+
+ /**
+ * @copybrief xnGetSupportedUserPositionsCount
+ * For full details and usage, see @ref xnGetSupportedUserPositionsCount
+ */
+ inline XnUInt32 GetSupportedUserPositionsCount() const
+ {
+ return xnGetSupportedUserPositionsCount(GetHandle());
+ }
+
+ /**
+ * @copybrief xnSetUserPosition
+ * For full details and usage, see @ref xnSetUserPosition
+ */
+ inline XnStatus SetUserPosition(XnUInt32 nIndex, const XnBoundingBox3D& Position)
+ {
+ return xnSetUserPosition(GetHandle(), nIndex, &Position);
+ }
+
+ /**
+ * @copybrief xnGetUserPosition
+ * For full details and usage, see @ref xnGetUserPosition
+ */
+ inline XnStatus GetUserPosition(XnUInt32 nIndex, XnBoundingBox3D& Position) const
+ {
+ return xnGetUserPosition(GetHandle(), nIndex, &Position);
+ }
+
+ /**
+ * @brief Registers an event handler for the 'User Position Change' event.
+ *
+ * @param [in] handler Callback function to be invoked when the event is raised.
+ * @param [in] pCookie User's cookie, to be delivered to the callback.
+ * @param [out] hCallback Handle to the callback to be used for unregistering it.
+ *
+ * For full details and usage of the parameters, see @ref reg_to_events.
+ */
+ inline XnStatus RegisterToUserPositionChange(StateChangedHandler handler, void* pCookie, XnCallbackHandle& hCallback)
+ {
+ return _RegisterToStateChange(xnRegisterToUserPositionChange, GetHandle(), handler, pCookie, hCallback);
+ }
+
+ /**
+ * @brief Unregisters the event handler for the 'User Position Change' event.
+ *
+ * @param [in] hCallback Handle received from registration.
+ *
+ * For full details and usage of the parameter, see @ref unreg_from_events .
+ */
+ inline void UnregisterFromUserPositionChange(XnCallbackHandle hCallback)
+ {
+ _UnregisterFromStateChange(xnUnregisterFromUserPositionChange, GetHandle(), hCallback);
+ }
+ };
+
+ /**
+ * @ingroup cppref_prd_func
+ * <b>Purpose:</b> A DepthGenerator node generates depth maps. Each pixel value of
+ * a depth map represents a distance from the sensor's plane in millimeters.
+ *
+ * <b>Usage:</b> Instantiate the class and call Create() to create a DepthGenerator
+ * node.
+ *
+ * This class is at the first level of classes in the OpenNI class hierarchy that is
+ * typically instantiated to create an actual node. (Examples of other classes at the
+ * first level are @ref xn::ImageGenerator and @ref xn::SceneAnalyzer).
+ *
+ * <b>Data output:</b> Depth maps and associated configuration data. Access via the node's
+ * @ref xn::DepthMetaData object.
+ *
+ * <b>Overview:</b>
+ *
+ * A DepthGenerator node generates a depth map as an array of pixels, where each pixel
+ * is a depth value representing a distance from the sensor's plane in millimeters. This is
+ * the Z-coordinate of the X-Y-Z coordinate of each user pixel. A smaller depth value
+ * indicates a scene point that is <i>closer</i> to the hardware sensor device; and
+ * a larger depth value indicates a scene point that is a <i>further away</i> from the
+ * sensor. A zero depth value indicates that the DepthGenerator node did not succeed
+ * in obtaining a valid depth reading.
+ *
+ * Typically, the process of generating 3D data begins by using a sensor device that
+ * produces raw output data. Dedicated middleware is then used to process this raw output,
+ * and produce a higher-level output, which can then be understood and used by the application.
+ *
+ * In a typical OpenNI production graph, a DepthGenerator node takes input directly
+ * from a sensor device and generates a depth map. Other generator nodes further along
+ * the production graph (dependant on the DepthGenerator node) take input from the DepthGenerator
+ * node's output. However, alternative dependency configurations are also possible.
+ *
+ * The DepthGenerator node's data and associated configuration are accessed through
+ * its @ref glos_frame_object "frame object" (i.e., its @ref xn::DepthMetaData object).
+ *
+ * Summary of Main Features:
+ * - Depth map: Provides the data of the depth map
+ * - Sensor device's maximum depth: Provides the maximum distance available for this
+ * depth generator
+ * - Field of View: Provides the sensor's maximum horizontal and vertical angles
+ * - User Position capability (optional)
+ */
+ class DepthGenerator : public MapGenerator
+ {
+ public:
+ /**
+ * Ctor
+ *
+ * @param [in] hNode Node handle
+ */
+ inline DepthGenerator(XnNodeHandle hNode = NULL) : MapGenerator(hNode) {}
+ inline DepthGenerator(const NodeWrapper& other) : MapGenerator(other) {}
+
+ /**
+ * @brief Creates a DepthGenerator node from available @ref node_alternative "production node alternatives".
+ *
+ * <b>Remarks:</b>
+ *
+ * For full details and usage, see @ref create_method.
+ */
+ inline XnStatus Create(Context& context, Query* pQuery = NULL, EnumerationErrors* pErrors = NULL);
+
+ /**
+ * @brief Gets the depth generator node's latest @ref glos_frame_object "frame object", saving
+ * it in the @ref xn::DepthMetaData object. This @ref glos_frame_object "frame object" is a
+ * snapshot of the generated depth map data and its associated configuration information at a
+ * certain point in time. This saved @ref glos_frame_object "frame object" provides fast
+ * and easy access to the depth generator node's data and configuration information.
+ *
+ * @param [out] metaData Structure to be filled with the frame object.
+ *
+ * <b>Remarks:</b>
+ *
+ * This method is central in the use of the DepthGenerator node. Once the DepthGenerator
+ * node is generating data, after each @ref conc_updating_data "'Update Data'" call,
+ * the application calls this method to get the node's frame object, which contains
+ * the data and all its associated properties.
+ */
+ inline void GetMetaData(DepthMetaData& metaData) const
+ {
+ xnGetDepthMetaData(GetHandle(), metaData.GetUnderlying());
+ }
+
+ /**
+ * @copybrief xnGetDepthMap
+ * For full details and usage, see @ref xnGetDepthMap
+ */
+ inline const XnDepthPixel* GetDepthMap() const
+ {
+ return xnGetDepthMap(GetHandle());
+ }
+
+ /**
+ * @brief Gets the maximum depth value that the DepthGenerator node can generate.
+ * The maximum depth value is a hardware specification of the sensor.
+ *
+ * <b>Remarks:</b>
+ *
+ * A typical maximum depth supports up to 10 meters of depth. Units are in millimeters,
+ * so the maximum depth value for 10 meters of depth would range from 0 to 10,000.
+ */
+ inline XnDepthPixel GetDeviceMaxDepth() const
+ {
+ return xnGetDeviceMaxDepth(GetHandle());
+ }
+
+ /**
+ * @brief Gets the dimensions of the field of view (FOV) of the hardware sensor.
+ *
+ * @param [out] FOV A struct to be filled with the field of view of the hardware sensor.
+ *
+ * <b>Remarks:</b>
+ *
+ * This method gets the dimensions of the field of view in radians. Radians are
+ * used for the output form since they are a spherical measurement and the FOV is
+ * defined in terms of the angle of width and height that the sensor sees, e.g.,
+ * 0.524 radians (30 degrees) above and below, and 1.047 radians (60 degrees) left
+ * and right.
+ *
+ * This method is useful for developers building algorithms to convert between real
+ * world and productive coordinate systems. Although OpenNI offers its own functionality
+ * for converting real-world and productive coordinate systems, some developers
+ * may wish to build their own conversion functions for reasons of optimization.
+ */
+ inline XnStatus GetFieldOfView(XnFieldOfView& FOV) const
+ {
+ return xnGetDepthFieldOfView(GetHandle(), &FOV);
+ }
+
+ /**
+ * @brief Registers an event handler for the 'Field-Of-View Change' event.
+ *
+ * @param [in] handler Callback function to be invoked when the event is raised.
+ * @param [in] pCookie User's cookie, to be delivered to the callback.
+ * @param [out] hCallback Handle to the callback to be used for unregistering it.
+ *
+ * For full details and usage of the parameters, see @ref reg_to_events.
+ */
+ inline XnStatus RegisterToFieldOfViewChange(StateChangedHandler handler, void* pCookie, XnCallbackHandle& hCallback)
+ {
+ return _RegisterToStateChange(xnRegisterToDepthFieldOfViewChange, GetHandle(), handler, pCookie, hCallback);
+ }
+
+ /**
+ * @brief Unregisters the event handler for the 'Field-Of-View Change' event.
+ *
+ * @param [in] hCallback Handle received from registration.
+ *
+ * For full details and usage of the parameter, see @ref unreg_from_events .
+ */
+ inline void UnregisterFromFieldOfViewChange(XnCallbackHandle hCallback)
+ {
+ _UnregisterFromStateChange(xnUnregisterFromDepthFieldOfViewChange, GetHandle(), hCallback);
+ }
+
+ /**
+ * @brief Converts a list of points from projective coordinates to real world coordinates.
+ *
+ * @param [in] nCount Number of points to convert.
+ * @param [in] aProjective Array of projective point coordinates.
+ * @param [in,out] aRealWorld Array to be filled with real-world point coordinates.
+ *
+ * See @ref conc_coord for futher information.
+ */
+ inline XnStatus ConvertProjectiveToRealWorld(XnUInt32 nCount, const XnPoint3D aProjective[], XnPoint3D aRealWorld[]) const
+ {
+ return xnConvertProjectiveToRealWorld(GetHandle(), nCount, aProjective, aRealWorld);
+ }
+
+ /**
+ * @brief Converts a list of points from real world coordinates to projective coordinates.
+ *
+ * @param [in] nCount Number of points to convert.
+ * @param [in] aRealWorld Array of projective point coordinates.
+ * @param [in,out] aProjective Array to be filled with real-world point coordinates.
+ *
+ * See @ref conc_coord for futher information.
+ */
+ inline XnStatus ConvertRealWorldToProjective(XnUInt32 nCount, const XnPoint3D aRealWorld[], XnPoint3D aProjective[]) const
+ {
+ return xnConvertRealWorldToProjective(GetHandle(), nCount, aRealWorld, aProjective);
+ }
+
+ /**
+ * Gets an @ref UserPositionCapability object for accessing User Position functionality.
+ * It is the application responsibility to check first if @ref XN_CAPABILITY_USER_POSITION
+ * is supported by calling @ref IsCapabilitySupported().
+ */
+ inline const UserPositionCapability GetUserPositionCap() const
+ {
+ return UserPositionCapability(GetHandle());
+ }
+
+ /**
+ * Gets an @ref UserPositionCapability object for accessing User Position functionality.
+ * It is the application responsibility to check first if @ref XN_CAPABILITY_USER_POSITION
+ * is supported by calling @ref IsCapabilitySupported().
+ */
+ inline UserPositionCapability GetUserPositionCap()
+ {
+ return UserPositionCapability(GetHandle());
+ }
+ };
+
+ /**
+ * @ingroup cppref_prd_func
+ * Represents a mock depth generator
+ */
+ class MockDepthGenerator : public DepthGenerator
+ {
+ public:
+ /**
+ * Ctor
+ *
+ * @param [in] hNode Node handle
+ */
+ inline MockDepthGenerator(XnNodeHandle hNode = NULL) : DepthGenerator(hNode) {}
+ inline MockDepthGenerator(const NodeWrapper& other) : DepthGenerator(other) {}
+
+ /**
+ * Creates a mock depth generator
+ *
+ * @param [in] context The context in which the node should be generated
+ * @param [in] strName Optional. The name of the new node.
+ */
+ XnStatus Create(Context& context, const XnChar* strName = NULL);
+
+ /**
+ * Creates a mock depth generator, copying the initial state from another depth
+ * generator.
+ *
+ * @param [in] other The depth generator to copy state from
+ * @param [in] strName Optional. The name of the new node.
+ */
+ XnStatus CreateBasedOn(DepthGenerator& other, const XnChar* strName = NULL);
+
+ /**
+ * @copybrief xnMockDepthSetData
+ * For full details and usage, see @ref xnMockDepthSetData
+ */
+ inline XnStatus SetData(XnUInt32 nFrameID, XnUInt64 nTimestamp, XnUInt32 nDataSize, const XnDepthPixel* pDepthMap)
+ {
+ return xnMockDepthSetData(GetHandle(), nFrameID, nTimestamp, nDataSize, pDepthMap);
+ }
+
+ /**
+ * Sets the data of the mock node from a meta data object, overriding frame ID and
+ * timestamp
+ *
+ * @param [in] depthMD Object to take data from
+ * @param [in] nFrameID Frame ID
+ * @param [in] nTimestamp Timestamp
+ */
+ inline XnStatus SetData(const DepthMetaData& depthMD, XnUInt32 nFrameID, XnUInt64 nTimestamp)
+ {
+ return SetData(nFrameID, nTimestamp, depthMD.DataSize(), depthMD.Data());
+ }
+
+ /**
+ * Sets the data of the mock node from a metadata object.
+ *
+ * @param [in] depthMD Object to take data from
+ */
+ inline XnStatus SetData(const DepthMetaData& depthMD)
+ {
+ return SetData(depthMD, depthMD.FrameID(), depthMD.Timestamp());
+ }
+ };
+
+ /**
+ * @ingroup cppref_prd_func
+ * <b>Purpose:</b> The ImageGenerator node generates color image maps of various formats.
+ *
+ * <b>Usage:</b> Instantiate the class and create an image generator node
+ *
+ * <b>Data output:</b> Image maps
+ *
+ * <b>Overview:</b>
+ *
+ * The ImageGenerator node generates color image maps of various formats, such as the
+ * RGB24 image format. Call its SetPixelFormat() method to set the image format to be
+ * generated.
+ *
+ * The other important function here is GetMetaData(), which, as in other generator
+ * nodes, gets the image frame object, through which you can access all the properties
+ * and the actual data of the saved frame.
+ */
+ class ImageGenerator : public MapGenerator
+ {
+ public:
+ /**
+ * Ctor
+ *
+ * @param [in] hNode Node handle
+ */
+ inline ImageGenerator(XnNodeHandle hNode = NULL) : MapGenerator(hNode) {}
+ inline ImageGenerator(const NodeWrapper& other) : MapGenerator(other) {}
+
+ /**
+ * @brief Creates and initializes an ImageGenerator node from available @ref node_alternative "production node alternatives".
+ *
+ * For full details and usage, see @ref create_method.
+ */
+ inline XnStatus Create(Context& context, Query* pQuery = NULL, EnumerationErrors* pErrors = NULL);
+
+ /**
+ * @brief Gets the image generator node's latest @ref glos_frame_object "frame object", saving
+ * it in the @ref xn::ImageMetaData object. This @ref glos_frame_object "frame object" is a
+ * snapshot of the generated image map data and its associated configuration information at a
+ * certain point in time. This saved @ref glos_frame_object "frame object" provides fast
+ * and easy access to the image generator node's data and configuration information.
+ *
+ * @param [out] metaData Structure to be filled with the frame object.
+ *
+ * <b>Remarks:</b>
+ *
+ * This method is central in the use of the ImageGenerator node. Once the ImageGenerator
+ * node is generating data, after each @ref conc_updating_data "'Update Data'" call,
+ * the application calls this method to get the node's frame object, which contains
+ * the data and all its associated properties.
+ */
+ inline void GetMetaData(ImageMetaData& metaData) const
+ {
+ xnGetImageMetaData(GetHandle(), metaData.GetUnderlying());
+ }
+
+ /**
+ * @copybrief xnGetRGB24ImageMap
+ * For full details and usage, see @ref xnGetRGB24ImageMap
+ */
+ inline const XnRGB24Pixel* GetRGB24ImageMap() const
+ {
+ return xnGetRGB24ImageMap(GetHandle());
+ }
+
+ /**
+ * @copybrief xnGetYUV422ImageMap
+ * For full details and usage, see @ref xnGetYUV422ImageMap
+ */
+ inline const XnYUV422DoublePixel* GetYUV422ImageMap() const
+ {
+ return xnGetYUV422ImageMap(GetHandle());
+ }
+
+ /**
+ * @copybrief xnGetGrayscale8ImageMap
+ * For full details and usage, see @ref xnGetGrayscale8ImageMap
+ */
+ inline const XnGrayscale8Pixel* GetGrayscale8ImageMap() const
+ {
+ return xnGetGrayscale8ImageMap(GetHandle());
+ }
+
+ /**
+ * @copybrief xnGetGrayscale16ImageMap
+ * For full details and usage, see @ref xnGetGrayscale16ImageMap
+ */
+ inline const XnGrayscale16Pixel* GetGrayscale16ImageMap() const
+ {
+ return xnGetGrayscale16ImageMap(GetHandle());
+ }
+
+ /**
+ * @copybrief xnGetImageMap()
+ * For full details, see @ref xnGetImageMap().
+ */
+ inline const XnUInt8* GetImageMap() const
+ {
+ return xnGetImageMap(GetHandle());
+ }
+
+ /**
+ * @brief Returns whether the ImageGenerator node supports a specific
+ * pixel color format for the image map.
+ *
+ * @param [in] Format The format to check for.
+ *
+ * <b>Remarks</b>
+ *
+ * Use this method before setting the pixel format for the next frame to be generated.
+ */
+ inline XnBool IsPixelFormatSupported(XnPixelFormat Format) const
+ {
+ return xnIsPixelFormatSupported(GetHandle(), Format);
+ }
+
+ /**
+ * @brief Sets the ImageGenerator node's current 'pixel color' format.
+ * This format is used for generating the next frame.
+ *
+ * @param [in] Format The format to set.
+ *
+ * <b>Remarks</b>
+ *
+ * As an example of a pixel color format, the RGB24 image format has one byte for
+ * red, one byte for green, and one byte for blue.
+ *
+ * When reading the generated data you must use the appropriate 'get' function,
+ * e.g., call RGB24Data() to read data generated as the RGB24Data format.
+ *
+ * It is the user responsibility to check first if the pixel format is supported
+ * by calling @ref xn::ImageGenerator::IsPixelFormatSupported().
+ */
+ inline XnStatus SetPixelFormat(XnPixelFormat Format)
+ {
+ return xnSetPixelFormat(GetHandle(), Format);
+ }
+
+ /**
+ * @brief Gets the current pixel color format. This is the format set
+ * using @ref xn::ImageGenerator node::SetPixelFormat().
+ *
+ * <b>Remarks</b>
+ *
+ * To get the pixel format of the saved frame - in the @ref glos_frame_object "frame
+ * object" - use the appropriate method of the node's associated @ref xn::ImageMetaData
+ * object.
+ */
+ inline XnPixelFormat GetPixelFormat() const
+ {
+ return xnGetPixelFormat(GetHandle());
+ }
+
+ /**
+ * @brief Registers an event handler for the 'Pixel Format Change' event.
+ *
+ * @param [in] handler Callback function to be invoked when the event is raised.
+ * @param [in] pCookie User's cookie, to be delivered to the callback.
+ * @param [out] hCallback Handle to the callback to be used for unregistering it.
+ *
+ * For full details and usage of the parameters, see @ref reg_to_events.
+ */
+ inline XnStatus RegisterToPixelFormatChange(StateChangedHandler handler, void* pCookie, XnCallbackHandle& hCallback)
+ {
+ return _RegisterToStateChange(xnRegisterToPixelFormatChange, GetHandle(), handler, pCookie, hCallback);
+ }
+
+ /**
+ * @brief Unregisters the event handler for the 'Pixel Format Change' event.
+ *
+ * @param [in] hCallback Handle received from registration.
+ *
+ * For full details and usage of the parameter, see @ref unreg_from_events .
+ */
+ inline void UnregisterFromPixelFormatChange(XnCallbackHandle hCallback)
+ {
+ _UnregisterFromStateChange(xnUnregisterFromPixelFormatChange, GetHandle(), hCallback);
+ }
+ };
+
+ /**
+ * @ingroup cppref_prd_func
+ * Represents a mock image generator
+ */
+ class MockImageGenerator : public ImageGenerator
+ {
+ public:
+ /**
+ * Ctor
+ *
+ * @param [in] hNode Node handle
+ */
+ inline MockImageGenerator(XnNodeHandle hNode = NULL) : ImageGenerator(hNode) {}
+ inline MockImageGenerator(const NodeWrapper& other) : ImageGenerator(other) {}
+
+ /**
+ * Creates a mock image generator
+ *
+ * @param [in] context The context in which the node should be generated
+ * @param [in] strName Optional. The name of the new node.
+ */
+ XnStatus Create(Context& context, const XnChar* strName = NULL);
+
+ /**
+ * Creates a mock image generator, copying the initial state from another image
+ * generator.
+ *
+ * @param [in] other The image generator to copy state from
+ * @param [in] strName Optional. The name of the new node.
+ */
+ XnStatus CreateBasedOn(ImageGenerator& other, const XnChar* strName = NULL);
+
+ /**
+ * @copybrief xnMockImageSetData
+ * For full details and usage, see @ref xnMockImageSetData
+ */
+ inline XnStatus SetData(XnUInt32 nFrameID, XnUInt64 nTimestamp, XnUInt32 nDataSize, const XnUInt8* pImageMap)
+ {
+ return xnMockImageSetData(GetHandle(), nFrameID, nTimestamp, nDataSize, pImageMap);
+ }
+
+ /**
+ * Sets the data of the mock node from a meta data object, overriding frame ID and
+ * timestamp
+ *
+ * @param [in] imageMD Object to take data from
+ * @param [in] nFrameID Frame ID
+ * @param [in] nTimestamp Timestamp
+ */
+ inline XnStatus SetData(const ImageMetaData& imageMD, XnUInt32 nFrameID, XnUInt64 nTimestamp)
+ {
+ return SetData(nFrameID, nTimestamp, imageMD.DataSize(), imageMD.Data());
+ }
+
+ /**
+ * Sets the data of the mock node from a meta data object.
+ *
+ * @param [in] imageMD Object to take data from
+ */
+ inline XnStatus SetData(const ImageMetaData& imageMD)
+ {
+ return SetData(imageMD, imageMD.FrameID(), imageMD.Timestamp());
+ }
+ };
+
+ /**
+ * @ingroup cppref_prd_func
+ * <b>Purpose:</b> An IRGenerator node is a map generator that outputs infra-red maps.
+ *
+ * <b>Usage:</b> Instantiate and create an IR generator node
+ *
+ * <b>Data output:</b> IR maps
+ */
+ class IRGenerator : public MapGenerator
+ {
+ public:
+ /**
+ * Ctor
+ *
+ * @param [in] hNode Node handle
+ */
+ inline IRGenerator(XnNodeHandle hNode = NULL) : MapGenerator(hNode) {}
+ inline IRGenerator(const NodeWrapper& other) : MapGenerator(other) {}
+
+ /**
+ * @brief Creates an IRGenerator node from available @ref node_alternative "production node alternatives".
+ *
+ * See @ref create_method for a detailed description
+ * about the operation of this method.
+ */
+ inline XnStatus Create(Context& context, Query* pQuery = NULL, EnumerationErrors* pErrors = NULL);
+
+ /**
+ * @brief Gets the IR generator node's latest @ref glos_frame_object "frame object", saving
+ * it in the @ref xn::IRMetaData object. This @ref glos_frame_object "frame object" is a
+ * snapshot of the generated IR map data and its associated configuration information at a
+ * certain point in time. This saved @ref glos_frame_object "frame object" provides fast
+ * and easy access to the IR generator node's data and configuration information.
+ *
+ * @param [out] metaData Structure to be filled with the frame object.
+ *
+ * <b>Remarks:</b>
+ *
+ * This method is central in the use of the IRGenerator node. Once the IRGenerator
+ * node is generating data, after each @ref conc_updating_data "'Update Data'" call,
+ * the application calls this method to get the node's frame object, which contains
+ * the data and all its associated properties.
+ */
+ inline void GetMetaData(IRMetaData& metaData) const
+ {
+ xnGetIRMetaData(GetHandle(), metaData.GetUnderlying());
+ }
+
+ /**
+ * @brief Gets a pointer to the latest IR map.
+ */
+ inline const XnIRPixel* GetIRMap() const
+ {
+ return xnGetIRMap(GetHandle());
+ }
+ };
+
+ /**
+ * @ingroup cppref_prd_func
+ * Represents a mock IR generator
+ */
+ class MockIRGenerator : public IRGenerator
+ {
+ public:
+ /**
+ * Ctor
+ *
+ * @param [in] hNode Node handle
+ */
+ inline MockIRGenerator(XnNodeHandle hNode = NULL) : IRGenerator(hNode) {}
+ inline MockIRGenerator(const NodeWrapper& other) : IRGenerator(other) {}
+
+ /**
+ * Creates a mock IR generator
+ *
+ * @param [in] context The context in which the node should be generated
+ * @param [in] strName Optional. The name of the new node.
+ */
+ XnStatus Create(Context& context, const XnChar* strName = NULL);
+ /**
+ * Creates a mock IR generator, copying the initial state from another IR generator.
+ *
+ * @param [in] other The IR generator to copy state from
+ * @param [in] strName Optional. The name of the new node.
+ */
+ XnStatus CreateBasedOn(IRGenerator& other, const XnChar* strName = NULL);
+
+ /**
+ * @copybrief xnMockIRSetData
+ * For full details and usage, see @ref xnMockIRSetData
+ */
+ inline XnStatus SetData(XnUInt32 nFrameID, XnUInt64 nTimestamp, XnUInt32 nDataSize, const XnIRPixel* pIRMap)
+ {
+ return xnMockIRSetData(GetHandle(), nFrameID, nTimestamp, nDataSize, pIRMap);
+ }
+
+ /**
+ * Sets the data of the mock node from a meta data object, overriding frame ID and
+ * timestamp
+ *
+ * @param [in] irMD Object to take data from
+ * @param [in] nFrameID Frame ID
+ * @param [in] nTimestamp Timestamp
+ */
+ inline XnStatus SetData(const IRMetaData& irMD, XnUInt32 nFrameID, XnUInt64 nTimestamp)
+ {
+ return SetData(nFrameID, nTimestamp, irMD.DataSize(), irMD.Data());
+ }
+
+ /**
+ * Sets the data of the mock node from a meta data object.
+ *
+ * @param [in] irMD Object to take data from
+ */
+ inline XnStatus SetData(const IRMetaData& irMD)
+ {
+ return SetData(irMD, irMD.FrameID(), irMD.Timestamp());
+ }
+ };
+
+ /**
+ * @ingroup cppref_prd_func
+ * <b>Purpose:</b>A GesturesGenerator node recognizes certain hand gestures and raise
+ * corresponding events accordingly.
+ *
+ * A gesture is a specific hand movement. The gesture generator node scans the FOV to
+ * detect gestures and generates the gesture data.
+ *
+ * <b>Usage:</b> Instantiate to create a gesture generator node.
+ *
+ * An example of a gesture is a specific hand movement. For example, the developer who builds
+ * a gesture generator node can decide that waving a hand can be a gesture; pushing can be a gesture.
+ * The developer can build an OpenNI gesture generator to support any number of gestures.
+ *
+ * <b>Overview with Sample of a Usage Scenario:</b>
+ *
+ * @note Everything in this introduction is just an @e example of usage; there
+ * is no obligation to use the gesture generator node in the particular way described
+ * here.
+ *
+ * An application might want to know who is the person they should interact with. For example,
+ * if currently there are three people in the room, which hand should be tracked?
+ *
+ * The application can use a specific gesture (such as waving to the camera) as a focus gesture,
+ * meaning the person who performs this gesture will be the one interacting with the application.
+ *
+ * To do that, the application can use a GestureGenerator to detect that specific gesture and then
+ * use the position of that gesture to initialize the HandsGenerator, asking it to track the hand
+ * located at that position. (There is no inherent connection between the GestureGenerator and the
+ * HandsGenerator. Detecting a gesture and using that position to initialize the HandsGenerator is
+ * just an example of how applications can use the two).
+ *
+ * <b>Sample Process: Setting up a Gesture Generator</b>
+ *
+ * <b>1. Creating a Gesture Generator </b>
+ *
+ * Assuming there is a gesture generator module (plug-in) installed on the computer, the application
+ * can create a gesture generator node and configure it to recognize gestures. As for many other
+ * types of generator nodes, use the @ref Create() method of the GestureGenerator class to create a
+ * gesture generator node.
+ *
+ * <b>2. Enumerating generators</b>
+ *
+ * Now, once the application has created a gesture generator node, the application can
+ * find out which gestures are supported by enumerating all its gestures. The gestures
+ * are identified by their names, e.g., "Wave" and "Click".
+ *
+ * The gesture generator node maintains a list of active gestures. An active gesture
+ * is a gesture for which the gesture generator is scanning the FOV in an attempt
+ * to recognize the gesture. Thus, to cause the gesture generator node to start scanning
+ * for a gesture, the application must add it to its list of active gestures.
+ *
+ * In a typical application, the application detects one gesture - the focus gesture -
+ * and can then send its location to the hand generator node. The application typically
+ * will then not want to recognize further gestures and so it must remove the gesture from
+ * the list; further gestures in the FOV may cause confusion. For example, if one particular
+ * human user started to control the TV, that user would not want someone else "taking the control".
+ *
+ * <b>3. Recognizing Gestures </b>
+ *
+ * Every gesture has an identification point (the position where the gesture was identified - perhaps
+ * in retrospect) and an end point (the position in which the hand currently is), although in most cases,
+ * both points will be the same. The application must know the position of the end of the gesture
+ * movement; because that's where the hand really is at the time the application gets the 'Gesture Recognized'
+ * event. The gesture generator sends both positions with the 'Gesture Recognized' event to the application.
+ * The application can then pass the end position to the hand generator for tracking that hand.
+ */
+ class GestureGenerator : public Generator
+ {
+ public:
+ /**
+ * Ctor
+ *
+ * @param [in] hNode Node handle
+ */
+ inline GestureGenerator(XnNodeHandle hNode = NULL) : Generator(hNode) {}
+ inline GestureGenerator(const NodeWrapper& other) : Generator(other) {}
+
+ /**
+ * @brief Creates a gesture generator node from available @ref node_alternative "production node alternatives".
+ *
+ * <b>Remarks</b>
+ *
+ * The application then uses the @ref AddGesture() method in order to activate the
+ * gesture.
+ *
+ * Typical gestures are focus gestures. Examples of focus gestures are 'Wave' and
+ * 'Click'.
+ *
+ * See @ref create_method for a detailed description of this method.
+ */
+ inline XnStatus Create(Context& context, Query* pQuery = NULL, EnumerationErrors* pErrors = NULL);
+
+ /**
+ * @brief Activates the GestureGenerator node to start looking for the named gesture in the FOV.
+ * It does this by adding the gesture's name to the list of gestures that the GestureGenerator node
+ * actively scans for in the FOV. If an area is supplied, the gesture will only be recognized if
+ * it is detected in that area.
+ *
+ * @param [in] strGesture Name of the gesture to look for
+ * @param [in] pArea Area in which to look for the gesture (in real-world coordinates)
+ *
+ * <b>Remarks</b>
+ *
+ * This gesture must be one of the built-in gestures of the GestureGenerator node.
+ */
+ inline XnStatus AddGesture(const XnChar* strGesture, XnBoundingBox3D* pArea)
+ {
+ return xnAddGesture(GetHandle(), strGesture, pArea);
+ }
+
+ /**
+ * @brief Disables the GestureGenerator from looking for the named gesture in the FOV.
+ * It does this by removing the gesture's name from the list of gestures that the
+ * GestureGenerator node actively scans for in the FOV.
+ *
+ * @param [in] strGesture The name of the gesture to not look for anymore.
+ */
+ inline XnStatus RemoveGesture(const XnChar* strGesture)
+ {
+ return xnRemoveGesture(GetHandle(), strGesture);
+ }
+
+ /**
+ * @brief Get the names of all gestures that are currently active in this generator node.
+ *
+ * @param [out] astrGestures Preallocated memory, for the gesture names
+ * @param [in] nNameLength Memory size for each gesture name
+ * @param [in,out] nGestures Inputs the total size of the preallocated memory.
+ * Outputs the total number of gestures in the list.
+ */
+ inline XnStatus GetAllActiveGestures(XnChar** astrGestures, XnUInt32 nNameLength, XnUInt16& nGestures) const
+ {
+ return xnGetAllActiveGestures(GetHandle(), astrGestures, nNameLength, &nGestures);
+ }
+
+ /**
+ * @copybrief xnGetNumberOfAvailableGestures
+ * For full details and usage, see @ref xnGetNumberOfAvailableGestures
+ */
+ inline XnUInt16 GetNumberOfAvailableGestures() const
+ {
+ return xnGetNumberOfAvailableGestures(GetHandle());
+ }
+
+ /**
+ * @brief Gets the names of all active gestures in this generator node.
+ *
+ * @param [out] astrGestures Preallocated memory, for the gesture names
+ * @param [in] nNameLength Memory size for each gesture name
+ * @param [in,out] nGestures The size of the preallocated memory. Changed to number
+ * of gestures
+ */
+ inline XnStatus EnumerateAllGestures(XnChar** astrGestures, XnUInt32 nNameLength, XnUInt16& nGestures) const
+ {
+ return xnEnumerateAllGestures(GetHandle(), astrGestures, nNameLength, &nGestures);
+ }
+
+ /**
+ * @brief Returns whether a specific gesture is available in this generator node.
+ * @param [in] strGesture Name of the gesture to check
+ *
+ */
+ inline XnBool IsGestureAvailable(const XnChar* strGesture) const
+ {
+ return xnIsGestureAvailable(GetHandle(), strGesture);
+ }
+
+ /**
+ * @copybrief xnIsGestureProgressSupported
+ * For full details and usage, see @ref xnIsGestureProgressSupported
+ */
+ inline XnBool IsGestureProgressSupported(const XnChar* strGesture) const
+ {
+ return xnIsGestureProgressSupported(GetHandle(), strGesture);
+ }
+
+ /**
+ * Callback for the recognition of a gesture.
+ * Signals that the GestureGenerator node has recognized the named gesture in the scene.
+
+ * Example of a callback header to handle the event:
+ @code
+ void XN_CALLBACK_TYPE GestureRecognized (GestureGenerator &generator, const XnChar *strGesture,
+ const XnPoint3D *pIDPosition, const XnPoint3D *pEndPosition,
+ void *pCookie)
+ @endcode
+ *
+ * @param [in] generator Node that raised the event.
+ * @param [in] strGesture Name of the gesture that was recognized.
+ * @param [in] pIDPosition X-Y-Z location coordinates of the hand point position in which the gesture was identified.
+ * @param [in] pEndPosition Position of the hand at the end of the gesture. This is the hand that performed the gesture.
+ * @param [in] pCookie User-provided cookie that was given when registering to this event.
+
+ <b>Remarks</b>
+
+ This event returns the identification point (the position where the gesture was identified - perhaps in retrospect) and an end point (the position in which the hand currently is), although in most cases, both points will be the same. The end position of the gesture movement is where the hand is located at the time the GestureGenerator recognized a complete gesture and raised the event.
+ */
+ typedef void (XN_CALLBACK_TYPE* GestureRecognized)(GestureGenerator& generator, const XnChar* strGesture, const XnPoint3D* pIDPosition, const XnPoint3D* pEndPosition, void* pCookie);
+
+ /**
+ * Callback for indication that a certain gesture is in progress.
+ *
+ * Signals to the application that a gesture is expected to soon be recognized,
+ * that is, a gesture is in progress.
+ *
+ * Example of a callback header to handle the event: @code
+ void XN_CALLBACK_TYPE GestureProgress (GestureGenerator &generator, const XnChar *strGesture,
+ const XnPoint3D *pPosition, XnFloat fProgress,
+ void *pCookie)
+ @endcode
+ *
+ * @param [in] generator The node that raised the event.
+ * @param [in] strGesture The gesture that is on its way to being recognized.
+ * @param [in] pPosition The current position of the hand that is performing the gesture.
+ * @param [in] fProgress The percentage of the gesture that was already performed.
+ * @param [in] pCookie A user-provided cookie that was given when registering to this event.
+ *
+ * Gesture progress varies between different types of gestures. For the 'Click'
+ * gesture, for example, the click gesture's first step is the 'Push' movement (assuming
+ * the click gesture is defined as 'Push' and then 'Pull'). When the hand in the
+ * FOV completes the 'Push' the GestureGenerator node raises this event.
+ *
+ * After the hand in the FOV completes the pull motion, the node sends the 'Gesture
+ * Recognized' event, as described above.
+ */
+ typedef void (XN_CALLBACK_TYPE* GestureProgress)(GestureGenerator& generator, const XnChar* strGesture, const XnPoint3D* pPosition, XnFloat fProgress, void* pCookie);
+
+ /**
+ * @brief Registers event handlers for the 'Gesture Recognized' and 'Gesture Progress' events.
+ * Pass NULL for any event the application does not need to receive.
+ *
+ * @param [in] RecognizedCB [Optional] Callback function to be invoked when the 'Gesture Recognized' event is raised.
+ * @param [in] ProgressCB [Optional] Callback function to be invoked when the 'Gesture Progress' event is raised.
+ * @param [in] pCookie User's cookie, to be delivered to the callback.
+ * @param [out] hCallback Handle to the callback to be used for unregistering it.
+ *
+ * For full details and usage of the parameters, see @ref reg_to_events.
+ */
+ XnStatus RegisterGestureCallbacks(GestureRecognized RecognizedCB, GestureProgress ProgressCB, void* pCookie, XnCallbackHandle& hCallback)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ GestureCookie* pGestureCookie;
+ XN_VALIDATE_ALLOC(pGestureCookie, GestureCookie);
+ pGestureCookie->recognizedHandler = RecognizedCB;
+ pGestureCookie->progressHandler = ProgressCB;
+ pGestureCookie->pUserCookie = pCookie;
+
+ nRetVal = xnRegisterGestureCallbacks(GetHandle(), GestureRecognizedCallback, GestureProgressCallback, pGestureCookie, &pGestureCookie->hCallback);
+ if (nRetVal != XN_STATUS_OK)
+ {
+ xnOSFree(pGestureCookie);
+ return (nRetVal);
+ }
+
+ hCallback = pGestureCookie;
+
+ return (XN_STATUS_OK);
+ }
+
+ /**
+ * @brief Unregisters the event handlers for the 'Gesture Recognized' and 'Gesture Progress' events.
+ *
+ * @param [in] hCallback Handle received from registration.
+ *
+ * For full details and usage of the parameter, see @ref unreg_from_events .
+ */
+ inline void UnregisterGestureCallbacks(XnCallbackHandle hCallback)
+ {
+ GestureCookie* pGestureCookie = (GestureCookie*)hCallback;
+ xnUnregisterGestureCallbacks(GetHandle(), pGestureCookie->hCallback);
+ xnOSFree(pGestureCookie);
+ }
+
+ /**
+ * @brief Registers an event handler for the 'Gesture Change' event.
+ *
+ * @param [in] handler Callback function to be invoked when the event is raised.
+ * @param [in] pCookie User's cookie, to be delivered to the callback.
+ * @param [out] hCallback Handle to the callback to be used for unregistering it.
+ *
+ * For full details and usage of the parameters, see @ref reg_to_events.
+ */
+ inline XnStatus RegisterToGestureChange(StateChangedHandler handler, void* pCookie, XnCallbackHandle& hCallback)
+ {
+ return _RegisterToStateChange(xnRegisterToGestureChange, GetHandle(), handler, pCookie, hCallback);
+ }
+
+ /**
+ * @brief Unregisters an event handler for the 'Gesture Change' event.
+ *
+ * @param [in] hCallback Handle received from registration.
+ *
+ * For full details and usage of the parameter, see @ref unreg_from_events .
+ */
+ inline void UnregisterFromGestureChange(XnCallbackHandle hCallback)
+ {
+ _UnregisterFromStateChange(xnUnregisterFromGestureChange, GetHandle(), hCallback);
+ }
+
+ /**
+ * Callback for indication that an intermediate stage of a gesture has been completed.
+ *
+ * Example of a callback function to handle the event:
+ @code
+ void XN_CALLBACK_TYPE GestureIntermediateStageCompleted(GestureGenerator& generator, const XnChar *strGesture,
+ const XnPoint3D *pPosition, void *pCookie)
+ @endcode
+ *
+ * @param [in] generator The node that raised the event.
+ * @param [in] strGesture The gesture that is on its way to being recognized.
+ * @param [in] pPosition The current position of the hand that is performing the gesture.
+ * @param [in] pCookie A user-provided cookie that was given when registering to this event.
+ *
+ * <b>Remarks</b>
+ *
+ * For different types of gestures there is a different point at which the GestureGenerator
+ * node can recognize that a gesture is in progress. For the 'Click' gesture, for
+ * example, the first step is the 'Push' movement (assuming the click gesture is
+ * defined as 'Push' and then 'Pull'). When the hand in the FOV completes the 'Push'
+ * the GestureGenerator node raises this event.
+ *
+ * The difference between the 'Gesture Intermediate Stage Completed' event and the
+ * 'Gesture Progress' event is that the 'Gesture Intermediate Stage Completed' event
+ * does not refer to how much of the gesture is complete. It deals with breaking
+ * the gesture into smaller intermediate stages, and informing about them.
+ */
+ typedef void (XN_CALLBACK_TYPE* GestureIntermediateStageCompleted)(GestureGenerator& generator, const XnChar* strGesture, const XnPoint3D* pPosition, void* pCookie);
+
+ /**
+ * @brief Registers an event handler for the 'Gesture Intermediate Stage Completed' event.
+ *
+ * @param [in] handler Callback function to be invoked when the event is raised.
+ * @param [in] pCookie User's cookie, to be delivered to the callback.
+ * @param [out] hCallback Handle to the callback to be used for unregistering it.
+ *
+ * For full details and usage of the parameters, see @ref reg_to_events.
+ */
+ XnStatus RegisterToGestureIntermediateStageCompleted(GestureIntermediateStageCompleted handler, void* pCookie, XnCallbackHandle& hCallback)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ GestureIntermediateStageCompletedCookie* pGestureCookie;
+ XN_VALIDATE_ALLOC(pGestureCookie, GestureIntermediateStageCompletedCookie);
+ pGestureCookie->handler = handler;
+ pGestureCookie->pUserCookie = pCookie;
+
+ nRetVal = xnRegisterToGestureIntermediateStageCompleted(GetHandle(), GestureIntermediateStageCompletedCallback, pGestureCookie, &pGestureCookie->hCallback);
+ if (nRetVal != XN_STATUS_OK)
+ {
+ xnOSFree(pGestureCookie);
+ return (nRetVal);
+ }
+
+ hCallback = pGestureCookie;
+
+ return (XN_STATUS_OK);
+ }
+
+ /**
+ * @brief Unregisters an event handler for the 'Gesture Intermediate Stage Completed' event.
+ *
+ * @param [in] hCallback Handle received from registration.
+ *
+ * For full details and usage of the parameter, see @ref unreg_from_events .
+ */
+ inline void UnregisterFromGestureIntermediateStageCompleted(XnCallbackHandle hCallback)
+ {
+ GestureIntermediateStageCompletedCookie* pGestureCookie = (GestureIntermediateStageCompletedCookie*)hCallback;
+ xnUnregisterFromGestureIntermediateStageCompleted(GetHandle(), pGestureCookie->hCallback);
+ xnOSFree(pGestureCookie);
+ }
+
+ /**
+ * Callback for indication that the GestureGenerator node recognizes it is ready
+ * for the next intermediate stage. The next stage is specific to the gesture.
+ *
+ * Example of a callback function to handle the event: @code
+ void XN_CALLBACK_TYPE GestureReadyForNextIntermediateStage(GestureGenerator &generator, const XnChar *strGesture,
+ const XnPoint3D *pPosition, void *pCookie)
+ @endcode
+ *
+ * <b>Remarks</b>
+ *
+ * The number of intermediate stages that there can be is implementation-dependent.
+ *
+ * @param [in] generator The node that raised the event.
+ * @param [in] strGesture The gesture that is on its way to being recognized.
+ * @param [in] pPosition The current position of the hand that is performing the gesture.
+ * @param [in] pCookie A user-provided cookie that was given when registering to this event.
+ */
+ typedef void (XN_CALLBACK_TYPE* GestureReadyForNextIntermediateStage)(GestureGenerator& generator, const XnChar* strGesture, const XnPoint3D* pPosition, void* pCookie);
+
+ /**
+ * @brief Registers an event handler for the 'Gesture Ready For Next Intermediate Stage' event.
+ *
+ * @param [in] handler Callback function to be invoked when the event is raised.
+ * @param [in] pCookie User's cookie, to be delivered to the callback.
+ * @param [out] hCallback Handle to the callback to be used for unregistering it.
+ *
+ * For full details and usage of the parameters, see @ref reg_to_events.
+ */
+ XnStatus RegisterToGestureReadyForNextIntermediateStage(GestureReadyForNextIntermediateStage handler, void* pCookie, XnCallbackHandle& hCallback)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ GestureReadyForNextIntermediateStageCookie* pGestureCookie;
+ XN_VALIDATE_ALLOC(pGestureCookie, GestureReadyForNextIntermediateStageCookie);
+ pGestureCookie->handler = handler;
+ pGestureCookie->pUserCookie = pCookie;
+
+ nRetVal = xnRegisterToGestureReadyForNextIntermediateStage(GetHandle(), GestureReadyForNextIntermediateStageCallback, pGestureCookie, &pGestureCookie->hCallback);
+ if (nRetVal != XN_STATUS_OK)
+ {
+ xnOSFree(pGestureCookie);
+ return (nRetVal);
+ }
+
+ hCallback = pGestureCookie;
+
+ return (XN_STATUS_OK);
+ }
+
+ /**
+ * @brief Unregisters an event handler for the 'Gesture Ready For Next Intermediate Stage' event.
+ *
+ * @param [in] hCallback Handle received from registration.
+ *
+ * For full details and usage of the parameter, see @ref unreg_from_events .
+ */
+ inline void UnregisterFromGestureReadyForNextIntermediateStageCallbacks(XnCallbackHandle hCallback)
+ {
+ GestureReadyForNextIntermediateStageCookie* pGestureCookie = (GestureReadyForNextIntermediateStageCookie*)hCallback;
+ xnUnregisterFromGestureReadyForNextIntermediateStage(GetHandle(), pGestureCookie->hCallback);
+ xnOSFree(pGestureCookie);
+ }
+
+ /** @cond */
+ inline XnStatus XN_API_DEPRECATED("Use GetAllActiveGestures() instead") GetActiveGestures(XnChar*& astrGestures, XnUInt16& nGestures) const
+ {
+ return xnGetActiveGestures(GetHandle(), &astrGestures, &nGestures);
+ }
+ inline XnStatus XN_API_DEPRECATED("Use EnumerateAllGestures() instead") EnumerateGestures(XnChar*& astrGestures, XnUInt16& nGestures) const
+ {
+ return xnEnumerateGestures(GetHandle(), &astrGestures, &nGestures);
+ }
+ /** @endcond */
+
+ private:
+ typedef struct GestureCookie
+ {
+ GestureRecognized recognizedHandler;
+ GestureProgress progressHandler;
+ void* pUserCookie;
+ XnCallbackHandle hCallback;
+ } GestureCookie;
+
+ static void XN_CALLBACK_TYPE GestureRecognizedCallback(XnNodeHandle hNode, const XnChar* strGesture, const XnPoint3D* pIDPosition, const XnPoint3D* pEndPosition, void* pCookie)
+ {
+ GestureCookie* pGestureCookie = (GestureCookie*)pCookie;
+ GestureGenerator gen(hNode);
+ if (pGestureCookie->recognizedHandler != NULL)
+ {
+ pGestureCookie->recognizedHandler(gen, strGesture, pIDPosition, pEndPosition, pGestureCookie->pUserCookie);
+ }
+ }
+
+ static void XN_CALLBACK_TYPE GestureProgressCallback(XnNodeHandle hNode, const XnChar* strGesture, const XnPoint3D* pPosition, XnFloat fProgress, void* pCookie)
+ {
+ GestureCookie* pGestureCookie = (GestureCookie*)pCookie;
+ GestureGenerator gen(hNode);
+ if (pGestureCookie->progressHandler != NULL)
+ {
+ pGestureCookie->progressHandler(gen, strGesture, pPosition, fProgress, pGestureCookie->pUserCookie);
+ }
+ }
+
+ typedef struct GestureIntermediateStageCompletedCookie
+ {
+ GestureIntermediateStageCompleted handler;
+ void* pUserCookie;
+ XnCallbackHandle hCallback;
+ } GestureIntermediateStageCompletedCookie;
+
+ static void XN_CALLBACK_TYPE GestureIntermediateStageCompletedCallback(XnNodeHandle hNode, const XnChar* strGesture, const XnPoint3D* pPosition, void* pCookie)
+ {
+ GestureIntermediateStageCompletedCookie* pGestureCookie = (GestureIntermediateStageCompletedCookie*)pCookie;
+ GestureGenerator gen(hNode);
+ if (pGestureCookie->handler != NULL)
+ {
+ pGestureCookie->handler(gen, strGesture, pPosition, pGestureCookie->pUserCookie);
+ }
+ }
+
+ typedef struct GestureReadyForNextIntermediateStageCookie
+ {
+ GestureReadyForNextIntermediateStage handler;
+ void* pUserCookie;
+ XnCallbackHandle hCallback;
+ } GestureReadyForNextIntermediateStageCookie;
+
+ static void XN_CALLBACK_TYPE GestureReadyForNextIntermediateStageCallback(XnNodeHandle hNode, const XnChar* strGesture, const XnPoint3D* pPosition, void* pCookie)
+ {
+ GestureReadyForNextIntermediateStageCookie* pGestureCookie = (GestureReadyForNextIntermediateStageCookie*)pCookie;
+ GestureGenerator gen(hNode);
+ if (pGestureCookie->handler != NULL)
+ {
+ pGestureCookie->handler(gen, strGesture, pPosition, pGestureCookie->pUserCookie);
+ }
+ }
+ };
+
+ /**
+ * @ingroup cppref_prd_func
+ * <b>Purpose:</b> Performs an analysis of the scene, identifying different
+ * objects.
+ *
+ * <b>Data output:</b> A label map and the floor plane.
+ *
+ * <b>Remarks:</b>
+ *
+ * The scene analyzer node analyzes a scene, calculating the separation
+ * of the foreground from the background, identification of figures in the scene, and
+ * detection of the floor plane and its coordinates.
+ *
+ * The SceneAnalyzer node's main output is a label map, in which each pixel
+ * is labeled according to the object it belongs to. So, for example,
+ * each human person gets a separate label, and all pixels belonging to him
+ * are labeled with that label.
+ */
+ class SceneAnalyzer : public MapGenerator
+ {
+ public:
+ /**
+ * Ctor
+ *
+ * @param [in] hNode Node handle
+ */
+ inline SceneAnalyzer(XnNodeHandle hNode = NULL) : MapGenerator(hNode) {}
+ inline SceneAnalyzer(const NodeWrapper& other) : MapGenerator(other) {}
+
+ /**
+ * @brief Creates a SceneAnalyzer node from available @ref node_alternative "production node alternatives".
+ *
+ * <b>Remarks</b>
+ *
+ * See @ref create_method for a detailed description of this method.
+ */
+ inline XnStatus Create(Context& context, Query* pQuery = NULL, EnumerationErrors* pErrors = NULL);
+
+
+ /**
+ * @brief Gets the scene analyzer node's latest @ref glos_frame_object "frame object", saving
+ * it in the @ref xn::SceneMetaData object. This @ref glos_frame_object "frame object" is a
+ * snapshot of the generated label map data and its associated configuration information at a
+ * certain point in time. This saved @ref glos_frame_object "frame object" provides fast
+ * and easy access to the scene analyzer node's data and configuration information.
+ *
+ * @param [out] metaData Structure to be filled with the frame object.
+ *
+ * <b>Remarks:</b>
+ *
+ * This method is central in the use of the SceneAnalyzer node. Once the SceneAnalyzer
+ * node is generating data, after each @ref conc_updating_data "'Update Data'" call,
+ * the application calls this method to get the node's frame object, which contains
+ * the data and all its associated properties.
+ *
+ * The frame scene is a labeled depth map, in which each pixel contains a numeric
+ * label indicating whether it represents a user, or it is part of the background.
+ */
+ inline void GetMetaData(SceneMetaData& metaData) const
+ {
+ xnGetSceneMetaData(GetHandle(), metaData.GetUnderlying());
+ }
+
+ /**
+ * @copybrief xnGetLabelMap
+ * For full details and usage, see @ref xnGetLabelMap
+ */
+ inline const XnLabel* GetLabelMap() const
+ {
+ return xnGetLabelMap(GetHandle());
+ }
+
+ /**
+ * @brief Gets a description of the floor, if it was found.
+ *
+ * @param [out] Plane A description of the floor
+ */
+ inline XnStatus GetFloor(XnPlane3D& Plane) const
+ {
+ return xnGetFloor(GetHandle(), &Plane);
+ }
+ };
+
+ /**
+ * @ingroup cppref_prd_func
+ * Allows access to <b>Hand touching FOV edge</b> capability functions.
+ *
+ * <b>Usage:</b> Do not instantiate directly. Instead, use @ref HandsGenerator::GetHandTouchingFOVEdgeCap()
+ * to obtain an instance.
+ */
+ class HandTouchingFOVEdgeCapability : public Capability
+ {
+ public:
+ /**
+ * Ctor
+ *
+ * @param [in] hNode Node handle
+ */
+ inline HandTouchingFOVEdgeCapability(XnNodeHandle hNode) : Capability(hNode) {}
+ HandTouchingFOVEdgeCapability(const NodeWrapper& node) : Capability(node) {}
+
+ /**
+ * Callback for the hand getting close to the edge of the FOV
+ *
+ * @param [in] touchingfov the hand touching fov edge capability that raised this event.
+ * @param [in] user ID of the hand that disappeared.
+ * @param [in] pPosition Position of the hand.
+ * @param [in] fTime Timestamp, in seconds.
+ * @param [in] eDir Direction of the FOV touched
+ * @param [in] pCookie User-provided cookie that was given when registering to this event.
+ */
+ typedef void (XN_CALLBACK_TYPE* HandTouchingFOVEdge)(HandTouchingFOVEdgeCapability& touchingfov, XnUserID user, const XnPoint3D* pPosition, XnFloat fTime, XnDirection eDir, void* pCookie);
+
+ /**
+ * @brief Registers an event handler for the 'Hand Touching FOV Edge' event.
+ *
+ * @param [in] handler Callback function to be invoked when the event is raised.
+ * @param [in] pCookie User's cookie, to be delivered to the callback.
+ * @param [out] hCallback Handle to the callback to be used for unregistering it.
+ *
+ * For full details and usage of the parameters, see @ref reg_to_events.
+ */
+ inline XnStatus RegisterToHandTouchingFOVEdge(HandTouchingFOVEdge handler, void* pCookie, XnCallbackHandle& hCallback)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ HandTouchingFOVEdgeCookie* pHandCookie;
+ XN_VALIDATE_ALLOC(pHandCookie, HandTouchingFOVEdgeCookie);
+ pHandCookie->handler = handler;
+ pHandCookie->pUserCookie = pCookie;
+
+ nRetVal = xnRegisterToHandTouchingFOVEdge(GetHandle(), HandTouchingFOVEdgeCB, pHandCookie, &pHandCookie->hCallback);
+ if (nRetVal != XN_STATUS_OK)
+ {
+ xnOSFree(pHandCookie);
+ return (nRetVal);
+ }
+
+ hCallback = pHandCookie;
+
+ return (XN_STATUS_OK);
+ }
+
+ /**
+ * @brief Unregisters an event handler for the 'Hand Touching FOV Edge' event.
+ *
+ * @param [in] hCallback Handle received from registration.
+ *
+ * For full details and usage of the parameter, see @ref unreg_from_events .
+ */
+ inline void UnregisterFromHandTouchingFOVEdge(XnCallbackHandle hCallback)
+ {
+ HandTouchingFOVEdgeCookie* pHandCookie = (HandTouchingFOVEdgeCookie*)hCallback;
+ xnUnregisterFromHandTouchingFOVEdge(GetHandle(), pHandCookie->hCallback);
+ xnOSFree(pHandCookie);
+ }
+ private:
+ typedef struct HandTouchingFOVEdgeCookie
+ {
+ HandTouchingFOVEdge handler;
+ void* pUserCookie;
+ XnCallbackHandle hCallback;
+ } HandTouchingFOVEdgeCookie;
+
+ static void XN_CALLBACK_TYPE HandTouchingFOVEdgeCB(XnNodeHandle hNode, XnUserID user, const XnPoint3D* pPosition, XnFloat fTime, XnDirection eDir, void* pCookie)
+ {
+ HandTouchingFOVEdgeCookie* pHandCookie = (HandTouchingFOVEdgeCookie*)pCookie;
+ HandTouchingFOVEdgeCapability cap(hNode);
+ if (pHandCookie->handler != NULL)
+ {
+ pHandCookie->handler(cap, user, pPosition, fTime, eDir, pHandCookie->pUserCookie);
+ }
+ }
+
+ };
+
+ /**
+ * @ingroup cppref_prd_func
+ * The HandsGenerator node generates tracking data about a single hand or multiple hands
+ * with persistent IDs.
+ *
+ * The user interface (UI) in natural interaction applications is specifically implemented
+ * and performed through hand movements.
+ *
+ * OpenNI's user interface (UI) ability is specifically through hand movements. Thus
+ * it is the HandsGenerator class that provides the main UI ability.
+ *
+ * Using events, the HandsGenerator object notifies the application of various occurrences: a
+ * 'Hand Create' event is sent when an expected hand has been positively identified or when a
+ * new hand appears; a 'Hand Update' event is sent when a tracked hand appears again in a new
+ * frame; a 'Hand Destroy' event is sent when a tracked hand disappears.
+ *
+ * <b>NOTE: </b> The HandsGenerator does not provide the mechanism for initially locating
+ * the hand. Initial location of the hand can be performed by the Gestures class (see
+ * further below). This is a typical scenario but not the only way to locate the hand.
+ *
+ * The following figure illustrates a typical scenario for using the HandsGenerator
+ * class. After hand recognition the HandsGenerator class continues tracking the hand
+ * and sending HandUpdate events until the application sends calls HandsGenerator's
+ * StopTracking method.
+ *
+ * <b>1. Creating a HandsGenerator</b>
+ *
+ * As for many other types of generator nodes, HandsGenerator provides a Create method
+ * to create a hands generator node.
+ *
+ * Assuming you have hands generator module (plug-in) installed on your computer, you
+ * can create a hands generator node. Then you can start tracking for an expected hand.
+ *
+ * @note Creating a HandsGenerator node has nothing to do with the 'Hand Create'
+ * event that OpenNI sends to the app on starting to successfully track the hand in
+ * the FOV.
+ *
+ * <b>2. Starting Tracking</b>
+ *
+ * When starting to track a hand, the application already expects that a person's hand
+ * is already present in the field of view and is at a certain coordinate (x,y) position.
+ *
+ * The source for this information, i.e., the presence of a hand object and its position,
+ * can be obtained, for example, from a gesture generator node.
+ * The application passes this location to the @ref StartTracking()
+ * method of the HandsGenerator object, which starts tracking for
+ * the expected hand. When - and if - the StartTracking() method finds the hand at the
+ * expected position it sends a 'Hand Create' event to the application.
+ *
+ * <b>3. Tracking</b>
+ *
+ * While tracking a hand, 'Hand Update' events are sent to the application notifying that the hand
+ * has moved to such and such a position. A 'Hand Update' event is sent each time a new
+ * frame processed by the input sensors shows the hand is still present. A 'Hand Update'
+ * event is sent even if the hand is still in the same position as it was in the previous
+ * frame.
+ *
+ * If the tracked hand disappears (e.g., when the person puts his hand behind his back)
+ * a 'Hand Destroy' event is sent to the application to notify that the hand has disappeared.
+ *
+ * The 'Hand Create' event is also sent if an additional hand is found internally.
+ *
+ * The tracking mechanism uses an algorithm that uses the depth to obtain points and
+ * track. This algorithm can be somewhat susceptible to jitter of the hand, so HandsGenerator
+ * provides a smoothing capability. Call the SetSmoothing() method to apply a smoothing
+ * factor of none (0) to maximum (1). The default is 0. Recommended is 0.1 when using
+ * the PrimeSense algorithm for hand generation.
+ *
+ * <b>4. Stopping Tracking</b>
+ *
+ * When the hand being tracked is no longer identified, the HandsGenerator object sends
+ * the 'Hand Destroy' event.
+ *
+ * The application can also intentionally stop tracking a specific hand, e.g., when
+ * the hand is no longer of interest. The application does this by calling the @ref StopTracking()
+ * method. When the node stops tracking the hand it sends a 'Hand Destroy' event to the application.
+ *
+ * The application can also stop the tracking of all hands at once by calling the @ref StopTrackingAll()
+ * method. In response, the node stops tracking all hands and for each hand it sends a
+ * 'Hand Destroy' event to the application.
+ * Even when there are no tracked hands, the HandsGenerator object remains functional
+ * for the next tracking request.
+ *
+ * <h2>Events:</h2>
+ *
+ * @image html ClassHandsGenerator_EventSeq-sm.png "Event Sequence for HandsGenerator node"
+ */
+ class HandsGenerator : public Generator
+ {
+ public:
+ /**
+ * Ctor
+ *
+ * @param [in] hNode Node handle
+ */
+ inline HandsGenerator(XnNodeHandle hNode = NULL) : Generator(hNode) {}
+ inline HandsGenerator(const NodeWrapper& other) : Generator(other) {}
+
+ /**
+ * @brief Creates a HandsGenerator node from available @ref node_alternative "production node alternatives".
+ *
+ * <b>Remarks:</b>
+ *
+ * See @ref create_method for a detailed description of this method.
+ */
+ inline XnStatus Create(Context& context, Query* pQuery = NULL, EnumerationErrors* pErrors = NULL);
+
+ /**
+ * Callback for the creation of a new hand.
+ *
+ * Signals that the hands generator has recognized and started tracking a new hand in response
+ * to the application calling the StartTracking() method. This event returns the
+ * ID of the new hand, the time of its recognition, and its position on recognition
+ * in the current frame.
+ *
+ * @param [in] generator Generator that raised this event.
+ * @param [in] user ID of the new hand.
+ * @param [in] pPosition Position at which the hand was created.
+ * @param [in] fTime Timestamp, in seconds.
+ * @param [in] pCookie User-provided cookie that was given when registering to
+ * this event.
+ */
+ typedef void (XN_CALLBACK_TYPE* HandCreate)(HandsGenerator& generator, XnUserID user, const XnPoint3D* pPosition, XnFloat fTime, void* pCookie);
+
+ /**
+ * Signals that an already-existing hand has moved to a new position.
+ *
+ * Signals that a currently tracked hand was recognized at a specific position in
+ * the new frame. OpenNI continues to send this event at each further frame that
+ * the hand is still present. This event returns the ID of the hand, which is the
+ * same ID returned by the HandCreate event, the hand's new position, and the time
+ * of the update.
+ *
+ * @param [in] generator the generator that raised this event.
+ * @param [in] user The id of the hand that moved.
+ * @param [in] pPosition The new position of the relevant hand.
+ * @param [in] fTime Timestamp, in seconds.
+ * @param [in] pCookie A user-provided cookie that was given when registering to
+ * this event.
+ */
+ typedef void (XN_CALLBACK_TYPE* HandUpdate)(HandsGenerator& generator, XnUserID user, const XnPoint3D* pPosition, XnFloat fTime, void* pCookie);
+
+ /**
+ * Callback for the disappearance of a hand.
+ *
+ * Signals that an existing hand has disappeared from the frame for any reason.
+ * This event returns the user ID &ndash; still the same user ID as before &ndash;
+ * and the time that it disappeared.
+ *
+ * @param [in] generator the generator that raised this event.
+ * @param [in] user The id of the hand that disappeared.
+ * @param [in] fTime Timestamp, in seconds.
+ * @param [in] pCookie A user-provided cookie that was given when registering to
+ * this event.
+ */
+ typedef void (XN_CALLBACK_TYPE* HandDestroy)(HandsGenerator& generator, XnUserID user, XnFloat fTime, void* pCookie);
+
+ /**
+ * @brief Registers event handlers for the 'Hand Create', 'Hand Update' and 'Hand Destroy' events.
+ * Pass NULL for any event you don't want your application to receive.
+ *
+ * @param [in] CreateCB [Optional] Callback function to be invoked when the 'Hand Create' event is raised.
+ * @param [in] UpdateCB [Optional] Callback function to be invoked when the 'Hand Update' event is raised.
+ * @param [in] DestroyCB [Optional] Callback function to be invoked when the 'Hand Destroy' event is raised.
+ * @param [in] pCookie User's cookie, to be delivered to the callback.
+ * @param [out] hCallback Handle to the callback to be used for unregistering it.
+ *
+ * For full details and usage of the parameters, see @ref reg_to_events.
+ */
+ inline XnStatus RegisterHandCallbacks(HandCreate CreateCB, HandUpdate UpdateCB, HandDestroy DestroyCB, void* pCookie, XnCallbackHandle& hCallback)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ HandCookie* pHandCookie;
+ XN_VALIDATE_ALLOC(pHandCookie, HandCookie);
+ pHandCookie->createHandler = CreateCB;
+ pHandCookie->updateHandler = UpdateCB;
+ pHandCookie->destroyHandler = DestroyCB;
+ pHandCookie->pUserCookie = pCookie;
+
+ nRetVal = xnRegisterHandCallbacks(GetHandle(), HandCreateCB, HandUpdateCB, HandDestroyCB, pHandCookie, &pHandCookie->hCallback);
+ if (nRetVal != XN_STATUS_OK)
+ {
+ xnOSFree(pHandCookie);
+ return (nRetVal);
+ }
+
+ hCallback = pHandCookie;
+
+ return (XN_STATUS_OK);
+ }
+
+ /**
+ * @brief Unregisters event handlers for the 'Hand Create', 'Hand Update' and 'Hand Destroy' events.
+ *
+ * @param [in] hCallback Handle received from registration.
+ *
+ * For full details and usage of the parameter, see @ref unreg_from_events .
+ */
+ inline void UnregisterHandCallbacks(XnCallbackHandle hCallback)
+ {
+ HandCookie* pHandCookie = (HandCookie*)hCallback;
+ xnUnregisterHandCallbacks(GetHandle(), pHandCookie->hCallback);
+ xnOSFree(pHandCookie);
+ }
+
+ /**
+ * @brief Stops tracking an existing hand that you are no longer interested in.
+ *
+ * @param [in] user Hand to stop tracking. This parameter is the ID of the hand.
+ *
+ * <b>Remarks</b>
+ *
+ * Typically, the application will stop tracking an existing hand that it is no
+ * longer interested in.
+ *
+ * Calling this method causes the 'Hand Destroy' event to be raised when OpenNI destroys
+ * the hand.
+ */
+ inline XnStatus StopTracking(XnUserID user)
+ {
+ return xnStopTracking(GetHandle(), user);
+ }
+
+ /**
+ * @brief Stops tracking all existing hands.
+ *
+ * <b>Remarks</b>
+ *
+ * Calling this method causes the 'Hand Destroy' event to be raised when OpenNI destroys
+ * the hand.
+ */
+ inline XnStatus StopTrackingAll()
+ {
+ return xnStopTrackingAll(GetHandle());
+ }
+
+ /**
+ * @brief Starts tracking at the specific position where the application expects a hand.
+ *
+ * @param [in] ptPosition The position at which there is a new hand
+ *
+ * <b>Remarks</b>
+ *
+ * Use the <code>ptPosition</code> parameter to tell the method what is the expected
+ * location (in X-Y-Z coordinates) of the hand.
+ *
+ * This expected location can be obtained from a 'Gesture Recognized' event, but
+ * it is not the only way of getting the hand's expected location.
+ *
+ * Calling this method causes the HandCreate event to be raised when OpenNI recognizes
+ * the hand.
+ */
+ inline XnStatus StartTracking(const XnPoint3D& ptPosition)
+ {
+ return xnStartTracking(GetHandle(), &ptPosition);
+ }
+
+ /**
+ * @brief Changes the smoothing factor.
+ *
+ * @param [in] fSmoothingFactor Smoothing factor, in the range 0..1. 0 Means no
+ * smoothing, 1 means infinite smoothing.
+ * Inside the range is generator dependent.
+ * <br>
+ * Recommended: 0.1
+ *
+ * <b>Remarks</b>
+ *
+ * The hand is identified from its physical depth. Since the human hand is not absolutely
+ * steady, the hand point generated may be too jittery to be used for controlling
+ * the user interface, e.g., pressing buttons. This method provides an algorithm
+ * to smooth the jitter. You provide the desired smoothing factor as a parameter.
+ */
+ inline XnStatus SetSmoothing(XnFloat fSmoothingFactor)
+ {
+ return xnSetTrackingSmoothing(GetHandle(), fSmoothingFactor);
+ }
+
+ /**
+ * Gets an @ref HandTouchingFOVEdgeCapability object for accessing hand touching
+ * FOV edge callbacks functionality.
+ * It is the application responsibility to check first if @ref XN_CAPABILITY_HAND_TOUCHING_FOV_EDGE
+ * is supported
+ * by calling @ref IsCapabilitySupported().
+ */
+ inline const HandTouchingFOVEdgeCapability GetHandTouchingFOVEdgeCap() const
+ {
+ return HandTouchingFOVEdgeCapability(GetHandle());
+ }
+
+ /**
+ * Gets an @ref HandTouchingFOVEdgeCapability object for accessing hand touching
+ * FOV edge callbacks functionality.
+ * It is the application responsibility to check first if @ref XN_CAPABILITY_HAND_TOUCHING_FOV_EDGE
+ * is supported
+ * by calling @ref IsCapabilitySupported().
+ */
+ inline HandTouchingFOVEdgeCapability GetHandTouchingFOVEdgeCap()
+ {
+ return HandTouchingFOVEdgeCapability(GetHandle());
+ }
+
+ private:
+ typedef struct HandCookie
+ {
+ HandCreate createHandler;
+ HandUpdate updateHandler;
+ HandDestroy destroyHandler;
+ void* pUserCookie;
+ XnCallbackHandle hCallback;
+ } HandCookie;
+
+ static void XN_CALLBACK_TYPE HandCreateCB(XnNodeHandle hNode, XnUserID user, const XnPoint3D* pPosition, XnFloat fTime, void* pCookie)
+ {
+ HandCookie* pHandCookie = (HandCookie*)pCookie;
+ HandsGenerator gen(hNode);
+ if (pHandCookie->createHandler != NULL)
+ {
+ pHandCookie->createHandler(gen, user, pPosition, fTime, pHandCookie->pUserCookie);
+ }
+ }
+ static void XN_CALLBACK_TYPE HandUpdateCB(XnNodeHandle hNode, XnUserID user, const XnPoint3D* pPosition, XnFloat fTime, void* pCookie)
+ {
+ HandCookie* pHandCookie = (HandCookie*)pCookie;
+ HandsGenerator gen(hNode);
+ if (pHandCookie->updateHandler != NULL)
+ {
+ pHandCookie->updateHandler(gen, user, pPosition, fTime, pHandCookie->pUserCookie);
+ }
+ }
+ static void XN_CALLBACK_TYPE HandDestroyCB(XnNodeHandle hNode, XnUserID user, XnFloat fTime, void* pCookie)
+ {
+ HandCookie* pHandCookie = (HandCookie*)pCookie;
+ HandsGenerator gen(hNode);
+ if (pHandCookie->destroyHandler != NULL)
+ {
+ pHandCookie->destroyHandler(gen, user, fTime, pHandCookie->pUserCookie);
+ }
+ }
+ };
+
+ /**
+ * @ingroup cppref_prd_func
+ * <b>Purpose:</b> Provides the 'Skeleton' functionality for a @ref xn::UserGenerator
+ * node. This capability lets the node generate a skeleton representation for each human
+ * user generated by the node.
+ *
+ * @note See @ref meanings_of_user "Meanings of 'User'".
+ *
+ * <b>Usage:</b> Do not instantiate directly. Instead, use @ref UserGenerator::GetSkeletonCap()
+ * to obtain an instance.
+ *
+ * <b>Data output:</b> Skeleton.
+ *
+ * The OpenNI definition of <i>joints</i> refers to a predefined set of points on the
+ * human body, as defined by the @ref xn::XnSkeletonJoint enum type. Examples of these
+ * joints are @ref XN_SKEL_HEAD, @ref XN_SKEL_TORSO, @ref XN_SKEL_LEFT_ELBOW,
+ * @ref XN_SKEL_LEFT_WRIST and @ref XN_SKEL_LEFT_HAND. Note that some of these <i>joints</i>
+ * are actual joints, in the conventional sense as termed by the English language, for
+ * example, @ref XN_SKEL_LEFT_ELBOW and @ref XN_SKEL_LEFT_WRIST; and other joints are in
+ * fact <i>limbs</i>, for example, @ref XN_SKEL_HEAD and @ref XN_SKEL_LEFT_HAND.
+ * However, OpenNI defines all these as <i>joints</i>, each joint with a single position
+ * coordinate. Each detected joint is defined by its <i>position</i>, which is held
+ * as a struct of type @ref xn::XnSkeletonJointPosition, comprising a 3D position coordinate
+ * and confidence. The 3D position coordinate defines a point somewhere in the center
+ * of the 'joint', for example, the position of the torso will be at the center of the
+ * torso, i.e., somewhere in the stomach area.
+ *
+ * To graphically draw a complete skeleton, therefore, each joint must be connected
+ * by a line to the adjacent point according to the form of the human body.
+ *
+ * An application typically uses this skeleton representation to track human motion,
+ * or to graphically display all or part of the user as an avatar on screen, and optionally
+ * graphically enhance it to make it look more like a full humanoid figure.
+ *
+ * @section skeleton_calib Calibration
+ *
+ * Tracking of a human user always starts with a process named 'Calibration'. In this
+ * process the algorithm performs some implementation-specific logic to enable it
+ * to track that user. there is no standard for what calibration is exactly and
+ * each implementation may use whatever it needs to produce and calibrate a skeleton.
+ * However, a typical way of calibrating the skeleton would be to measure distances
+ * between key joints for a particular user and record the data as the calibration data
+ * for that particular user.
+ *
+ * Some implementations of the user generator node require a human user to pose a specific
+ * posture for the calibration process to succeed. The application can check if current implementation
+ * requires such a pose by calling @ref NeedPoseForCalibration() method. If the answer is TRUE,
+ * the application should call @ref GetCalibrationPose() to find out the name of the pose a human user should
+ * take in order to calibrate the algorithm. The application can use the @ref xn::PoseDetectionCapability
+ * to find out if a human user is assuming a specific position, and once he does, calibration can start.
+ *
+ * The application starts the calibration process by calling @ref RequestCalibration(). There
+ * are several events raised during the calibration process, but the most important one is
+ * 'Calibration Complete'. Once calibration is done, the application may call @ref StartTracking()
+ * to make the algorithm start tracking the skeleton of that human user.
+ */
+ class SkeletonCapability : public Capability
+ {
+ public:
+ /**
+ * Ctor
+ *
+ * @param [in] hNode Node handle
+ */
+ inline SkeletonCapability(XnNodeHandle hNode) : Capability(hNode) {}
+ SkeletonCapability(const NodeWrapper& node) : Capability(node) {}
+
+ /**
+ * @brief Returns whether a specific skeleton joint is supported by the SkeletonCapability object.
+ *
+ * @param [in] eJoint Joint to check.
+ */
+ inline XnBool IsJointAvailable(XnSkeletonJoint eJoint) const
+ {
+ return xnIsJointAvailable(GetHandle(), eJoint);
+ }
+
+ /**
+ * @brief Returns whether a specific skeleton profile is supported by the SkeletonCapability object.
+ *
+ * @param [in] eProfile Profile to check.
+ */
+ inline XnBool IsProfileAvailable(XnSkeletonProfile eProfile) const
+ {
+ return xnIsProfileAvailable(GetHandle(), eProfile);
+ }
+
+ /**
+ * @brief Sets the skeleton profile. The skeleton profile specifies which joints are to
+ * be active, and which to be inactive. The @ref UserGenerator node generates output data
+ * for the active joints only. This profile applies to all skeletons that the @ref UserGenerator node generates.
+ *
+ * @param [in] eProfile Specifies the profile to set.
+ *
+ * <b>Remarks</b>
+ *
+ * The profile (@ref xn::XnSkeletonProfile) enables the application to choose between
+ * generating all joints, just the upper or lower torso, or just the head and hands
+ * only.
+ *
+ * Since this method provides the flexibility to request only the data that the
+ * application requires, this can help to significantly improve response time: setting
+ * a smaller skeleton profile reduces the processing load on the computer, which
+ * can cause a significant increase in avatar responsiveness.
+ *
+ * Use the @ref SetJointActive() method for selecting the profile down to a finer
+ * resolution than possible with this method, e.g., to be able to select a specific
+ * hand or foot.
+ *
+ * OpenNI does not standardize the initial profile set. If no profile is set, each
+ * implementation may have its own default profile. For example, PrimeSense implementation's
+ * default profile is NONE. This means if no profile is set, no joint will be available.
+ *
+ * Setting a profile changes all the joint configuration to that profile. This means
+ * you can set a profile, then refine specific joints (adding or removing). You
+ * can't do it the other way around.
+ */
+ inline XnStatus SetSkeletonProfile(XnSkeletonProfile eProfile)
+ {
+ return xnSetSkeletonProfile(GetHandle(), eProfile);
+ }
+
+ /**
+ * @brief Changes the state of a specific skeleton joint to be active or inactive.
+ * The @ref xn::UserGenerator node generates output data for the active joints only.
+ * This state setting applies to all skeletons that the @ref xn::UserGenerator node generates.
+ *
+ * @param [in] eJoint Specifies the joint.
+ * @param [in] bState New activation state (true/false).
+ *
+ * <b>Remarks</b>
+ *
+ * This method lets the application set the skeleton profile down to a finer resolution
+ * than is possible with the @ref SetSkeletonProfile() method.
+ *
+ * The joint selector parameter (@ref xn::XnSkeletonJoint) lets the application
+ * choose specific parts of a skeleton, e.g., a specific hand or foot.
+ *
+ * Since this method provides the flexibility to request only the data that the
+ * application requires, this can help to significantly improve response time. Setting
+ * a smaller skeleton profile can reduce the processing load on the computer, which
+ * can cause a significant increase in avatar responsiveness (implementation-dependent).
+ * Some implementations may produce all the data they can, and only filter it at
+ * the end according to the configuration.
+ */
+ inline XnStatus SetJointActive(XnSkeletonJoint eJoint, XnBool bState)
+ {
+ return xnSetJointActive(GetHandle(), eJoint, bState);
+ }
+
+ /**
+ * @brief Checks if a specific joint is tracked or not.
+ *
+ * @param [in] eJoint Specifies the joint.
+ */
+ inline XnBool IsJointActive(XnSkeletonJoint eJoint) const
+ {
+ return xnIsJointActive(GetHandle(), eJoint);
+ }
+
+ /**
+ * @brief Registers an event handler for the 'Joint Configuration Change' event.
+ *
+ * @param [in] handler Callback function to be invoked when the event is raised.
+ * @param [in] pCookie User's cookie, to be delivered to the callback.
+ * @param [out] hCallback Handle to the callback to be used for unregistering it.
+ *
+ * For full details and usage of the parameters, see @ref reg_to_events.
+ */
+ inline XnStatus RegisterToJointConfigurationChange(StateChangedHandler handler, void* pCookie, XnCallbackHandle& hCallback)
+ {
+ return _RegisterToStateChange(xnRegisterToJointConfigurationChange, GetHandle(), handler, pCookie, hCallback);
+ }
+
+ /**
+ * @brief Unregisters an event handler for the 'Joint Configuration Change' event.
+ *
+ * @param [in] hCallback Handle received from registration.
+ *
+ * For full details and usage of the parameter, see @ref unreg_from_events .
+ */
+ inline void UnregisterFromJointConfigurationChange(XnCallbackHandle hCallback)
+ {
+ _UnregisterFromStateChange(xnUnregisterFromJointConfigurationChange, GetHandle(), hCallback);
+ }
+
+ /**
+ * @copybrief xnEnumerateActiveJoints
+ * For full details and usage, see @ref xnEnumerateActiveJoints
+ */
+ inline XnStatus EnumerateActiveJoints(XnSkeletonJoint* pJoints, XnUInt16& nJoints) const
+ {
+ return xnEnumerateActiveJoints(GetHandle(), pJoints, &nJoints);
+ }
+
+ /**
+ * @brief Gets all available information about a specific joint in the skeleton.
+ *
+ * @param [in] user ID of the user.
+ * @param [in] eJoint Joint specifier.
+ * @param [out] Joint Transformation structure for the joint. Includes position
+ * and orientation.
+ */
+ inline XnStatus GetSkeletonJoint(XnUserID user, XnSkeletonJoint eJoint, XnSkeletonJointTransformation& Joint) const
+ {
+ return xnGetSkeletonJoint(GetHandle(), user, eJoint, &Joint);
+ }
+
+ /**
+ * @brief Gets the position of one of the skeleton joints in the most recently generated user data.
+ *
+ * @param [in] user ID of the user.
+ * @param [in] eJoint Joint specifier.
+ * @param [out] Joint Latest position of the joint.
+ *
+ * <b>Remarks</b>
+ *
+ * The joint position is returned as a @ref XnSkeletonJointPosition structure, comprising
+ * a real-world coordinate together with a confidence rating.
+ *
+ * Confidence can be in the range of 0..1.
+ *
+ * 0 means 'I'm guessing here'.<br>
+ * 1 means 'This is where it is'. <br>
+ *
+ * The API is ready for when an implementation decides it is 'fairly certain'. In
+ * a typical implementation, 0.5 is used when there is an educated guess, or have
+ * run some heuristics to determine the position.
+ */
+ inline XnStatus GetSkeletonJointPosition(XnUserID user, XnSkeletonJoint eJoint, XnSkeletonJointPosition& Joint) const
+ {
+ return xnGetSkeletonJointPosition(GetHandle(), user, eJoint, &Joint);
+ }
+
+ /**
+ * @brief Gets the orientation of a specific skeleton joint.
+ *
+ * @param [in] user ID of the user.
+ * @param [in] eJoint Joint specifier.
+ * @param [out] Joint Joint's orientation.
+ */
+ inline XnStatus GetSkeletonJointOrientation(XnUserID user, XnSkeletonJoint eJoint, XnSkeletonJointOrientation& Joint) const
+ {
+ return xnGetSkeletonJointOrientation(GetHandle(), user, eJoint, &Joint);
+ }
+
+ /**
+ * @brief Returns whether a user is currently being tracked.
+ *
+ * @param [in] user ID of the user.
+ *
+ * <b>Remarks</b>
+ *
+ * This is a utility method. It is an alternative approach to saving the states
+ * from the events that notify stages in calibration and tracking.
+ */
+ inline XnBool IsTracking(XnUserID user) const
+ {
+ return xnIsSkeletonTracking(GetHandle(), user);
+ }
+
+ /**
+ * @brief Returns whether a user has been calibrated. see @ref skeleton_calib.
+ *
+ * @param [in] user ID of the user.
+ *
+ * <b>Remarks</b>
+ *
+ * This is a utility method. It is an alternative approach to saving the states
+ * from the events that notify stages in calibration.
+ */
+ inline XnBool IsCalibrated(XnUserID user) const
+ {
+ return xnIsSkeletonCalibrated(GetHandle(), user);
+ }
+
+ /**
+ * @brief Returns whether a user is being calibrated right now. see @ref skeleton_calib.
+ *
+ * @param [in] user ID of the user.
+ *
+ * <b>Remarks</b>
+ *
+ * This is a utility method. It is an alternative approach to saving the states
+ * from the events that notify stages in calibration.
+ */
+ inline XnBool IsCalibrating(XnUserID user) const
+ {
+ return xnIsSkeletonCalibrating(GetHandle(), user);
+ }
+
+ /**
+ * @brief Starts the calibration process to calibrate a user.
+ *
+ * @param [in] user ID of the user.
+ * @param [in] bForce Disregard previous calibration to force a further calibration.<br>
+ * Values:<br>
+ * True: Disregards any previous calibration and forces a new calibration.<br>
+ * False: Starts the calibration process only if no calibration data is available
+ * for the skeleton.<br>
+ * This means that if the user was previously calibrated (which actually means measuring
+ * the length of its limbs, and estimating its torso, to be used in its skeletal
+ * representation), and another calibration was requested, to either make do with
+ * what we have (false), or forget the previous measurements and perform calibration
+ * again.
+ *
+ * <b>Remarks</b>
+ *
+ * This method is typically called from inside an event handler for the 'Pose Detected'
+ * event, signaling that a pose was detected in the FOV. Once a valid pose has been
+ * detected the application will want to start calibrating the user.
+ *
+ * It can also be called outside of that, in implementations that don't require
+ * a pose.
+ */
+ inline XnStatus RequestCalibration(XnUserID user, XnBool bForce)
+ {
+ return xnRequestSkeletonCalibration(GetHandle(), user, bForce);
+ }
+
+ /**
+ * @brief Aborts an existing calibration process currently being executed for a specified user.
+ *
+ * @param [in] user ID of the user.
+ *
+ * <b>Remarks</b>
+ *
+ * Raises the 'Calibration Complete' event.
+ */
+ inline XnStatus AbortCalibration(XnUserID user)
+ {
+ return xnAbortSkeletonCalibration(GetHandle(), user);
+ }
+
+ /**
+ * @brief Saves the skeleton's current calibration data to a file.
+ *
+ * @param [in] user ID of the user.
+ * @param [in] strFileName Name of the file for saving the calibration data.
+ *
+ * <b>Remarks</b>
+ *
+ * The application is the one that should match the user, however it sees fit. For
+ * example, if a calibration was saved as C:\\john_smith.bin, and then later another
+ * application recognizes John Smith (let's say, through face recognition), the
+ * calibration data can be loaded, instead of performing the entire calibration
+ * process.
+ *
+ * This is a very useful tool for developers. They can save their own calibration,
+ * and test their application without calibrating each time (going into pose, spend
+ * time on calibration).
+ */
+ inline XnStatus SaveCalibrationDataToFile(XnUserID user, const XnChar* strFileName)
+ {
+ return xnSaveSkeletonCalibrationDataToFile(GetHandle(), user, strFileName);
+ }
+
+ /**
+ * @brief Loads skeleton calibration data from a file to a skeleton.
+ *
+ * @param [in] user ID of the user.
+ * @param [in] strFileName File to load the calibration data from.
+ */
+ inline XnStatus LoadCalibrationDataFromFile(XnUserID user, const XnChar* strFileName)
+ {
+ return xnLoadSkeletonCalibrationDataFromFile(GetHandle(), user, strFileName);
+ }
+
+ /**
+ * @brief Saves the calibration data of a specified user. The calibration data includes the lengths of the human user's limbs.
+ *
+ * @param [in] user ID of the user.
+ * @param [in] nSlot Slot to use for saving the calibration data
+ *
+ * <b>Remarks</b>
+ *
+ * The slots mechanism allows saving the calibration to memory instead of to files.
+ * When used, a calibration is saved to a slot, and may be reloaded from it.
+ */
+ inline XnStatus SaveCalibrationData(XnUserID user, XnUInt32 nSlot)
+ {
+ return xnSaveSkeletonCalibrationData(GetHandle(), user, nSlot);
+ }
+
+ /**
+ * @brief Loads calibration data of a specified user. The calibration data includes the lengths of the human user's limbs.
+ *
+ * @param [in] user ID of the user.
+ * @param [in] nSlot Slot to use for saving the calibration data
+ */
+ inline XnStatus LoadCalibrationData(XnUserID user, XnUInt32 nSlot)
+ {
+ return xnLoadSkeletonCalibrationData(GetHandle(), user, nSlot);
+ }
+
+ /**
+ * @brief Clears a specified slot of any saved calibration data.
+ *
+ * @param [in] nSlot Slot specifier.
+ */
+ inline XnStatus ClearCalibrationData(XnUInt32 nSlot)
+ {
+ return xnClearSkeletonCalibrationData(GetHandle(), nSlot);
+ }
+
+ /**
+ * @brief Returns whether a specific slot already holds calibration data.
+ *
+ * @param [in] nSlot Slot specifier.
+ */
+ inline XnBool IsCalibrationData(XnUInt32 nSlot) const
+ {
+ return xnIsSkeletonCalibrationData(GetHandle(), nSlot);
+ }
+
+ /**
+ * @brief Starts tracking a skeleton.
+ *
+ * @param [in] user ID of the user.
+ *
+ * <b>Remarks</b>
+ *
+ * This method is used for tracking the motion of the skeleton, representing a human
+ * user body, within a real-life (3D) scene for analysis, interpretation, and use
+ * by the application.
+ *
+ * While the skeleton is being tracked, the application can call the @ref GetSkeletonJointPosition()
+ * method to get data about one of the joint positions.
+ */
+ inline XnStatus StartTracking(XnUserID user)
+ {
+ return xnStartSkeletonTracking(GetHandle(), user);
+ }
+
+ /**
+ * @brief Stops tracking a skeleton.
+ * @param [in] user ID of the user.
+ */
+ inline XnStatus StopTracking(XnUserID user)
+ {
+ return xnStopSkeletonTracking(GetHandle(), user);
+ }
+
+ /**
+ * @brief Discards a skeleton's calibration.
+ * @param [in] user ID of the user.
+ *
+ * <b>Remarks</b>
+ *
+ * Utility method for resetting a user to its initial state. For use in development.
+ */
+ inline XnStatus Reset(XnUserID user)
+ {
+ return xnResetSkeleton(GetHandle(), user);
+ }
+
+ /**
+ * @brief Returns whether a specific pose is required for
+ * calibration. This setting is applicable to all users.
+ *
+ * <b>Remarks</b>
+ *
+ * This is a setting made by the developer of the SkeletonCapability plug-in.
+ */
+ inline XnBool NeedPoseForCalibration() const
+ {
+ return xnNeedPoseForSkeletonCalibration(GetHandle());
+ }
+
+ /**
+ * @brief Gets the name of the pose that is required for calibration. The
+ * pose and its name reside in the plug-in module that provides the
+ * SkeletonCapability. The pose's name and details are defined by the
+ * developer of the module.
+ *
+ * @param [out] strPose Name of the pose required for calibration
+ * <b>Remarks</b>
+ *
+ * This method is to be used only if the @ref NeedPoseForCalibration() method returns
+ * TRUE, and only then will this method returns a name.
+ */
+ inline XnStatus GetCalibrationPose(XnChar* strPose) const
+ {
+ return xnGetSkeletonCalibrationPose(GetHandle(), strPose);
+ }
+
+ /**
+ * @brief Sets the smoothing factor for all users generated by this @ref xn::UserGenerator node.
+ * @param [in] fSmoothingFactor Smoothing factor<br>
+ * Range: 0 to 1<br>
+ *
+ * <b>Remarks</b>
+ *
+ * The human body is identified from its physical depth. Since the human body is
+ * not absolutely steady, the human body being calibrated may be too jittery to
+ * easily obtain its position. This method provides an algorithm to smooth the jitter.
+ * You provide the desired smoothing factor as a parameter.
+ */
+ inline XnStatus SetSmoothing(XnFloat fSmoothingFactor)
+ {
+ return xnSetSkeletonSmoothing(GetHandle(), fSmoothingFactor);
+ }
+
+ /**
+ * Signals that a specific user's SkeletonCapability object is now starting the
+ * calibration process.
+ *
+ * Example of a callback function to handle the 'Calibration Start' event:
+ *
+ @code
+ OnCalibrationStart(xn::SkeletonCapability& skeleton, XnUserID user, void* pCookie)
+ @endcode
+ *
+ * @param [in] skeleton SkeletonCapability object that raised the event.
+ * @param [in] user The id of the user that's being calibrated.
+ * @param [in] pCookie A user-provided cookie that was given when registering to
+ * this event.
+ *
+ * <b>Remarks</b>
+ *
+ * The application itself initiates calibration by calling the @ref RequestCalibration() method.
+ * When a SkeletonCapability object actually starts to perform the calibration,
+ * it raises this event.
+ */
+ typedef void (XN_CALLBACK_TYPE* CalibrationStart)(SkeletonCapability& skeleton, XnUserID user, void* pCookie);
+
+ /**
+ * Signals that a specific user's SkeletonCapability object has now completed the
+ * calibration process.
+ *
+ * Example of a callback function to handle the 'Calibration Complete' event:
+ @code
+ OnCalibrationEnd(xn::SkeletonCapability &skeleton, XnUserID user,
+ XnCalibrationStatus calibrationError, void *pCookie)
+ @endcode
+ *
+ * <b>Parameters: </b>
+ *
+ * hNode [in] Node that raised the event.
+ * user [in] ID of the user for which calibration was attempted.
+ * bSuccess [in] Indication of whether or not the calibration attempt succeeded.
+ * pCookie [in] User-provided cookie that was given when registering to this event.
+ */
+ typedef void (XN_CALLBACK_TYPE* CalibrationEnd)(SkeletonCapability& skeleton, XnUserID user, XnBool bSuccess, void* pCookie);
+
+ /**
+ * @brief Registers an event handler for the 'Calibration Start' event.
+ *
+ * @param [in] handler Callback function to be invoked when the event is raised.
+ * @param [in] pCookie User's cookie, to be delivered to the callback.
+ * @param [out] hCallback Handle to the callback to be used for unregistering it.
+ *
+ * See @ref skeleton_calib for information about calibration.
+ *
+ * For full details and usage of the parameters, see @ref reg_to_events.
+ */
+ inline XnStatus RegisterToCalibrationStart(CalibrationStart handler, void* pCookie, XnCallbackHandle& hCallback)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+ CalibrationStartCookie* pCalibrationCookie;
+ XN_VALIDATE_ALLOC(pCalibrationCookie, CalibrationStartCookie);
+ pCalibrationCookie->handler = handler;
+ pCalibrationCookie->pUserCookie = pCookie;
+ nRetVal = xnRegisterToCalibrationStart(GetHandle(), CalibrationStartCallback, pCalibrationCookie, &pCalibrationCookie->hCallback);
+ if (nRetVal != XN_STATUS_OK)
+ {
+ xnOSFree(pCalibrationCookie);
+ return nRetVal;
+ }
+ hCallback = pCalibrationCookie;
+ return XN_STATUS_OK;
+ }
+
+ /**
+ * @brief Unregisters a handler from the 'Calibration Start' event.
+ *
+ * @param [in] hCallback Handle received from registration.
+ *
+ * <b>Remarks</b>
+ *
+ * Due to historical reasons, this function has an XnStatus return value. In practice,
+ * it will always succeed. The user can safely ignore the return value.
+ */
+ inline XnStatus UnregisterFromCalibrationStart(XnCallbackHandle hCallback)
+ {
+ CalibrationStartCookie* pCalibrationCookie = (CalibrationStartCookie*)hCallback;
+ xnUnregisterFromCalibrationStart(GetHandle(), pCalibrationCookie->hCallback);
+ xnOSFree(pCalibrationCookie);
+ return XN_STATUS_OK;
+ }
+
+ /**
+ * Signals that a specific user's skeleton is calibrating, and its current status.
+ *
+ * Example of a callback function to handle the 'Calibration Progress' event:
+ @code
+ OnCalibrationProgress(xn::SkeletonCapability &skeleton, XnUserID user,
+ XnCalibrationStatus calibrationError, void *pCookie)
+ @endcode
+ *
+ * @param [in] skeleton SkeletonCapability object that raised the event.
+ * @param [in] user ID of the user holding SkeletonCapability object.
+ * @param [in] calibrationError Status of the calibration. Values are defined by
+ * XnCalibrationStatus.
+ * @param [in] pCookie User's cookie, to be delivered to the callback.
+ *
+ * <b>Remarks</b>
+ *
+ * After the 'Calibration Start' event, the 'Calibration in Progress' event is raised
+ * every frame until 'Calibration Complete' is raised. It informs the application
+ * as to the current state of the calibration process.
+ */
+ typedef void (XN_CALLBACK_TYPE* CalibrationInProgress)(SkeletonCapability& skeleton, XnUserID user, XnCalibrationStatus calibrationError, void* pCookie);
+
+ /**
+ * @brief Registers an event handler for the 'Calibration In Progress' event.
+ *
+ * @param [in] handler Callback function to be invoked when the event is raised.
+ * @param [in] pCookie User's cookie, to be delivered to the callback.
+ * @param [out] hCallback Handle to the callback to be used for unregistering it.
+ *
+ * For full details and usage of the parameters, see @ref reg_to_events.
+ */
+ inline XnStatus RegisterToCalibrationInProgress(CalibrationInProgress handler, void* pCookie, XnCallbackHandle& hCallback)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ CalibrationInProgressCookie* pSkeletonCookie;
+ XN_VALIDATE_ALLOC(pSkeletonCookie, CalibrationInProgressCookie);
+ pSkeletonCookie->handler = handler;
+ pSkeletonCookie->pUserCookie = pCookie;
+
+ nRetVal = xnRegisterToCalibrationInProgress(GetHandle(), CalibrationInProgressCallback, pSkeletonCookie, &pSkeletonCookie->hCallback);
+ if (nRetVal != XN_STATUS_OK)
+ {
+ xnOSFree(pSkeletonCookie);
+ return (nRetVal);
+ }
+
+ hCallback = pSkeletonCookie;
+
+ return (XN_STATUS_OK);
+ }
+
+ /**
+ * @brief Unregisters an event handler for the 'Calibration In Progress' event.
+ *
+ * @param [in] hCallback Handle received from registration.
+ *
+ * For full details and usage of the parameter, see @ref unreg_from_events .
+ */
+ inline void UnregisterFromCalibrationInProgress(XnCallbackHandle hCallback)
+ {
+ CalibrationInProgressCookie* pSkeletonCookie = (CalibrationInProgressCookie*)hCallback;
+ xnUnregisterFromCalibrationInProgress(GetHandle(), pSkeletonCookie->hCallback);
+ xnOSFree(pSkeletonCookie);
+ }
+
+ /**
+ * @brief Signals that a specific user's skeleton has now completed the calibration
+ * process, and provides a result status.
+ *
+ * Following is an example of a callback header to handle the 'Calibration Complete'
+ * event:
+ @code
+ OnCalibrationComplete(xn::SkeletonCapability &skeleton, XnUserID user,
+ XnCalibrationStatus calibrationError, void *pCookie)
+ @endcode
+ *
+ * @param [in] skeleton SkeletonCapability object that raised the event.
+ * @param [in] user ID of the user holding SkeletonCapability object.
+ * @param [in] calibrationError Status of the calibration. Values are defined by
+ * XnCalibrationStatus.
+ * @param [in] pCookie User's cookie, to be delivered to the callback.
+ */
+ typedef void (XN_CALLBACK_TYPE* CalibrationComplete)(SkeletonCapability& skeleton, XnUserID user, XnCalibrationStatus calibrationError, void* pCookie);
+
+ /**
+ * @brief Registers an event handler for the 'Calibration Complete' event.
+ *
+ * @param [in] handler Callback function to be invoked when the event is raised.
+ * @param [in] pCookie User's cookie, to be delivered to the callback.
+ * @param [out] hCallback Handle to the callback to be used for unregistering it.
+ *
+ * For full details and usage of the parameters, see @ref reg_to_events.
+ */
+ inline XnStatus RegisterToCalibrationComplete(CalibrationComplete handler, void* pCookie, XnCallbackHandle& hCallback)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ CalibrationCompleteCookie* pSkeletonCookie;
+ XN_VALIDATE_ALLOC(pSkeletonCookie, CalibrationCompleteCookie);
+ pSkeletonCookie->handler = handler;
+ pSkeletonCookie->pUserCookie = pCookie;
+
+ nRetVal = xnRegisterToCalibrationComplete(GetHandle(), CalibrationCompleteCallback, pSkeletonCookie, &pSkeletonCookie->hCallback);
+ if (nRetVal != XN_STATUS_OK)
+ {
+ xnOSFree(pSkeletonCookie);
+ return (nRetVal);
+ }
+
+ hCallback = pSkeletonCookie;
+
+ return (XN_STATUS_OK);
+ }
+
+ /**
+ * @brief Unregisters an event handler for the 'Calibration Complete' event.
+ *
+ * @param [in] hCallback Handle received from registration.
+ *
+ * For full details and usage of the parameter, see @ref unreg_from_events .
+ */
+ inline void UnregisterFromCalibrationComplete(XnCallbackHandle hCallback)
+ {
+ CalibrationCompleteCookie* pSkeletonCookie = (CalibrationCompleteCookie*)hCallback;
+ xnUnregisterFromCalibrationComplete(GetHandle(), pSkeletonCookie->hCallback);
+ xnOSFree(pSkeletonCookie);
+ }
+
+ /** @cond */
+ XN_API_DEPRECATED("Use the overload with one argument - the bState parameter is useless")
+ inline XnBool IsJointActive(XnSkeletonJoint eJoint, XnBool /*bState*/) const
+ {
+ return xnIsJointActive(GetHandle(), eJoint);
+ }
+
+ inline XnStatus XN_API_DEPRECATED("Please use RegisterToCalibrationStart/Complete") RegisterCalibrationCallbacks(CalibrationStart CalibrationStartCB, CalibrationEnd CalibrationEndCB, void* pCookie, XnCallbackHandle& hCallback)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ SkeletonCookie* pSkeletonCookie;
+ XN_VALIDATE_ALLOC(pSkeletonCookie, SkeletonCookie);
+ pSkeletonCookie->startHandler = CalibrationStartCB;
+ pSkeletonCookie->endHandler = CalibrationEndCB;
+ pSkeletonCookie->pUserCookie = pCookie;
+
+#pragma warning (push)
+#pragma warning (disable: XN_DEPRECATED_WARNING_IDS)
+ nRetVal = xnRegisterCalibrationCallbacks(GetHandle(), CalibrationStartBundleCallback, CalibrationEndBundleCallback, pSkeletonCookie, &pSkeletonCookie->hCallback);
+#pragma warning (pop)
+ if (nRetVal != XN_STATUS_OK)
+ {
+ xnOSFree(pSkeletonCookie);
+ return (nRetVal);
+ }
+
+ hCallback = pSkeletonCookie;
+
+ return (XN_STATUS_OK);
+ }
+
+ inline void XN_API_DEPRECATED("Please use UnregisterFromCalibrationStart/Complete") UnregisterCalibrationCallbacks(XnCallbackHandle hCallback)
+ {
+ SkeletonCookie* pSkeletonCookie = (SkeletonCookie*)hCallback;
+#pragma warning (push)
+#pragma warning (disable: XN_DEPRECATED_WARNING_IDS)
+ xnUnregisterCalibrationCallbacks(GetHandle(), pSkeletonCookie->hCallback);
+#pragma warning (pop)
+ xnOSFree(pSkeletonCookie);
+ }
+ /** @endcond */
+
+private:
+ typedef struct SkeletonCookie
+ {
+ CalibrationStart startHandler;
+ CalibrationEnd endHandler;
+ void* pUserCookie;
+ XnCallbackHandle hCallback;
+ } SkeletonCookie;
+
+ static void XN_CALLBACK_TYPE CalibrationStartBundleCallback(XnNodeHandle hNode, XnUserID user, void* pCookie)
+ {
+ SkeletonCookie* pSkeletonCookie = (SkeletonCookie*)pCookie;
+ SkeletonCapability cap(hNode);
+ if (pSkeletonCookie->startHandler != NULL)
+ {
+ pSkeletonCookie->startHandler(cap, user, pSkeletonCookie->pUserCookie);
+ }
+ }
+
+ static void XN_CALLBACK_TYPE CalibrationEndBundleCallback(XnNodeHandle hNode, XnUserID user, XnBool bSuccess, void* pCookie)
+ {
+ SkeletonCookie* pSkeletonCookie = (SkeletonCookie*)pCookie;
+ SkeletonCapability cap(hNode);
+ if (pSkeletonCookie->endHandler != NULL)
+ {
+ pSkeletonCookie->endHandler(cap, user, bSuccess, pSkeletonCookie->pUserCookie);
+ }
+ }
+
+ typedef struct CalibrationStartCookie
+ {
+ CalibrationStart handler;
+ void* pUserCookie;
+ XnCallbackHandle hCallback;
+ } CalibrationStartCookie;
+
+ static void XN_CALLBACK_TYPE CalibrationStartCallback(XnNodeHandle hNode, XnUserID user, void* pCookie)
+ {
+ CalibrationStartCookie* pCalibrationCookie = (CalibrationStartCookie*)pCookie;
+ SkeletonCapability cap(hNode);
+ if (pCalibrationCookie->handler != NULL)
+ {
+ pCalibrationCookie->handler(cap, user, pCalibrationCookie->pUserCookie);
+ }
+ }
+
+ typedef struct CalibrationInProgressCookie
+ {
+ CalibrationInProgress handler;
+ void* pUserCookie;
+ XnCallbackHandle hCallback;
+ } CalibrationInProgressCookie;
+
+ static void XN_CALLBACK_TYPE CalibrationInProgressCallback(XnNodeHandle hNode, XnUserID user, XnCalibrationStatus calibrationError, void* pCookie)
+ {
+ CalibrationInProgressCookie* pSkeletonCookie = (CalibrationInProgressCookie*)pCookie;
+ SkeletonCapability cap(hNode);
+ if (pSkeletonCookie->handler != NULL)
+ {
+ pSkeletonCookie->handler(cap, user, calibrationError, pSkeletonCookie->pUserCookie);
+ }
+ }
+
+ typedef struct CalibrationCompleteCookie
+ {
+ CalibrationComplete handler;
+ void* pUserCookie;
+ XnCallbackHandle hCallback;
+ } CalibrationCompleteCookie;
+
+ static void XN_CALLBACK_TYPE CalibrationCompleteCallback(XnNodeHandle hNode, XnUserID user, XnCalibrationStatus calibrationError, void* pCookie)
+ {
+ CalibrationCompleteCookie* pSkeletonCookie = (CalibrationCompleteCookie*)pCookie;
+ SkeletonCapability cap(hNode);
+ if (pSkeletonCookie->handler != NULL)
+ {
+ pSkeletonCookie->handler(cap, user, calibrationError, pSkeletonCookie->pUserCookie);
+ }
+ }
+ };
+
+ /**
+ * @ingroup cppref_prd_func
+ *
+ * <b>Purpose:</b> Provides a 'Pose Detection' functionality for a @ref xn::UserGenerator
+ * node. This capability lets the node recognize when the user is posed in a specific
+ * position.
+ *
+ * <b>Usage:</b> Do not instantiate directly. Instead, use @ref UserGenerator::GetPoseDetectionCap()
+ * to obtain an instance.
+ *
+ * <b>Data output:</b> Raises events.
+ *
+ * <b>Remarks:</b>
+ *
+ * A pose is a specific full body posture involving all the limbs. The PoseDetectionCapability
+ * object scans the FOV to detect users performing poses. The PoseDetectionCapability
+ * then generates the pose data.
+ *
+ * When and if the @ref PoseDetectionCapability object detects a pose it raises the
+ * 'Pose Detected' event.
+ */
+ class PoseDetectionCapability : public Capability
+ {
+ public:
+ /**
+ * Ctor
+ *
+ * @param [in] hNode Node handle
+ */
+ inline PoseDetectionCapability(XnNodeHandle hNode) : Capability(hNode) {}
+ PoseDetectionCapability(const NodeWrapper& node) : Capability(node) {}
+
+ /**
+ * <b>'Pose Detection' event</b>
+ *
+ * This event is raised to signal that a specific user has entered a pose.
+ *
+ * @param [in] pose Reference to the specific @ref xn::UserGenerator node
+ * that raised the event.
+ * @param [in] strPose Name of the specific pose defined for this event handler.
+ * (The PoseDetectionCapability can define more than a single pose that can be detected.)
+ * @param [in] user ID of the user that entered the pose.
+ * @param [in] pCookie Returns any information ("cookie") that the application
+ * placed in this parameter at the time of registering the event..
+ */
+ typedef void (XN_CALLBACK_TYPE* PoseDetection)(PoseDetectionCapability& pose, const XnChar* strPose, XnUserID user, void* pCookie);
+
+ /**
+ * @brief Get the number of poses supported by this capability.
+ *
+ * <b>Remarks</b>
+ *
+ * The number of supported poses is defined by the developer of the capability and
+ * is common to all @ref xn::UserGenerator nodes using this capability on this OpenNI
+ * deployment.
+ */
+ inline XnUInt32 GetNumberOfPoses() const
+ {
+ return xnGetNumberOfPoses(GetHandle());
+ }
+
+ /**
+ * @brief Gets the names of all poses supported by this capability.
+
+ * @param [out] pstrPoses Pre-allocated memory for the names of the supported poses.
+ * @param [in] nNameLength Memory size for each pose name.
+ * @param [in,out] nPoses In input - size of the preallocated memory, in output
+ * - the number of pose names.
+ *
+ * <b>Remarks</b>
+ *
+ * The names of the poses are preset in advance by the developer of this capability.
+ */
+ inline XnStatus GetAllAvailablePoses(XnChar** pstrPoses, XnUInt32 nNameLength, XnUInt32& nPoses) const
+ {
+ return xnGetAllAvailablePoses(GetHandle(), pstrPoses, nNameLength, &nPoses);
+ }
+
+ inline XnBool IsPoseSupported(const XnChar* strPose)
+ {
+ return xnIsPoseSupported(GetHandle(), strPose);
+ }
+
+ inline XnStatus GetPoseStatus(XnUserID userID, const XnChar* poseName, XnUInt64& poseTime, XnPoseDetectionStatus& eStatus, XnPoseDetectionState& eState)
+ {
+ return xnGetPoseStatus(GetHandle(), userID, poseName, &poseTime, &eStatus, &eState);
+ }
+
+ /**
+ * @brief Starts attempting to detect a pose for a specific user.
+ *
+ * @param [in] strPose Name of the requested pose. Call the GetAvailablePoses()
+ * method to get the names of poses supported by the PoseDetectionCapability.
+ * @param [in] user ID of a user to detect a pose for.
+ *
+ * <b>Remarks</b>
+ *
+ * This method will typically be used after a new user has been recognized in the
+ * FOV. This is typically the next stage in the process of calibrating the new user -
+ * @see skeleton_calib.
+ * When and if the @ref PoseDetectionCapability object detects a pose it raises
+ * the 'Pose Detected' event.
+ */
+ inline XnStatus StartPoseDetection(const XnChar* strPose, XnUserID user)
+ {
+ return xnStartPoseDetection(GetHandle(), strPose, user);
+ }
+
+ /**
+ * @brief Stops attempting to detect a pose (for a specific user).
+ *
+ * @param [in] user ID of a user.
+ *
+ * <b>Remarks</b>
+ *
+ * The application will typically call this method when it has already received
+ * a 'Pose Detected' event. Once a pose has been detected it is no longer necessary
+ * to try to detect poses.
+ */
+ inline XnStatus StopPoseDetection(XnUserID user)
+ {
+ return xnStopPoseDetection(GetHandle(), user);
+ }
+
+ /** @copybrief xnStopSinglePoseDetection
+ * For full details and usage, see @ref xnStopSinglePoseDetection
+ */
+ inline XnStatus StopSinglePoseDetection(XnUserID user, const XnChar* strPose)
+ {
+ return xnStopSinglePoseDetection(GetHandle(), user, strPose);
+ }
+
+ /**
+ * @brief Registers an event handler for the 'Pose Detected' event.
+ *
+ * @param [in] handler Callback function to be invoked when the event is raised.
+ * @param [in] pCookie User's cookie, to be delivered to the callback.
+ * @param [out] hCallback Handle to the callback to be used for unregistering it.
+ *
+ * For full details and usage of the parameters, see @ref reg_to_events.
+ */
+ inline XnStatus RegisterToPoseDetected(PoseDetection handler, void* pCookie, XnCallbackHandle& hCallback)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+ PoseDetectionCookie* pPoseCookie;
+ XN_VALIDATE_ALLOC(pPoseCookie, PoseDetectionCookie);
+ pPoseCookie->handler = handler;
+ pPoseCookie->pPoseCookie = pCookie;
+
+ nRetVal = xnRegisterToPoseDetected(GetHandle(), PoseDetectionCallback, pPoseCookie, &pPoseCookie->hCallback);
+ if (nRetVal != XN_STATUS_OK)
+ {
+ xnOSFree(pPoseCookie);
+ return nRetVal;
+ }
+ hCallback = pPoseCookie;
+ return XN_STATUS_OK;
+ }
+
+ /**
+ * @brief Registers an event handler for the 'Out Of Pose' event.
+ *
+ * @param [in] handler Callback function to be invoked when the event is raised.
+ * @param [in] pCookie User's cookie, to be delivered to the callback.
+ * @param [out] hCallback Handle to the callback to be used for unregistering it.
+ *
+ * For full details and usage of the parameters, see @ref reg_to_events.
+ */
+ inline XnStatus RegisterToOutOfPose(PoseDetection handler, void* pCookie, XnCallbackHandle& hCallback)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+ PoseDetectionCookie* pPoseCookie;
+ XN_VALIDATE_ALLOC(pPoseCookie, PoseDetectionCookie);
+ pPoseCookie->handler = handler;
+ pPoseCookie->pPoseCookie = pCookie;
+
+ nRetVal = xnRegisterToOutOfPose(GetHandle(), PoseDetectionCallback, pPoseCookie, &pPoseCookie->hCallback);
+ if (nRetVal != XN_STATUS_OK)
+ {
+ xnOSFree(pPoseCookie);
+ return nRetVal;
+ }
+ hCallback = pPoseCookie;
+ return XN_STATUS_OK;
+ }
+ /**
+ * @brief Unregisters an event handler for the 'Pose Detected' event.
+ *
+ * @param [in] hCallback Handle received from registration.
+ *
+ * For full details and usage of the parameter, see @ref unreg_from_events .
+ */
+ inline void UnregisterFromPoseDetected(XnCallbackHandle hCallback)
+ {
+ PoseDetectionCookie* pPoseCookie = (PoseDetectionCookie*)hCallback;
+ xnUnregisterFromPoseDetected(GetHandle(), pPoseCookie->hCallback);
+ xnOSFree(pPoseCookie);
+ }
+ /**
+ * @brief Unregisters an event handler for the 'Out Of Pose' event.
+ *
+ * @param [in] hCallback Handle received from registration.
+ *
+ * For full details and usage of the parameter, see @ref unreg_from_events .
+ */
+ inline void UnregisterFromOutOfPose(XnCallbackHandle hCallback)
+ {
+ PoseDetectionCookie* pPoseCookie = (PoseDetectionCookie*)hCallback;
+ xnUnregisterFromOutOfPose(GetHandle(), pPoseCookie->hCallback);
+ xnOSFree(pPoseCookie);
+ }
+
+ /**
+ * <b>'Pose In Progress' event</b>:
+ *
+ * Raised at each frame time from the time StartPoseDetection was called until the
+ * pose is detected. This event returns the current status of pose detection of
+ * a user.
+ *
+ * @param [in] pose Reference to the specific @ref UserGenerator node that raised
+ * the event.
+ * @param [in] strPose Name of the specific pose defined for this event handler.
+ * (The PoseDetectionCapability can define more than a single pose that can be detected.
+ * @param [in] user ID of the user that entered the pose.
+ * @param [in] poseError Current status of the pose detection.
+ * Defined statuses:
+ * XN_POSE_DETECTION_STATUS_OK
+ * XN_POSE_DETECTION_STATUS_NO_USER
+ * XN_POSE_DETECTION_STATUS_TOP_FOV
+ * XN_POSE_DETECTION_STATUS_SIDE_FOV
+ * XN_POSE_DETECTION_STATUS_ERROR
+ * @param [in] pCookie Returns any information ("cookie") that the application
+ * placed in this parameter at the time of registering the event.
+ */
+ typedef void (XN_CALLBACK_TYPE* PoseInProgress)(PoseDetectionCapability& pose, const XnChar* strPose, XnUserID user, XnPoseDetectionStatus poseError, void* pCookie);
+
+ /**
+ * @brief Registers an event handler for the 'Pose In Progress' event.
+ * @param [in] handler Callback function to be invoked when the event is raised.
+ * @param [in] pCookie User's cookie, to be delivered to the callback.
+ * @param [out] hCallback Handle to the callback to be used for unregistering it.
+ *
+ * For full details and usage of the parameters, see @ref reg_to_events.
+ *
+ * <b>Remarks</b>
+ *
+ * This event is raised at each frame time from the time StartPoseDetection() method
+ * was called until the pose is actually detected.
+ *
+ * See the @ref PoseDetection callback type declaration for how to write the callback
+ * (event handler).
+ */
+ inline XnStatus RegisterToPoseInProgress(PoseInProgress handler, void* pCookie, XnCallbackHandle& hCallback)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ PoseInProgressCookie* pPoseCookie;
+ XN_VALIDATE_ALLOC(pPoseCookie, PoseInProgressCookie);
+ pPoseCookie->handler = handler;
+ pPoseCookie->pPoseCookie = pCookie;
+
+ nRetVal = xnRegisterToPoseDetectionInProgress(GetHandle(), PoseDetectionInProgressCallback, pPoseCookie, &pPoseCookie->hCallback);
+ if (nRetVal != XN_STATUS_OK)
+ {
+ xnOSFree(pPoseCookie);
+ return (nRetVal);
+ }
+
+ hCallback = pPoseCookie;
+
+ return (XN_STATUS_OK);
+ }
+
+ /**
+ * @brief Unregisters an event handler for the 'Pose In Progress' event.
+ *
+ * @param [in] hCallback Handle received from registration.
+ *
+ * For full details and usage of the parameter, see @ref unreg_from_events .
+ */
+ inline void UnregisterFromPoseInProgress(XnCallbackHandle hCallback)
+ {
+ PoseInProgressCookie* pPoseCookie = (PoseInProgressCookie*)hCallback;
+ xnUnregisterFromPoseDetectionInProgress(GetHandle(), pPoseCookie->hCallback);
+ xnOSFree(pPoseCookie);
+ }
+
+ /** @cond */
+ inline XnStatus XN_API_DEPRECATED("Use GetAllAvailablePoses() instead") GetAvailablePoses(XnChar** pstrPoses, XnUInt32& nPoses) const
+ {
+ return xnGetAvailablePoses(GetHandle(), pstrPoses, &nPoses);
+ }
+
+ inline XnStatus XN_API_DEPRECATED("Please use RegisterToPoseDetected/RegisterToOutOfPose instead") RegisterToPoseCallbacks(PoseDetection PoseStartCB, PoseDetection PoseEndCB, void* pCookie, XnCallbackHandle& hCallback)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ PoseCookie* pPoseCookie;
+ XN_VALIDATE_ALLOC(pPoseCookie, PoseCookie);
+ pPoseCookie->startHandler = PoseStartCB;
+ pPoseCookie->endHandler = PoseEndCB;
+ pPoseCookie->pPoseCookie = pCookie;
+
+#pragma warning (push)
+#pragma warning (disable: XN_DEPRECATED_WARNING_IDS)
+ nRetVal = xnRegisterToPoseCallbacks(GetHandle(), PoseDetectionStartBundleCallback, PoseDetectionStartEndBundleCallback, pPoseCookie, &pPoseCookie->hCallback);
+#pragma warning (pop)
+ if (nRetVal != XN_STATUS_OK)
+ {
+ xnOSFree(pPoseCookie);
+ return (nRetVal);
+ }
+
+ hCallback = pPoseCookie;
+
+ return (XN_STATUS_OK);
+ }
+
+ inline void XN_API_DEPRECATED("Please use UnregisterFromPoseDetected/UnregisterFromOutOfPose instead") UnregisterFromPoseCallbacks(XnCallbackHandle hCallback)
+ {
+ PoseCookie* pPoseCookie = (PoseCookie*)hCallback;
+#pragma warning (push)
+#pragma warning (disable: XN_DEPRECATED_WARNING_IDS)
+ xnUnregisterFromPoseCallbacks(GetHandle(), pPoseCookie->hCallback);
+#pragma warning (pop)
+ xnOSFree(pPoseCookie);
+ }
+ /** @endcond */
+
+private:
+ typedef struct PoseCookie
+ {
+ PoseDetection startHandler;
+ PoseDetection endHandler;
+ void* pPoseCookie;
+ XnCallbackHandle hCallback;
+ } PoseCookie;
+
+ static void XN_CALLBACK_TYPE PoseDetectionStartBundleCallback(XnNodeHandle hNode, const XnChar* strPose, XnUserID user, void* pCookie)
+ {
+ PoseCookie* pPoseCookie = (PoseCookie*)pCookie;
+ PoseDetectionCapability cap(hNode);
+ if (pPoseCookie->startHandler != NULL)
+ {
+ pPoseCookie->startHandler(cap, strPose, user, pPoseCookie->pPoseCookie);
+ }
+ }
+
+ static void XN_CALLBACK_TYPE PoseDetectionStartEndBundleCallback(XnNodeHandle hNode, const XnChar* strPose, XnUserID user, void* pCookie)
+ {
+ PoseCookie* pPoseCookie = (PoseCookie*)pCookie;
+ PoseDetectionCapability cap(hNode);
+ if (pPoseCookie->endHandler != NULL)
+ {
+ pPoseCookie->endHandler(cap, strPose, user, pPoseCookie->pPoseCookie);
+ }
+ }
+ typedef struct PoseDetectionCookie
+ {
+ PoseDetection handler;
+ void* pPoseCookie;
+ XnCallbackHandle hCallback;
+ } PoseDetectionCookie;
+ static void XN_CALLBACK_TYPE PoseDetectionCallback(XnNodeHandle hNode, const XnChar* strPose, XnUserID user, void* pCookie)
+ {
+ PoseDetectionCookie* pPoseDetectionCookie = (PoseDetectionCookie*)pCookie;
+ PoseDetectionCapability cap(hNode);
+ if (pPoseDetectionCookie->handler != NULL)
+ {
+ pPoseDetectionCookie->handler(cap, strPose, user, pPoseDetectionCookie->pPoseCookie);
+ }
+ }
+
+ typedef struct PoseInProgressCookie
+ {
+ PoseInProgress handler;
+ void* pPoseCookie;
+ XnCallbackHandle hCallback;
+ } PoseInProgressCookie;
+
+ static void XN_CALLBACK_TYPE PoseDetectionInProgressCallback(XnNodeHandle hNode, const XnChar* strPose, XnUserID user, XnPoseDetectionStatus poseErrors, void* pCookie)
+ {
+ PoseInProgressCookie* pPoseCookie = (PoseInProgressCookie*)pCookie;
+ PoseDetectionCapability cap(hNode);
+ if (pPoseCookie->handler != NULL)
+ {
+ pPoseCookie->handler(cap, strPose, user, poseErrors, pPoseCookie->pPoseCookie);
+ }
+ }
+ };
+
+ /**
+ * @ingroup cppref_prd_func
+ * <b>Purpose:</b> The UserGenerator node generates data describing users that it recognizes
+ * in the scene, identifying each user individually and thus allowing actions to be
+ * done on specific users.
+ *
+ * <b>Usage:</b> Instantiate the class and call Create() to create a user generator node.
+ *
+ * <b>Data output:</b>
+ * - CoM from UserGenerator local data
+ * - User pixels from @ref SceneMetaData
+ *
+ * <b>Capabilities:</b>
+ * - @ref SkeletonCapability
+ * - @ref PoseDetectionCapability
+ *
+ * <b>Remarks:</b>
+ *
+ * The UserGenerator node provides access to the recognized users through user IDs it
+ * returns. The user IDs are unique user identification numbers. The application uses
+ * these user IDs to pass them to various methods of this node to access the specific
+ * data of the specified user. For example:
+ *
+ * @ref xn::UserGenerator::GetUserPixels() gets the pixel map of a specific user, and
+ * @ref xn::UserGenerator::GetCoM() gets the location of the center of mass of a specific
+ * user.
+ *
+ * Typically, an application will require only a single UserGenerator node. However,
+ * there are cases where more than one UserGenerator node could be required. For example,
+ * where there are two sensors it may be convenient to build a production graph with
+ * two UserGenerator nodes, one node for each depth output.
+ *
+ * <b>Main Features:</b>
+ *
+ * - User CoM: Provides the location of the center of mass of a specific user.
+ * - Number of users: Provides the number of users currently detected in the scene.
+ * - Users list: Provides a list of the IDs of currently recognized users in the scene.
+ * - User pixels: Provides the pixels that represent a specific user.
+ * - Events: Provides events about users in the scene:
+ * - A new user is identified ('New User')
+ * - An existing user exits temporarily ('User Exit')
+ * - An exited user returns ('User Reenter')
+ * - An existing user exits permanently ('Lost User')
+ *
+ * @note Registering to the 'New User' and 'Lost User' events is done by calling @ref RegisterUserCallbacks().
+ * Registering to the 'User Exit' and 'User Reenter' events is done by calling @ref RegisterToUserExit() and @ref RegisterToUserReEnter().
+ *
+ * @section user_events Events
+ *
+ * <b>New User' event</b>
+ *
+ * Signals that a new user has now been recognized in the scene. A new user is a
+ * user that was not previously recognized in the scene, and is now recognized in
+ * the scene.
+ *
+ * <b>'Lost User' event</b>
+ *
+ * Signals that a user has been lost from the list of previously recognized users
+ * in the scene.
+ *
+ * The exact meaning of a lost user is decided by the developer of the user generator.
+ * However, a typical implementation would define that a lost user is a previously
+ * recognized user that then exits the scene and does not return, even after a 'Lost
+ * User' timeout has elapsed. Thus this event is raised only after some delay after
+ * the user actually exited the scene.
+ *
+ * Using the above approach, the difference then between the 'Lost User' event and
+ * the 'User Exit' event (see below) would be that the 'User Exit' event is raised
+ * every time a recognized user leaves the scene, but a 'Lost User' event is raised
+ * only after the user has remained absent ("exit-ed") for a certain timeout period
+ * of time.
+ *
+ * If no timeout is used at all, the 'User Exit' and 'User Reenter' events are redundant.
+ *
+ * <b>'User Exit' event</b>
+ *
+ * Signals that a user now exited from the scene.
+ *
+ * The exact meaning of a user that exited is decided by the developer of the
+ * user generator. However, a typical implementation would define that a user that
+ * exited the scene is a previously recognized user that then leaves the scene.
+ * but returns within a specified time, before the 'Lost User' timeout has elapsed.
+ * In such a case the UserGenerator object still remembers the user and so when
+ * the user comes back, everything known about it is restored. See the 'Lost User'
+ * event above for more explanation of the difference between the 'User Exit' event
+ * and the 'Lost User' event in a typical implementation.
+ *
+ * <b>'User Reenter' event</b>
+ *
+ * Signals that a user has now reentered to the scene after exiting. A user that
+ * reenters the scene after exiting is a recognized user that exited, but now is
+ * returning within a specified permitted time span, before the 'Lost User' timeout
+ * has elapsed. In such a case the UserGenerator node still remembers the user and
+ * so when the user returns, everything known about it is restored.
+ *
+ * <b>Event Sequence</b>
+ *
+ * The following event sequences are typical:
+ *
+ * A:
+ * -# 'New User'
+ * -# 'User Exit'
+ * -# 'Lost User'
+ *
+ * B:
+ * -# 'New User'
+ * -# 'User Exit'
+ * -# 'User Reenter'
+ * -# 'User Exit'
+ * -# 'Lost User'
+ */
+ class UserGenerator : public Generator
+ {
+ public:
+ /**
+ * Ctor
+ *
+ * @param [in] hNode Node handle
+ */
+ inline UserGenerator(XnNodeHandle hNode = NULL) : Generator(hNode) {}
+ inline UserGenerator(const NodeWrapper& other) : Generator(other) {}
+
+ /**
+ * @brief Creates a UserGenerator node from available @ref node_alternative "production node alternatives".
+ *
+ * <b>Remarks:</b>
+ *
+ * See @ref create_method for a detailed description of this method.
+ */
+ inline XnStatus Create(Context& context, Query* pQuery = NULL, EnumerationErrors* pErrors = NULL);
+
+ /**
+ * @brief Event handler signature for all UserGenerator events.
+ *
+ * Example of a handler prototype (for the 'New User' event in this case):
+ @code
+ void XN_CALLBACK_TYPE OnNewUser(xn::UserGenerator& generator, XnUserID nId, void* pCookie)
+ @endcode
+ *
+ * @param [in] generator UserGenerator node that raised the event.
+ * @param [in] user ID of the user.
+ * @param [in] pCookie User's cookie, to be delivered to the callback.
+ */
+ typedef void (XN_CALLBACK_TYPE* UserHandler)(UserGenerator& generator, XnUserID user, void* pCookie);
+
+ /**
+ * @brief Gets the number of users currently identified in the scene.
+ *
+ * <b>Remarks:</b>
+ *
+ * The result of this method is required as input for the GetUsers() method.
+ */
+ inline XnUInt16 GetNumberOfUsers() const
+ {
+ return xnGetNumberOfUsers(GetHandle());
+ }
+
+ /**
+ * @brief Gets an array of user IDs of all the recognized users in the scene at the current time.
+ *
+ * @param [out] aUsers Preallocated memory for the method to enter the user IDs.
+ * @param [in,out] nUsers Number of users.
+ *
+ * @c nUsers is used both as an in parameter and an out one in this method:
+ * [in] Size of the aUsers array (in units of users).
+ * To get the value of nUsers (i.e., the size of array that you want - see
+ * parameter below), you use the GetNumberOfUsers() method.
+ * For example, if you want an array of size 4 - to contain a maximum of 4 users -
+ * you pass 4 as the value of this parameter.
+ *
+ * [out] On completion, the method returns the number of users that were recognized.
+ * E.g., if there is actually only one user, the output will be 1, although the
+ * caller passed a value of 4 (as above) for to allocate an array of size 4.
+ *
+ * <b>Remarks:</b>
+ *
+ * The output user IDs from this method can be used as input to the @ref xn::UserGenerator::GetCoM()
+ * method for getting the center of mass of each user.
+ */
+ inline XnStatus GetUsers(XnUserID aUsers[], XnUInt16& nUsers) const
+ {
+ return xnGetUsers(GetHandle(), aUsers, &nUsers);
+ }
+
+ /**
+ * @brief Gets the position of a user's center of mass. This is the single point for
+ * representing the user.
+ *
+ * @param [in] user Specifies a user ID.
+ * @param [out] com The user's center of mass in 3-D coordinates.
+ *
+ * The center of mass is a useful point to represent the user. When you don't have
+ * any other reference point (e.g., you don't have the position of a specific joint,
+ * or of the head, or any other such point), this is an adequate point with which
+ * to start to represent the user.
+ *
+ * <b>Remarks:</b>
+ *
+ * The returned @ref XnPoint3D value is the center of mass of all the shown pixels
+ * that belong to that user, but not necessarily the real center of mass of the
+ * human user.
+ * The application can use this method to request the center of mass for each user.
+ */
+ inline XnStatus GetCoM(XnUserID user, XnPoint3D& com) const
+ {
+ return xnGetUserCoM(GetHandle(), user, &com);
+ }
+
+ /**
+ * @brief Gets the pixel map of the specified user in the scene and saves it in the @ref xn::SceneMetaData object.
+ * The pixels that form part of the user's body are labeled with user's ID. Other values are irrelevant.
+ *
+ * @param [in] user The ID of the user the pixel map should be returned for.
+ * @param [out] smd Struct to be filled with the pixel map.
+ *
+ * <b>Remarks:</b>
+ *
+ * A usage example for this method in gaming is for coloring the avatar on the screen.
+ *
+ * The special value 0 (zero) can be used in the @c user parameter, telling the generator to return a label map
+ * containing all users, where each pixel is either marked as 0 (background pixel) or with the user ID to which
+ * it belongs.
+ */
+ inline XnStatus GetUserPixels(XnUserID user, SceneMetaData& smd) const
+ {
+ return xnGetUserPixels(GetHandle(), user, smd.GetUnderlying());
+ }
+
+ /**
+ * @brief Registers event handlers for the 'New User' and 'Lost User' events.
+ *
+ * @param [in] NewUserCB Callback function to be invoked when the 'New User' event is raised.
+ * @param [in] LostUserCB Callback function to be invoked when the 'Lost User' event is raised.
+ * @param [in] pCookie User's cookie, to be delivered to the callback.
+ * @param [out] hCallback Handle to the callback to be used for unregistering it.
+ *
+ * For full details and usage of the parameters, see @ref reg_to_events.
+ */
+ inline XnStatus RegisterUserCallbacks(UserHandler NewUserCB, UserHandler LostUserCB, void* pCookie, XnCallbackHandle& hCallback)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ UserCookie* pUserCookie;
+ XN_VALIDATE_ALLOC(pUserCookie, UserCookie);
+ pUserCookie->newHandler = NewUserCB;
+ pUserCookie->lostHandler = LostUserCB;
+ pUserCookie->pUserCookie = pCookie;
+
+ nRetVal = xnRegisterUserCallbacks(GetHandle(), NewUserCallback, LostUserCallback, pUserCookie, &pUserCookie->hCallback);
+ if (nRetVal != XN_STATUS_OK)
+ {
+ xnOSFree(pUserCookie);
+ return (nRetVal);
+ }
+
+ hCallback = pUserCookie;
+
+ return (XN_STATUS_OK);
+ }
+
+ /**
+ * @brief Unregisters event handlers for the 'New User' and 'Lost User' events.
+ *
+ * @param [in] hCallback Handle received from registration.
+ *
+ * For full details and usage of the parameter, see @ref unreg_from_events .
+ */
+ inline void UnregisterUserCallbacks(XnCallbackHandle hCallback)
+ {
+ UserCookie* pUserCookie = (UserCookie*)hCallback;
+ xnUnregisterUserCallbacks(GetHandle(), pUserCookie->hCallback);
+ xnOSFree(pUserCookie);
+ }
+
+ /**
+ * @brief Gets a @ref SkeletonCapability object for accessing Skeleton functionality.
+ *
+ * <b>Remarks:</b>
+ *
+ * Once the @ref SkeletonCapability object has been obtained, the application can
+ * work with a skeleton.
+ *
+ * It is the application's responsibility to check first if Skeleton capability
+ * is supported by calling the @ref IsCapabilitySupported() method..
+ */
+ inline const SkeletonCapability GetSkeletonCap() const
+ {
+ return SkeletonCapability(GetHandle());
+ }
+
+ /**
+ * @brief Gets a @ref SkeletonCapability object for accessing Skeleton functionality.
+ *
+ * <b>Remarks:</b>
+ *
+ * Once the @ref SkeletonCapability object has been obtained, the application can
+ * work with a skeleton.
+ *
+ * It is the application's responsibility to check first if Skeleton capability
+ * is supported by calling the @ref IsCapabilitySupported() method..
+ */
+ inline SkeletonCapability GetSkeletonCap()
+ {
+ return SkeletonCapability(GetHandle());
+ }
+
+ /**
+ * @brief Gets a @ref xn::PoseDetectionCapability object for accessing Pose Detection
+ * functionality
+ *
+ * <b>Remarks:</b>
+ *
+ * It is the application responsibility to check first if @ref XN_CAPABILITY_POSE_DETECTION
+ * is supported
+ * by calling @ref xn::ProductionNode::IsCapabilitySupported().
+ */
+ inline const PoseDetectionCapability GetPoseDetectionCap() const
+ {
+ return PoseDetectionCapability(GetHandle());
+ }
+
+ /**
+ * @brief Gets a @ref xn::PoseDetectionCapability object for accessing Pose Detection
+ * functionality
+ *
+ * <b>Remarks:</b>
+ *
+ * It is the application responsibility to check first if @ref XN_CAPABILITY_POSE_DETECTION
+ * is supported
+ * by calling @ref xn::ProductionNode::IsCapabilitySupported().
+ */
+ inline PoseDetectionCapability GetPoseDetectionCap()
+ {
+ return PoseDetectionCapability(GetHandle());
+ }
+
+ /**
+ * @brief Registers an event handler for the 'User Exit' event.
+ *
+ * @param [in] handler Callback function to be invoked when the event is raised.
+ * @param [in] pCookie User's cookie, to be delivered to the callback.
+ * @param [out] hCallback Handle to the callback to be used for unregistering it.
+ *
+ * For full details and usage of the parameters, see @ref reg_to_events.
+ */
+ inline XnStatus RegisterToUserExit(UserHandler handler, void* pCookie, XnCallbackHandle& hCallback)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ UserSingleCookie* pUserCookie;
+ XN_VALIDATE_ALLOC(pUserCookie, UserSingleCookie);
+ pUserCookie->handler = handler;
+ pUserCookie->pUserCookie = pCookie;
+
+ nRetVal = xnRegisterToUserExit(GetHandle(), UserSingleCallback, pUserCookie, &pUserCookie->hCallback);
+ if (nRetVal != XN_STATUS_OK)
+ {
+ xnOSFree(pUserCookie);
+ return (nRetVal);
+ }
+
+ hCallback = pUserCookie;
+
+ return (XN_STATUS_OK);
+ }
+
+ /**
+ * @brief Unregisters an event handler for the 'User Exit' event.
+ *
+ * @param [in] hCallback Handle received from registration.
+ *
+ * For full details and usage of the parameter, see @ref unreg_from_events .
+ */
+ inline void UnregisterFromUserExit(XnCallbackHandle hCallback)
+ {
+ UserSingleCookie* pUserCookie = (UserSingleCookie*)hCallback;
+ xnUnregisterFromUserExit(GetHandle(), pUserCookie->hCallback);
+ xnOSFree(pUserCookie);
+ }
+
+ /**
+ * @brief Registers an event handler for the 'User Reenter' event.
+ *
+ * @param [in] handler Callback function to be invoked when the event is raised.
+ * @param [in] pCookie User's cookie, to be delivered to the callback.
+ * @param [out] hCallback Handle to the callback to be used for unregistering it.
+ *
+ * For full details and usage of the parameters, see @ref reg_to_events.
+ */
+ inline XnStatus RegisterToUserReEnter(UserHandler handler, void* pCookie, XnCallbackHandle& hCallback)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ UserSingleCookie* pUserCookie;
+ XN_VALIDATE_ALLOC(pUserCookie, UserSingleCookie);
+ pUserCookie->handler = handler;
+ pUserCookie->pUserCookie = pCookie;
+
+ nRetVal = xnRegisterToUserReEnter(GetHandle(), UserSingleCallback, pUserCookie, &pUserCookie->hCallback);
+ if (nRetVal != XN_STATUS_OK)
+ {
+ xnOSFree(pUserCookie);
+ return (nRetVal);
+ }
+
+ hCallback = pUserCookie;
+
+ return (XN_STATUS_OK);
+ }
+
+ /**
+ * @brief Unregisters an event handler for the 'User Reenter' event.
+ *
+ * @param [in] hCallback Handle received from registration.
+ *
+ * For full details and usage of the parameter, see @ref unreg_from_events .
+ */
+ inline void UnregisterFromUserReEnter(XnCallbackHandle hCallback)
+ {
+ UserSingleCookie* pUserCookie = (UserSingleCookie*)hCallback;
+ xnUnregisterFromUserReEnter(GetHandle(), pUserCookie->hCallback);
+ xnOSFree(pUserCookie);
+ }
+
+ private:
+ typedef struct UserCookie
+ {
+ UserHandler newHandler;
+ UserHandler lostHandler;
+ void* pUserCookie;
+ XnCallbackHandle hCallback;
+ } UserCookie;
+
+ static void XN_CALLBACK_TYPE NewUserCallback(XnNodeHandle hNode, XnUserID user, void* pCookie)
+ {
+ UserCookie* pUserCookie = (UserCookie*)pCookie;
+ UserGenerator gen(hNode);
+ if (pUserCookie->newHandler != NULL)
+ {
+ pUserCookie->newHandler(gen, user, pUserCookie->pUserCookie);
+ }
+ }
+
+ static void XN_CALLBACK_TYPE LostUserCallback(XnNodeHandle hNode, XnUserID user, void* pCookie)
+ {
+ UserCookie* pUserCookie = (UserCookie*)pCookie;
+ UserGenerator gen(hNode);
+ if (pUserCookie->lostHandler != NULL)
+ {
+ pUserCookie->lostHandler(gen, user, pUserCookie->pUserCookie);
+ }
+ }
+
+ typedef struct UserSingleCookie
+ {
+ UserHandler handler;
+ void* pUserCookie;
+ XnCallbackHandle hCallback;
+ } UserSingleCookie;
+
+ static void XN_CALLBACK_TYPE UserSingleCallback(XnNodeHandle hNode, XnUserID user, void* pCookie)
+ {
+ UserSingleCookie* pUserCookie = (UserSingleCookie*)pCookie;
+ UserGenerator gen(hNode);
+ if (pUserCookie->handler != NULL)
+ {
+ pUserCookie->handler(gen, user, pUserCookie->pUserCookie);
+ }
+ }
+ };
+
+ /**
+ * @ingroup cppref_prd_func
+ * <b>Purpose:</b> An audio generator node generates audio data.
+ *
+ * <b>Event: 'Wave Output Mode Change'</b>
+ *
+ * Signals that the node's current configuration's Wave Output Mode has been changed
+ * to some other wave output mode.
+ *
+ * Use @ref RegisterToWaveOutputModeChanges() and @ref UnregisterFromWaveOutputModeChanges() for using this event.
+ *
+ * This event is raised by calling SetWaveOutputMode().
+ */
+ class AudioGenerator : public Generator
+ {
+ public:
+ /**
+ * Ctor
+ *
+ * @param [in] hNode Node handle
+ */
+ inline AudioGenerator(XnNodeHandle hNode = NULL) : Generator(hNode) {}
+ inline AudioGenerator(const NodeWrapper& other) : Generator(other) {}
+
+ /**
+ * @brief Creates an AudioGenerator node from available @ref node_alternative "production node alternatives".
+ *
+ * <b>Remarks</b>
+ *
+ * See @ref create_method for a detailed description of this method.
+ */
+ inline XnStatus Create(Context& context, Query* pQuery = NULL, EnumerationErrors* pErrors = NULL);
+
+ /**
+ * @brief Gets the audio generator node's latest @ref glos_frame_object "frame object", saving
+ * it in the @ref xn::AudioMetaData object. This @ref glos_frame_object "frame object" is a
+ * snapshot of the generated label map data and its associated configuration information at a
+ * certain point in time. This saved @ref glos_frame_object "frame object" provides fast
+ * and easy access to the audio generator node's data and configuration information.
+ *
+ * @param [out] metaData Structure to be filled with the frame object.
+ *
+ * <b>Remarks:</b>
+ *
+ * This method is central in the use of the AudioGenerator node. Once the AudioGenerator
+ * node is generating data, after each @ref conc_updating_data "'Update Data'" call,
+ * the application calls this method to get the node's frame object, which contains
+ * the data and all its associated properties.
+ */
+ inline void GetMetaData(AudioMetaData& metaData) const
+ {
+ xnGetAudioMetaData(GetHandle(), metaData.GetUnderlying());
+ }
+
+ /**
+ * @copybrief xnGetAudioBuffer
+ * For full details and usage, see @ref xnGetAudioBuffer
+ */
+ inline const XnUChar* GetAudioBuffer() const
+ {
+ return xnGetAudioBuffer(GetHandle());
+ }
+
+ /**
+ * @brief Gets the node's number of supported wave output modes.
+ */
+ inline XnUInt32 GetSupportedWaveOutputModesCount() const
+ {
+ return xnGetSupportedWaveOutputModesCount(GetHandle());
+ }
+
+ /**
+ * @brief Returns a list of the wave output modes that the @ref AudioGenerator node supports.
+ * @param [out] aSupportedModes Buffer to be filled with the list of wave output modes.
+ * @param [in,out] nCount [in] Size of the array.
+ [out] Number of modes returned.
+ */
+ inline XnStatus GetSupportedWaveOutputModes(XnWaveOutputMode* aSupportedModes, XnUInt32& nCount) const
+ {
+ return xnGetSupportedWaveOutputModes(GetHandle(), aSupportedModes, &nCount);
+ }
+
+ /**
+ * @brief Sets the current wave output mode of the AudioGenerator node. This output mode
+ * is used for generating the next audio packet.
+ *
+ * @param [in] OutputMode Mode to set as the current wave output mode.
+ *
+ * <b>Remarks</b>
+ *
+ * The wave output mode is contained in the @ref xn::XnWaveOutputMode struct. It
+ * comprises: bits per sample, channel, and sample rate.
+ */
+ inline XnStatus SetWaveOutputMode(const XnWaveOutputMode& OutputMode)
+ {
+ return xnSetWaveOutputMode(GetHandle(), &OutputMode);
+ }
+
+ /**
+ * @brief Gets the current AudioGenerator node's wave output mode. This output mode
+ * is used for generating the next audio packet.
+ *
+ * @param [out] OutputMode Current wave output mode.
+ *
+ * <b>Remarks</b>
+ *
+ * The wave output mode is contained in the XnWaveOutputMode struct. Each wave output
+ * mode comprises settings for bits per sample, channel, and sample rate, as follows:
+ */
+ inline XnStatus GetWaveOutputMode(XnWaveOutputMode& OutputMode) const
+ {
+ return xnGetWaveOutputMode(GetHandle(), &OutputMode);
+ }
+
+ /**
+ * @brief Registers an event handler for the 'Wave Output Mode Change' event.
+ *
+ * @param [in] handler Callback function to be invoked when the event is raised.
+ * @param [in] pCookie User's cookie, to be delivered to the callback.
+ * @param [out] hCallback Handle to the callback to be used for unregistering it.
+ *
+ * For full details and usage of the parameters, see @ref reg_to_events.
+ */
+ inline XnStatus RegisterToWaveOutputModeChanges(StateChangedHandler handler, void* pCookie, XnCallbackHandle& hCallback)
+ {
+ return _RegisterToStateChange(xnRegisterToWaveOutputModeChanges, GetHandle(), handler, pCookie, hCallback);
+ }
+
+ /**
+ * @brief Unregisters an event handler for the 'Wave Output Mode Change' event.
+ *
+ * @param [in] hCallback Handle received from registration.
+ *
+ * For full details and usage of the parameter, see @ref unreg_from_events .
+ */
+ inline void UnregisterFromWaveOutputModeChanges(XnCallbackHandle hCallback)
+ {
+ _UnregisterFromStateChange(xnUnregisterFromWaveOutputModeChanges, GetHandle(), hCallback);
+ }
+ };
+
+ /**
+ * @ingroup cppref_prd_func
+ * Represents a Mock Audio Generator node
+ */
+ class MockAudioGenerator : public AudioGenerator
+ {
+ public:
+ /**
+ * Ctor
+ *
+ * @param [in] hNode Node handle
+ */
+ inline MockAudioGenerator(XnNodeHandle hNode = NULL) : AudioGenerator(hNode) {}
+ inline MockAudioGenerator(const NodeWrapper& other) : AudioGenerator(other) {}
+
+ /**
+ * Creates a mock audio generator
+ *
+ * @param [in] context The context in which the node should be generated
+ * @param [in] strName Optional. The name of the new node.
+ */
+ XnStatus Create(Context& context, const XnChar* strName = NULL);
+
+ /**
+ * Creates a mock audio generator, copying the initial state from another audio
+ * generator.
+ *
+ * @param [in] other The audio generator to copy state from
+ * @param [in] strName Optional. The name of the new node.
+ */
+ XnStatus CreateBasedOn(AudioGenerator& other, const XnChar* strName = NULL);
+
+ /**
+ * @copybrief xnMockAudioSetData
+ * For full details and usage, see @ref xnMockAudioSetData
+ */
+ inline XnStatus SetData(XnUInt32 nFrameID, XnUInt64 nTimestamp, XnUInt32 nDataSize, const XnUInt8* pAudioBuffer)
+ {
+ return xnMockAudioSetData(GetHandle(), nFrameID, nTimestamp, nDataSize, pAudioBuffer);
+ }
+
+ /**
+ * Sets the data of the mock node from a meta data object, overriding frame ID and
+ * timestamp
+ *
+ * @param [in] audioMD Object to take data from
+ * @param [in] nFrameID Frame ID
+ * @param [in] nTimestamp Timestamp
+ */
+ inline XnStatus SetData(const AudioMetaData& audioMD, XnUInt32 nFrameID, XnUInt64 nTimestamp)
+ {
+ return SetData(nFrameID, nTimestamp, audioMD.DataSize(), audioMD.Data());
+ }
+
+ /**
+ * Sets the data of the mock node from a meta data object
+ *
+ * @param [in] audioMD Object to take data from
+ */
+ inline XnStatus SetData(const AudioMetaData& audioMD)
+ {
+ return SetData(audioMD, audioMD.FrameID(), audioMD.Timestamp());
+ }
+ };
+
+ /**
+ * @ingroup cppref_prd_func
+ */
+ class MockRawGenerator : public Generator
+ {
+ public:
+ MockRawGenerator(XnNodeHandle hNode = NULL) : Generator(hNode) {}
+ MockRawGenerator(const NodeWrapper& other) : Generator(other) {}
+
+ inline XnStatus Create(Context& context, const XnChar* strName = NULL);
+
+ inline XnStatus SetData(XnUInt32 nFrameID, XnUInt64 nTimestamp, XnUInt32 nDataSize, const void* pData)
+ {
+ return xnMockRawSetData(GetHandle(), nFrameID, nTimestamp, nDataSize, pData);
+ }
+
+ };
+
+ /**
+ * @ingroup cppref_prd_func
+ * Represents a Codec node.
+ */
+ class Codec : public ProductionNode
+ {
+ public:
+ /**
+ * Ctor
+ *
+ * @param [in] hNode Node handle
+ */
+ inline Codec(XnNodeHandle hNode = NULL) : ProductionNode(hNode) {}
+ inline Codec(const NodeWrapper& other) : ProductionNode(other) {}
+
+ /**
+ * @copybrief xnCreateCodec
+ * For full details and usage, see @ref xnCreateCodec
+ */
+ inline XnStatus Create(Context& context, XnCodecID codecID, ProductionNode& initializerNode);
+
+ /**
+ * @copybrief xnGetCodecID
+ * For full details and usage, see @ref xnGetCodecID
+ */
+ inline XnCodecID GetCodecID() const
+ {
+ return xnGetCodecID(GetHandle());
+ }
+
+ /**
+ * @copybrief xnEncodeData
+ * For full details and usage, see @ref xnEncodeData
+ */
+ inline XnStatus EncodeData(const void* pSrc, XnUInt32 nSrcSize, void* pDst, XnUInt32 nDstSize, XnUInt* pnBytesWritten) const
+ {
+ return xnEncodeData(GetHandle(), pSrc, nSrcSize, pDst, nDstSize, pnBytesWritten);
+ }
+
+ /**
+ * @copybrief xnDecodeData
+ * For full details and usage, see @ref xnDecodeData
+ */
+ inline XnStatus DecodeData(const void* pSrc, XnUInt32 nSrcSize, void* pDst, XnUInt32 nDstSize, XnUInt* pnBytesWritten) const
+ {
+ return xnDecodeData(GetHandle(), pSrc, nSrcSize, pDst, nDstSize, pnBytesWritten);
+ }
+ };
+
+ /**
+ * @ingroup cppref_prd_func
+ *
+ * <b>Purpose:</b> The ScriptNode object loads an XML script from a file or string,
+ * and then runs the XML script to build a production graph. It also references every
+ * node created from that script, so it wouldn't be destroyed.
+ *
+ * <b>Remarks:</b>
+ *
+ * A typical usage of a script node is:
+ * - Create the script node, using the @ref Create() method.
+ * - Load XML script from file or string, using @ref LoadScriptFromFile() or @ref LoadScriptFromString().
+ * - Execute the script, using @ref Run().
+ *
+ * Note that the context's @ref xn::Context::RunXmlScriptFromFile "RunXmlScriptFromFile()" or
+ * @ref xn::Context::RunXmlScript "RunXmlScript()" methods can be used to perform
+ * all above steps.
+
+ * All production nodes in the production graph use reference count to determine their life time,
+ * but if an application executed a script, it can't know upfront which nodes will be created
+ * by this script, and so, can't take reference to them, so those nodes might be destroyed
+ * immediately. The script node, apart from executing the script, also keeps reference to
+ * all the nodes created by the script. This means that if the script node is destroyed,
+ * every production node that was created by the script, and is unreferenced by the application
+ * will also be destroyed. For this reason, it is recommended for application using XML scripts
+ * to keep a reference to the script node as long as they keep a reference to the context itself.
+ *
+ * A single ScriptNode object is responsible for building the entire production graph,
+ * irrespective of however many node definitions there are in the XML script and how
+ * many production nodes are created.
+ *
+ * For additional information about XML scripts, see @ref xmlscripts.
+ */
+ class ScriptNode : public ProductionNode
+ {
+ public:
+ /**
+ * Ctor
+ *
+ * @param [in] hNode Node handle
+ */
+ inline ScriptNode(XnNodeHandle hNode = NULL) : ProductionNode(hNode) {}
+ inline ScriptNode(const NodeWrapper& other) : ProductionNode(other) {}
+
+ inline XnStatus Create(Context& context, const XnChar* strFormat);
+
+ inline const XnChar* GetSupportedFormat()
+ {
+ return xnScriptNodeGetSupportedFormat(GetHandle());
+ }
+
+ /**
+ * @brief Loads an XML script file into the ScriptNode object.
+ *
+ * @param [in] strFileName Name of file containing an XML script.
+ */
+ inline XnStatus LoadScriptFromFile(const XnChar* strFileName)
+ {
+ return xnLoadScriptFromFile(GetHandle(), strFileName);
+ }
+
+ /**
+ * @brief Loads an XML script string into the ScriptNode object.
+ *
+ * @param [in] strScript String containing an XML script.
+ */
+ inline XnStatus LoadScriptFromString(const XnChar* strScript)
+ {
+ return xnLoadScriptFromString(GetHandle(), strScript);
+ }
+
+ /**
+ * @brief Runs the ScriptNode object's XML script to build a production graph.
+ *
+ * @param [out] pErrors List of enumeration errors produced during method execution.
+ *
+ * <b>Remarks</b>
+ *
+ * This method causes the whole production graph to enter Generating state. To read
+ * data you have to run one of the @ref conc_updating_data "'Update Data'" methods
+ * of the Context or of the node itself.
+ */
+ inline XnStatus Run(EnumerationErrors* pErrors);
+ };
+
+ //---------------------------------------------------------------------------
+ // EnumerationErrors
+ //---------------------------------------------------------------------------
+ /**
+ * @ingroup cppref_graph_mgmt
+ * <b>Purpose:</b> An EnumerationError object returns a full list of modules that failed
+ * to enumerate specifying exactly why each module failed.
+ *
+ * <b>Usage:</b> Instantiate and pass to enumeration methods.
+ *
+ * <b>Remarks:</b>
+ *
+ * Sometimes an application enumerates for a specific node, and receives zero results.
+ * An obvious reason for this failure is that no module implementing the node type was
+ * installed. Another possible reason is that a module may be installed but has no license.
+ * Yet another possible reason is that a required hardware device is currently disconnected.
+ *
+ * Applications can use the EnumerationErrors class to acquire a full list of modules
+ * that failed to enumerate specifying for each exactly why each module failed.
+ *
+ * The methods provided by the EnumerationErrors class let the application search enumeration
+ * lists for specific types of nodes.
+ */
+ class EnumerationErrors
+ {
+ public:
+ /**
+ * Ctor
+ */
+ inline EnumerationErrors() : m_bAllocated(TRUE), m_pErrors(NULL) { xnEnumerationErrorsAllocate(&m_pErrors); }
+
+ /**
+ * Ctor
+ *
+ * @param [in] pErrors underlying C object to wrap
+ * @param [in] bOwn TRUE to own the object (i.e. free it upon destruction), FALSE
+ * otherwise.
+ */
+ inline EnumerationErrors(XnEnumerationErrors* pErrors, XnBool bOwn = FALSE) : m_bAllocated(bOwn), m_pErrors(pErrors) {}
+
+ /**
+ * Dtor
+ */
+ ~EnumerationErrors() { Free(); }
+
+ /**
+ * An iterator over enumeration errors
+ */
+ class Iterator
+ {
+ public:
+ friend class EnumerationErrors;
+
+ /**
+ * Checks if the other iterator points to the same location
+ *
+ * @param [in] other another iterator
+ */
+ XnBool operator==(const Iterator& other) const
+ {
+ return m_it == other.m_it;
+ }
+
+ /**
+ * Checks if the other iterator points to a different location
+ *
+ * @param [in] other another iterator
+ */
+ XnBool operator!=(const Iterator& other) const
+ {
+ return m_it != other.m_it;
+ }
+
+ /**
+ * Moves the iterator to the next location. If end of list was reached, iterator
+ * will be equal to @ref EnumerationErrors::End().
+ */
+ inline Iterator& operator++()
+ {
+ m_it = xnEnumerationErrorsGetNext(m_it);
+ return *this;
+ }
+
+ /**
+ * Returns an iterator to the next location. If end of list was reached, iterator
+ * will be equal to @ref EnumerationErrors::End().
+ */
+ inline Iterator operator++(int)
+ {
+ return Iterator(xnEnumerationErrorsGetNext(m_it));
+ }
+
+ /**
+ * @brief Returns the description data of the failing node the iterator points to.
+ *
+ * <b>Remarks</b>
+ *
+ * The description data returned in the @ref XnProductionNodeDescription struct
+ * includes the node name, the vendor, and the version.
+ */
+ inline const XnProductionNodeDescription& Description() { return *xnEnumerationErrorsGetCurrentDescription(m_it); }
+
+ /**
+ * @brief Returns the failure error code of the failing node the iterator points to.
+ * For a string representation of this error, call @ref xnGetStatusString().
+ */
+ inline XnStatus Error() { return xnEnumerationErrorsGetCurrentError(m_it); }
+
+ private:
+ inline Iterator(XnEnumerationErrorsIterator it) : m_it(it) {}
+
+ XnEnumerationErrorsIterator m_it;
+ };
+
+ /**
+ * @brief Gets an iterator to the first item in an enumeration errors list.
+ *
+ * <b>Remarks</b>
+ *
+ * To access the contents of the error item, either use the @ref ToString() method
+ * of this class or the methods of the @ref EnumerationErrors::Iterator class.
+ */
+ inline Iterator Begin() const { return Iterator(xnEnumerationErrorsGetFirst(m_pErrors)); }
+
+ /**
+ * @brief Returns an iterator referring to the past-the-end element in an enumeration errors list.
+ * This iterator does not point to an actual item.
+ *
+ * <b>Remarks</b>
+ *
+ * Use this as the sentinel for flagging the end of a list when searching.
+ */
+ inline Iterator End() const { return Iterator(NULL); }
+
+ /**
+ * @brief Returns a string representation of the Enumeration Errors object. The string
+ * contains a full list of the modules that failed the most recent enumeration operation.
+ * For each failed module, the Enumeration Errors object specifies why exactly the module failed.
+ *
+ * @param [in] csBuffer Character buffer to be filled.
+ * @param [in] nSize Size of the character buffer.
+ */
+ inline XnStatus ToString(XnChar* csBuffer, XnUInt32 nSize)
+ {
+ return xnEnumerationErrorsToString(m_pErrors, csBuffer, nSize);
+ }
+
+ /**
+ * @copybrief xnEnumerationErrorsFree
+ * For full details and usage, see @ref xnEnumerationErrorsFree
+ */
+ inline void Free()
+ {
+ if (m_bAllocated)
+ {
+ xnEnumerationErrorsFree(m_pErrors);
+ m_pErrors = NULL;
+ m_bAllocated = FALSE;
+ }
+ }
+
+ /**
+ * Gets the underlying C object
+ */
+ inline XnEnumerationErrors* GetUnderlying() { return m_pErrors; }
+
+ private:
+ XnEnumerationErrors* m_pErrors;
+ XnBool m_bAllocated;
+ };
+
+ //---------------------------------------------------------------------------
+ // Context
+ //---------------------------------------------------------------------------
+
+ /**
+ * @ingroup cppref_graph_mgmt
+ *
+ * A context is a workspace where the application builds an OpenNI production graph.
+ * It contains methods for managing the production graph.
+ *
+ * In order to use any of the OpenNI functionality you must first construct a Context
+ * object and initialize it. Prior to this, the application cannot do anything with
+ * OpenNI.
+ *
+ * For a comprehensive overview to the Context class and its members, see @ref conc_context
+ * "Overview to Contexts".
+ *
+ * @section context_global_error_event Event: 'Global Error State Change'
+ *
+ * Signals that the error state of any of the nodes has changed.
+ *
+ * This event can be used by the application to get a signal as soon as any error occurs
+ * in one of the production nodes. The global error state aggregates error state from all
+ * the production nodes in the context.
+ *
+ * Use @ref RegisterToErrorStateChange() and @ref UnregisterFromErrorStateChange() for using this event.
+ *
+ * @section context_node_creation_event Event: 'Node Creation'
+ *
+ * Signals that a new node was created in the context production graph.
+ *
+ * Use @ref RegisterToNodeCreation() and @ref UnregisterFromNodeCreation() for using this event.
+ *
+ * @section context_node_destruction_event Event: 'Node Destruction'
+ *
+ * Signals that a node was removed from the context production graph, and destroyed.
+ *
+ * Use @ref RegisterToNodeDestruction() and @ref UnregisterFromNodeDestruction() for using this event.
+ */
+ class Context
+ {
+ public:
+ /**
+ * Callback prototype for the @ref context_node_creation_event "'Node Creation'" event handler.
+ *
+ * @param [in] context The context that raised this event.
+ * @param [in] createdNode The id of the hand that disappeared.
+ * @param [in] pCookie A user-provided cookie that was given when registering to
+ * this event.
+ *
+ * Example for such a handler:
+ @code
+ void XN_CALLBACK_TYPE OnNodeCreation(Context& context, ProductionNode& createdNode, void* pCookie)
+ {}
+ @endcode
+ */
+ typedef void (XN_CALLBACK_TYPE* NodeCreationHandler)(Context& context, ProductionNode& createdNode, void* pCookie);
+
+ /**
+ * Callback prototype for the @ref context_node_destruction_event "'Node Destruction'" event handler.
+ *
+ * @param [in] context The context that raised this event.
+ * @param [in] strDestroyedNodeName The name of the node that was destroyed.
+ * @param [in] pCookie A user-provided cookie that was given when registering to
+ * this event.
+ *
+ * Example for such a handler:
+ @code
+ void XN_CALLBACK_TYPE OnNodeDestruction(Context& context, const XnChar* strDestroyedNodeName, void* pCookie)
+ {}
+ @endcode
+ */
+ typedef void (XN_CALLBACK_TYPE* NodeDestructionHandler)(Context& context, const XnChar* strDestroyedNodeName, void* pCookie);
+
+ /**
+ * Ctor
+ */
+ inline Context() : m_pContext(NULL), m_bUsingDeprecatedAPI(FALSE), m_bAllocated(FALSE), m_hShuttingDownCallback(NULL) {}
+
+ /**
+ * Ctor
+ *
+ * @param [in] pContext Underlying C object
+ */
+ inline Context(XnContext* pContext) : m_pContext(NULL), m_bUsingDeprecatedAPI(FALSE), m_bAllocated(FALSE), m_hShuttingDownCallback(NULL)
+ {
+ SetHandle(pContext);
+ }
+
+ /**
+ * Copy Ctor
+ *
+ * @param [in] other Another context. Note that the context will only be destroyed
+ * when the original object is destroyed.
+ */
+ inline Context(const Context& other) : m_pContext(NULL), m_bUsingDeprecatedAPI(FALSE), m_bAllocated(FALSE), m_hShuttingDownCallback(NULL)
+ {
+ SetHandle(other.m_pContext);
+ }
+
+ /**
+ * Dtor
+ */
+ ~Context()
+ {
+ SetHandle(NULL);
+ }
+
+ inline Context& operator=(const Context& other)
+ {
+ SetHandle(other.m_pContext);
+ return *this;
+ }
+
+ /**
+ * Gets the underlying C object
+ */
+ inline XnContext* GetUnderlyingObject() const { return m_pContext; }
+
+ /**
+ * Checks if two context objects are references to the same context.
+ *
+ * @param [in] other Another object
+ */
+ inline XnBool operator==(const Context& other)
+ {
+ return (GetUnderlyingObject() == other.GetUnderlyingObject());
+ }
+
+ /**
+ * Checks if two context objects are <i>not</i> references to the same context.
+ *
+ * @param [in] other Another object
+ */
+ inline XnBool operator!=(const Context& other)
+ {
+ return (GetUnderlyingObject() != other.GetUnderlyingObject());
+ }
+
+ /**
+ * @brief Builds the context's general software environment.
+ *
+ * This method initializes runtime variables and data structures, and examines all
+ * registered plug-ins to learn the purpose and specific capabilities of each. In
+ * particular, during initialization the context initialization examines all registered
+ * plug-ins to learn the purpose and specific capabilities of each. For example,
+ * one plug-in is for creating a skeleton node, and another plug-in is for creating
+ * a depth node. Thus an entire database is built of plug-ins that can be queried
+ * according to vendor, model, and capabilities of each.
+ *
+ * Once you have completed the initialization you can create nodes that are based
+ * on the plug-ins that OpenNI has discovered by this initialization process.
+ */
+ inline XnStatus Init()
+ {
+ XnContext* pContext = NULL;
+ XnStatus nRetVal = xnInit(&pContext);
+ XN_IS_STATUS_OK(nRetVal);
+
+ TakeOwnership(pContext);
+ m_bAllocated = TRUE;
+
+ return (XN_STATUS_OK);
+ }
+
+ /**
+ * @brief Runs an XML script string to build a production graph.
+ *
+ * @param [in] strScript String containing an XML script.
+ * @param [out] scriptNode @ref xn::ScriptNode object as the root to all the nodes
+ * created from the XML file. When no longer needed, the node can
+ * be released, causing all the created nodes to decrement their reference counts.
+ * @param [in,out] pErrors Optional. To be filled with enumeration errors.
+ *
+ * <B>Remarks:</B>
+ *
+ * For a full description of the XML structure, see @ref xmlscripts.
+ * Compare this method with initialization methods that run an XML script from a
+ * file.
+ */
+ inline XnStatus RunXmlScript(const XnChar* strScript, ScriptNode& scriptNode, EnumerationErrors* pErrors = NULL)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ XnNodeHandle hScriptNode;
+ nRetVal = xnContextRunXmlScriptEx(m_pContext, strScript, pErrors == NULL ? NULL : pErrors->GetUnderlying(), &hScriptNode);
+ XN_IS_STATUS_OK(nRetVal);
+
+ scriptNode.TakeOwnership(hScriptNode);
+
+ return (XN_STATUS_OK);
+ }
+
+ /**
+ * @brief Runs an XML script file to build a production graph.
+ *
+ * @param [in] strFileName Name of file containing an XML script.
+ * @param [out] scriptNode scriptNode object as the root to all the nodes created
+ * from the XML file. When no longer needed, the node can
+ * be released, causing all the created nodes to decrement
+ * their reference counts.
+ * @param [in,out] pErrors Optional. To be filled with enumeration errors.
+ *
+ * <B>Remarks:</B>
+ *
+ * The XML script file describes all the nodes you want to create. For each node
+ * description in the XML file, this method creates a @ref xn::ProductionNode object.
+ */
+ inline XnStatus RunXmlScriptFromFile(const XnChar* strFileName, ScriptNode& scriptNode, EnumerationErrors* pErrors = NULL)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ XnNodeHandle hScriptNode;
+ nRetVal = xnContextRunXmlScriptFromFileEx(m_pContext, strFileName, pErrors == NULL ? NULL : pErrors->GetUnderlying(), &hScriptNode);
+ XN_IS_STATUS_OK(nRetVal);
+
+ scriptNode.TakeOwnership(hScriptNode);
+
+ return (XN_STATUS_OK);
+ }
+
+ /**
+ * @brief Shorthand combination of two other initialization methods - @ref Init() and then @ref RunXmlScriptFromFile() -
+ * to initialize the context object and then create a production graph.
+ *
+ * @param [in] strFileName Name of file containing an XML script.
+ * @param [out] scriptNode ScriptNode object as the root to all the nodes created
+ * from the XML file. When no longer needed, the node can be
+ * released, causing all the created nodes to decrement their reference counts.
+ * @param [out] pErrors Optional. To be filled with enumeration errors.
+ *
+ * <B>Remarks:</B>
+ *
+ * The XML script file describes all the nodes you want to create. For each node
+ * description in the XML file, this method creates a @ref xn::ProductionNode object.
+ */
+ inline XnStatus InitFromXmlFile(const XnChar* strFileName, ScriptNode& scriptNode, EnumerationErrors* pErrors = NULL)
+ {
+ XnContext* pContext = NULL;
+
+ XnNodeHandle hScriptNode;
+ XnStatus nRetVal = xnInitFromXmlFileEx(strFileName, &pContext, pErrors == NULL ? NULL : pErrors->GetUnderlying(), &hScriptNode);
+ XN_IS_STATUS_OK(nRetVal);
+
+ scriptNode.TakeOwnership(hScriptNode);
+ TakeOwnership(pContext);
+ m_bAllocated = TRUE;
+
+ return (XN_STATUS_OK);
+ }
+
+ /**
+ * @brief Recreates a production graph from a recorded ONI file and then replays the data
+ * generation exactly as it was recorded.
+ *
+ * @param [in] strFileName Name of the recorded file to be run.
+ * @param [out] playerNode Returns a @ref xn::Player object through which
+ * playback can be controlled, e.g., seeking and setting playback speed.
+ *
+ * <B>Remarks:</B>
+ *
+ * OpenNI provides great flexibility of recording. You can decide you want to record
+ * only the final output, e.g., just a skeleton in movement; or record both the
+ * output skeleton and the depth input; or record only the depth input and then
+ * recreate the skeleton at run-time after reading the recorded raw depth data.
+ * You can also choose which nodes to record.
+ */
+ inline XnStatus OpenFileRecording(const XnChar* strFileName, ProductionNode& playerNode)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ XnNodeHandle hPlayer;
+ nRetVal = xnContextOpenFileRecordingEx(m_pContext, strFileName, &hPlayer);
+ XN_IS_STATUS_OK(nRetVal);
+
+ playerNode.TakeOwnership(hPlayer);
+
+ return (XN_STATUS_OK);
+ }
+
+ /**
+ * @copybrief xnCreateMockNode
+ * For full details and usage, see @ref xnCreateMockNode
+ */
+ inline XnStatus CreateMockNode(XnProductionNodeType type, const XnChar* strName, ProductionNode& mockNode)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ XnNodeHandle hMockNode;
+ nRetVal = xnCreateMockNode(m_pContext, type, strName, &hMockNode);
+ XN_IS_STATUS_OK(nRetVal);
+
+ mockNode.TakeOwnership(hMockNode);
+
+ return (XN_STATUS_OK);
+ }
+
+ /**
+ * @copybrief xnCreateMockNodeBasedOn
+ * For full details and usage, see @ref xnCreateMockNodeBasedOn
+ */
+ inline XnStatus CreateMockNodeBasedOn(ProductionNode& originalNode, const XnChar* strName, ProductionNode& mockNode)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ XnNodeHandle hMockNode;
+ nRetVal = xnCreateMockNodeBasedOn(m_pContext, originalNode, strName, &hMockNode);
+ XN_IS_STATUS_OK(nRetVal);
+
+ mockNode.TakeOwnership(hMockNode);
+
+ return (XN_STATUS_OK);
+ }
+
+ /**
+ * @copybrief xnCreateCodec
+ * For full details and usage, see @ref xnCreateCodec
+ */
+ inline XnStatus CreateCodec(XnCodecID codecID, ProductionNode& initializerNode, Codec& codec)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ XnNodeHandle hCodec;
+ nRetVal = xnCreateCodec(m_pContext, codecID, initializerNode.GetHandle(), &hCodec);
+ XN_IS_STATUS_OK(nRetVal);
+
+ codec.TakeOwnership(hCodec);
+
+ return (XN_STATUS_OK);
+ }
+
+ /**
+ * @copybrief xnContextAddRef
+ * For full details and usage, see @ref xnContextAddRef
+ */
+ inline XnStatus AddRef()
+ {
+ return xnContextAddRef(m_pContext);
+ }
+
+ /**
+ * @copybrief xnContextRelease
+ * For full details and usage, see @ref xnContextRelease
+ */
+ inline void Release()
+ {
+ SetHandle(NULL);
+ }
+
+
+ /**
+ * @copybrief xnAddLicense
+ * For full details and usage, see @ref xnAddLicense
+ */
+ inline XnStatus AddLicense(const XnLicense& License)
+ {
+ return xnAddLicense(m_pContext, &License);
+ }
+
+ /**
+ * @copybrief xnEnumerateLicenses
+ * For full details and usage, see @ref xnEnumerateLicenses
+ */
+ inline XnStatus EnumerateLicenses(XnLicense*& aLicenses, XnUInt32& nCount) const
+ {
+ return xnEnumerateLicenses(m_pContext, &aLicenses, &nCount);
+ }
+
+ /**
+ * @copybrief xnFreeLicensesList
+ * For full details and usage, see @ref xnFreeLicensesList
+ */
+ inline static void FreeLicensesList(XnLicense aLicenses[])
+ {
+ xnFreeLicensesList(aLicenses);
+ }
+
+ /**
+ * @brief Enumerates all available production nodes for a specific node type (e.g., the application wants to create a
+ * depth generator node) and returns a full list of matching production nodes.
+ *
+ * @param [in] Type Requested node type.
+ * @param [in] pQuery Optional. A query object that can be used to filter results.
+ * @param [out] TreesList List of possible production nodes.
+ * @param [out] pErrors Optional. To contain enumeration errors.
+ *
+ * <B>Remarks:</B>
+ *
+ * The application chooses one of the nodes from the node list returned by this method and uses it as input
+ * to the @ref xn::Context::CreateProductionTree() method to create a new production node.
+ *
+ * Using this method to help create a production node offers the greatest flexibility since it returns a
+ * complete list of matching production nodes and so the application can then choose the most suitable node.
+ *
+ * By contrast, using @ref xn::Context::CreateAnyProductionTree() "CreateAnyProductionTree()" or a node's <b>Create()</b>
+ * method creates a node from the first matching node that satisfies the query.
+ */
+ XnStatus EnumerateProductionTrees(XnProductionNodeType Type, const Query* pQuery, NodeInfoList& TreesList, EnumerationErrors* pErrors = NULL) const
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ const XnNodeQuery* pInternalQuery = (pQuery != NULL) ? pQuery->GetUnderlyingObject() : NULL;
+
+ XnNodeInfoList* pList = NULL;
+ nRetVal = xnEnumerateProductionTrees(m_pContext, Type, pInternalQuery, &pList, pErrors == NULL ? NULL : pErrors->GetUnderlying());
+ XN_IS_STATUS_OK(nRetVal);
+
+ TreesList.ReplaceUnderlyingObject(pList);
+
+ return (XN_STATUS_OK);
+ }
+
+ /**
+ * @brief Enumerates for production nodes of a specific node type, and creates the first
+ * production node found of that type.
+ *
+ * @param [in] type Requested node type.
+ * @param [in] pQuery Optional. A query object that can be used to filter results.
+ * @param [out] node Handle to the newly created node.
+ * @param [in,out] pErrors Optional. To contain enumeration errors.
+ *
+ * <B>Remarks:</B>
+ *
+ * This method is a 'shortcut' version of using the @ref EnumerateProductionTrees()
+ * method and then passing the first result to @ref CreateProductionTree().
+ * Thus, this method is exactly like the <b>Create()</b> method for nodes.
+ *
+ * Other ways of creating a production graph let the application retrieve a complete
+ * list of alternatives and then choose the most appropriate alternative.
+ *
+ * This method is the method used by the above XML script methods to create the
+ * ProductionNode objects. The XML method runs the XML script, and for each node
+ * description the XML method runs this function to create that node.
+ *
+ * Using this function is called 'creating a node from the context'. You can also
+ * create a node by invoking the <b>Create</b> method of the node itself, e.g.,
+ * the @ref xn::HandsGenerator::Create "Create()" method of a @ref xn::HandsGenerator
+ * "HandsGenerator" node.
+ *
+ * By default, this method does not enable the production nodes to start generating
+ * data immediately on creation.
+ *
+ * @sa @ref create_method for more detail.
+ */
+ XnStatus CreateAnyProductionTree(XnProductionNodeType type, Query* pQuery, ProductionNode& node, EnumerationErrors* pErrors = NULL)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ XnNodeQuery* pInternalQuery = (pQuery != NULL) ? pQuery->GetUnderlyingObject() : NULL;
+
+ XnNodeHandle hNode;
+ nRetVal = xnCreateAnyProductionTree(m_pContext, type, pInternalQuery, &hNode, pErrors == NULL ? NULL : pErrors->GetUnderlying());
+ XN_IS_STATUS_OK(nRetVal);
+
+ node.TakeOwnership(hNode);
+
+ return (XN_STATUS_OK);
+ }
+
+ /**
+ * @brief Creates a production node from the information supplied in a @ref xn::NodeInfo object.
+ *
+ * @param [in] Tree Node properties for creating the new node.
+ * @param [out] node Reference to the new @ref xn::ProductionNode object.
+ *
+ * <B>Remarks:</B>
+ *
+ * The application gets the NodeInfo object by choosing it from the list returned
+ * by the @ref xn::Context::EnumerateProductionTrees() method.
+ *
+ * If the new production node requires additional nodes for its input, and those
+ * nodes do not yet exist, then this method creates those additional nodes also
+ * and associates them with the "original" new production node.
+ *
+ */
+ XnStatus CreateProductionTree(NodeInfo& Tree, ProductionNode& node)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ XnNodeHandle hNode;
+ nRetVal = xnCreateProductionTree(m_pContext, Tree, &hNode);
+ XN_IS_STATUS_OK(nRetVal);
+
+ node.TakeOwnership(hNode);
+
+ return (XN_STATUS_OK);
+ }
+
+ /**
+ * @brief Returns a list of all the context's existing created nodes.
+ *
+ * @param [out] list List of the context's existing created nodes.
+ *
+ * You can use the @ref xn::NodeInfoList::FilterList() method to filter the returned
+ * list of existing nodes.
+ */
+ XnStatus EnumerateExistingNodes(NodeInfoList& list) const
+ {
+ XnNodeInfoList* pList;
+ XnStatus nRetVal = xnEnumerateExistingNodes(m_pContext, &pList);
+ XN_IS_STATUS_OK(nRetVal);
+
+ list.ReplaceUnderlyingObject(pList);
+
+ return (XN_STATUS_OK);
+ }
+
+ /**
+ * @brief Returns a list of the context's existing created nodes filtered by type.
+ *
+ * @param [in] list List of the context's existing created nodes.
+ * @param [in] type Type to enumerate for.
+ *
+ * <B>Remarks</B>
+ *
+ * Returns the list after filtering them by type, so it returns a list of the created
+ * nodes of the specific type only.
+ *
+ * An example of a typical case of returning a list of two nodes of the same type
+ * is where there are two sensors in a 3D set-up and you need to retrieve the corresponding
+ * two depth nodes to generate data from them.
+ *
+ * You can use the @ref xn::NodeInfoList::FilterList() method to filter the returned
+ * list of existing nodes.
+ */
+ XnStatus EnumerateExistingNodes(NodeInfoList& list, XnProductionNodeType type) const
+ {
+ XnNodeInfoList* pList;
+ XnStatus nRetVal = xnEnumerateExistingNodesByType(m_pContext, type, &pList);
+ XN_IS_STATUS_OK(nRetVal);
+
+ list.ReplaceUnderlyingObject(pList);
+
+ return (XN_STATUS_OK);
+ }
+
+ /**
+ * @brief Searches for an existing created node of a specified type and returns a reference to it.
+ *
+ * @param [in] type Type of node to search for.
+ * @param [out] node Reference to an existing created node that was found.
+ *
+ * <B>Remarks</B>
+ *
+ * This method returns only the first node it finds; this method does not return
+ * the entire list of matching nodes. Compare this with the @ref xn::Context::EnumerateExistingNodes()
+ * method, which returns the entire list of matching nodes.
+ * A typical usage is that the application already created all the nodes from XML.
+ * Then, when it needs to start generating data from a particular node, e.g., the
+ * skeleton data, it will call FindExistingNode specifying the skeleton type, and
+ * it will get it and start using it.
+ *
+ * This method does not provide a query parameter (compare with @ref xn::Context::EnumerateExistingNodes).
+ */
+ XnStatus FindExistingNode(XnProductionNodeType type, ProductionNode& node) const
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ XnNodeHandle hNode;
+ nRetVal = xnFindExistingRefNodeByType(m_pContext, type, &hNode);
+ XN_IS_STATUS_OK(nRetVal);
+
+ node.TakeOwnership(hNode);
+
+ return (XN_STATUS_OK);
+ }
+
+ /**
+ * @copybrief xnGetNodeHandleByName
+ * For full details and usage, see @ref xnGetNodeHandleByName
+ */
+ XnStatus GetProductionNodeByName(const XnChar* strInstanceName, ProductionNode& node) const
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ XnNodeHandle hNode;
+ nRetVal = xnGetRefNodeHandleByName(m_pContext, strInstanceName, &hNode);
+ XN_IS_STATUS_OK(nRetVal);
+
+ node.TakeOwnership(hNode);
+
+ return (XN_STATUS_OK);
+ }
+
+ /**
+ * @copybrief xnGetNodeHandleByName
+ * For full details and usage, see @ref xnGetNodeHandleByName
+ */
+ XnStatus GetProductionNodeInfoByName(const XnChar* strInstanceName, NodeInfo& nodeInfo) const
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ XnNodeHandle hNode;
+ nRetVal = xnGetRefNodeHandleByName(m_pContext, strInstanceName, &hNode);
+ XN_IS_STATUS_OK(nRetVal);
+
+ xnProductionNodeRelease(hNode);
+
+ nodeInfo = NodeInfo(xnGetNodeInfo(hNode));
+
+ return (XN_STATUS_OK);
+ }
+
+ /**
+ * @brief Ensures all created @ref dict_gen_node "generator nodes" are generating data.
+ *
+ */
+ inline XnStatus StartGeneratingAll()
+ {
+ return xnStartGeneratingAll(m_pContext);
+ }
+
+ /**
+ * @brief Ensures all @ref dict_gen_node "generator nodes" are not generating data.
+ */
+ inline XnStatus StopGeneratingAll()
+ {
+ return xnStopGeneratingAll(m_pContext);
+ }
+
+ /**
+ * @brief Enables/disables the GlobalMirror flag.
+ *
+ * @param [in] bMirror New mirroring state.
+ *
+ * <B>Remarks:</B>
+ *
+ * See @ref conc_global_mirror for understanding of the 'Global Mirror' concept.
+ */
+ inline XnStatus SetGlobalMirror(XnBool bMirror)
+ {
+ return xnSetGlobalMirror(m_pContext, bMirror);
+ }
+
+ /**
+ * @brief Gets the current state of the GlobalMirror flag.
+ *
+ */
+ inline XnBool GetGlobalMirror()
+ {
+ return xnGetGlobalMirror(m_pContext);
+ }
+
+ /**
+ * @copybrief xnGetGlobalErrorState
+ * For full details and usage, see @ref xnGetGlobalErrorState
+ */
+ inline XnStatus GetGlobalErrorState()
+ {
+ return xnGetGlobalErrorState(m_pContext);
+ }
+
+ /**
+ * @brief Registers an event handler for the 'Global Error State Change' event.
+ *
+ * @param [in] handler Callback function to be invoked when the event is raised.
+ * @param [in] pCookie User's cookie, to be delivered to the callback.
+ * @param [out] hCallback Handle to the callback to be used for unregistering it.
+ *
+ * For full details and usage of the parameters, see @ref reg_to_events.
+ */
+ inline XnStatus RegisterToErrorStateChange(XnErrorStateChangedHandler handler, void* pCookie, XnCallbackHandle& hCallback)
+ {
+ return xnRegisterToGlobalErrorStateChange(m_pContext, handler, pCookie, &hCallback);
+ }
+
+ /**
+ * @brief Unregisters an event handler for the 'Global Error State Change' event.
+ *
+ * @param [in] hCallback Handle received from registration.
+ *
+ * For full details and usage of the parameter, see @ref unreg_from_events .
+ */
+ inline void UnregisterFromErrorStateChange(XnCallbackHandle hCallback)
+ {
+ xnUnregisterFromGlobalErrorStateChange(m_pContext, hCallback);
+ }
+
+ /**
+ * @brief Registers an event handler for the 'Node Creation' event. see @ref context_node_creation_event.
+ *
+ * @param [in] handler Callback function to be invoked when the event is raised.
+ * @param [in] pCookie User's cookie, to be delivered to the callback.
+ * @param [out] hCallback Handle to the callback to be used for unregistering it.
+ *
+ * For full details and usage of the parameters, see @ref reg_to_events.
+ */
+ inline XnStatus RegisterToNodeCreation(NodeCreationHandler handler, void* pCookie, XnCallbackHandle& hCallback)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ NodeCreationCookie* pCreationCookie;
+ XN_VALIDATE_ALLOC(pCreationCookie, NodeCreationCookie);
+ pCreationCookie->pFunc = handler;
+ pCreationCookie->pCookie = pCookie;
+
+ nRetVal = xnRegisterToNodeCreation(m_pContext, NodeCreationCallback, pCreationCookie, &pCreationCookie->hUnderlyingCallback);
+ XN_IS_STATUS_OK(nRetVal);
+
+ hCallback = pCreationCookie;
+
+ return XN_STATUS_OK;
+ }
+
+ /**
+ * @brief Unregisters an event handler for the 'Node Creation' event. see @ref context_node_creation_event.
+ *
+ * @param [in] hCallback Handle received from registration.
+ *
+ * For full details and usage of the parameter, see @ref unreg_from_events.
+ */
+ inline void UnregisterFromNodeCreation(XnCallbackHandle hCallback)
+ {
+ NodeCreationCookie* pCreationCookie = (NodeCreationCookie*)hCallback;
+ xnUnregisterFromNodeCreation(m_pContext, pCreationCookie->hUnderlyingCallback);
+ xnOSFree(pCreationCookie);
+ }
+
+ /**
+ * @brief Registers an event handler for the 'Node Destruction' event. see @ref context_node_destruction_event.
+ *
+ * @param [in] handler Callback function to be invoked when the event is raised.
+ * @param [in] pCookie User's cookie, to be delivered to the callback.
+ * @param [out] hCallback Handle to the callback to be used for unregistering it.
+ *
+ * For full details and usage of the parameters, see @ref reg_to_events.
+ */
+ inline XnStatus RegisterToNodeDestruction(NodeDestructionHandler handler, void* pCookie, XnCallbackHandle& hCallback)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ NodeDestructionCookie* pDestructionCookie;
+ XN_VALIDATE_ALLOC(pDestructionCookie, NodeDestructionCookie);
+ pDestructionCookie->pFunc = handler;
+ pDestructionCookie->pCookie = pCookie;
+
+ nRetVal = xnRegisterToNodeDestruction(m_pContext, NodeDestructionCallback, pDestructionCookie, &pDestructionCookie->hUnderlyingCallback);
+ XN_IS_STATUS_OK(nRetVal);
+
+ hCallback = pDestructionCookie;
+
+ return XN_STATUS_OK;
+ }
+
+ /**
+ * @brief Unregisters an event handler for the 'Node Destruction' event. see @ref context_node_destruction_event.
+ *
+ * @param [in] hCallback Handle received from registration.
+ *
+ * For full details and usage of the parameter, see @ref unreg_from_events.
+ */
+ inline void UnregisterFromNodeDestruction(XnCallbackHandle hCallback)
+ {
+ NodeDestructionCookie* pDestructionCookie = (NodeDestructionCookie*)hCallback;
+ xnUnregisterFromNodeDestruction(m_pContext, pDestructionCookie->hUnderlyingCallback);
+ xnOSFree(pDestructionCookie);
+ }
+
+ /**
+ * @brief Updates all generator nodes in the context to their latest available data,
+ * first waiting for all nodes to have new data available.
+ *
+ * <b>Remarks</b>
+ *
+ * This method requests from OpenNI to cause all nodes in the context's Production
+ * Graph that have new data available to update their application buffers with the
+ * new data, each node updating its own application buffer.
+ *
+ * Before OpenNI causes the data updates, it waits until @b all the nodes have notified
+ * that they have new data available. On receiving all the 'new data available'
+ * notifications, OpenNI then causes all nodes with new data available to update
+ * their application buffers with their new data. At this stage the generator nodes
+ * have "generated" new data. This method then stops waiting and returns a success
+ * status. The application can now read the newly generated data.
+ *
+ * @note Using this method is not recommended for most applications since it requires
+ * <i>all</i> the nodes to have new data. Consider instead using @ref WaitAnyUpdateAll()
+ * or @ref WaitOneUpdateAll(). Typical applications use the WaitAnyUpdateAll()
+ * method.
+ *
+ * An error situation is defined as: after a preset timeout, not all nodes have
+ * yet notified OpenNI they have new data available. On error, the method stops
+ * waiting and returns an error status. None of the nodes update their application
+ * buffers.
+ *
+ * See @ref conc_updating_data__summary_of_wait_fns for an overview to the @ref
+ * conc_updating_data "'WaitXUpdateAll'" methods and how to read the data from the
+ * nodes.
+ *
+ * @retval XN_STATUS_WAIT_DATA_TIMEOUT No new data available within 2 seconds.
+ */
+ inline XnStatus WaitAndUpdateAll()
+ {
+ return xnWaitAndUpdateAll(m_pContext);
+ }
+
+ /**
+ * @brief Updates all generator nodes in the context to their latest available data,
+ * first waiting for any of the nodes to have new data available.
+ *
+ * @note Typical applications use this method. Consider using this method for your
+ * application.
+ *
+ * <b>Remarks</b>
+ *
+ * This method requests from OpenNI to cause all nodes with new data available in
+ * the context's Production Graph to update their application buffers with the new
+ * data, each node updating its own application buffer.
+ *
+ * Before OpenNI causes the data updates, it waits for any of the nodes to have
+ * notified that it has new data available. On receiving a 'new data available'
+ * notification, OpenNI then causes all nodes with new data available to update
+ * their application buffers with their new data. At this stage the generator nodes
+ * have "generated" new data. This method then stops waiting and returns a success
+ * status. The application can now read the newly generated data.
+ *
+ * A node that does not have new data available does not update its application
+ * buffer.
+ *
+ * An error situation is defined as: after a preset timeout, none of the nodes have
+ * yet notified OpenNI they have new data available. On error, the method stops
+ * waiting and returns an error status. None of the nodes update their application
+ * buffers.
+ *
+ * See @ref conc_updating_data__summary_of_wait_fns for an overview to the @ref
+ * conc_updating_data "'WaitXUpdateAll'" methods and how to read the data from the
+ * nodes.
+ *
+ * @retval XN_STATUS_WAIT_DATA_TIMEOUT No new data available within 2 seconds.
+ */
+ inline XnStatus WaitAnyUpdateAll()
+ {
+ return xnWaitAnyUpdateAll(m_pContext);
+ }
+
+ /**
+ * @brief Updates all generator nodes in the context to their latest available data, first waiting for a specified node to have new data available.
+ *
+ * <b>Remarks</b>
+ *
+ * This method requests from OpenNI to cause all nodes in the context's Production
+ * Graph with new data available to update their application buffers with the new
+ * data, each node updating its own application buffer.
+ *
+ * Before OpenNI causes the data updates, it waits for a specified node to notify
+ * that it has new data available. On receiving the 'new data available' notification,
+ * OpenNI then causes all nodes with new data available to update their application
+ * buffers with their new data. At this stage the generator nodes have "generated"
+ * new data. This method then stops waiting and returns a success status. The application
+ * can now read the newly generated data.
+ *
+ * A node that does not have new data available does not update its application
+ * buffer.
+ *
+ * An error situation is defined as: after a preset timeout, none of the nodes have
+ * yet notified OpenNI they have has new data available. On error, the method stops
+ * waiting and returns an error status. None of the nodes update their application
+ * buffers.
+ *
+ * See @ref conc_updating_data__summary_of_wait_fns for an overview to the @ref
+ * conc_updating_data "'WaitXUpdateAll'" methods and how to read the data from the
+ * nodes.
+ *
+ * @retval XN_STATUS_WAIT_DATA_TIMEOUT No new data available within 2 seconds.
+ */
+ inline XnStatus WaitOneUpdateAll(ProductionNode& node)
+ {
+ return xnWaitOneUpdateAll(m_pContext, node.GetHandle());
+ }
+
+ /**
+ * @brief Immediately updates all generator nodes in the context to their latest available data, without waiting for notification that any node has new data available.
+ *
+ * <b>Remarks</b>
+ *
+ * This method requests from OpenNI to cause all nodes in the context's Production
+ * Graph with new data available to update their application buffers with the new
+ * data, each node updating its own application buffer.
+ *
+ * OpenNI causes all nodes with new data available to update their application buffers
+ * with their new data. At this stage the generator nodes have "generated" new data.
+ * This method returns a success status. The application can now read the newly
+ * generated data.
+ *
+ * A node that does not have new data available does not update its application
+ * buffer.
+ *
+ * See @ref conc_updating_data__summary_of_wait_fns for an overview to the @ref
+ * conc_updating_data "'WaitXUpdateAll'" methods and how to read the data from the
+ * nodes.
+ */
+ inline XnStatus WaitNoneUpdateAll()
+ {
+ return xnWaitNoneUpdateAll(m_pContext);
+ }
+
+ /**
+ * @copybrief xnAutoEnumerateOverSingleInput
+ * For full details and usage, see @ref xnAutoEnumerateOverSingleInput
+ */
+ inline XnStatus AutoEnumerateOverSingleInput(NodeInfoList& List, XnProductionNodeDescription& description, const XnChar* strCreationInfo, XnProductionNodeType InputType, EnumerationErrors* pErrors, Query* pQuery = NULL) const
+ {
+ return xnAutoEnumerateOverSingleInput(m_pContext, List.GetUnderlyingObject(), &description, strCreationInfo, InputType, pErrors == NULL ? NULL : pErrors->GetUnderlying(), pQuery == NULL ? NULL : pQuery->GetUnderlyingObject());
+ }
+
+ /**
+ * Replaces the underlying C object pointed to by this object.
+ */
+ inline void SetHandle(XnContext* pContext)
+ {
+ if (m_pContext == pContext)
+ {
+ return;
+ }
+
+ if (m_pContext != NULL)
+ {
+ if (m_bUsingDeprecatedAPI && m_bAllocated)
+ {
+ // Backwards compatibility: call shutdown instead of release, to make old programs get the
+ // exact same behavior they used to have.
+ xnForceShutdown(m_pContext);
+ }
+ else
+ {
+ xnContextUnregisterFromShutdown(m_pContext, m_hShuttingDownCallback);
+ xnContextRelease(m_pContext);
+ }
+ }
+
+ if (pContext != NULL)
+ {
+ XnStatus nRetVal = xnContextAddRef(pContext);
+ XN_ASSERT(nRetVal == XN_STATUS_OK);
+ XN_REFERENCE_VARIABLE(nRetVal);
+
+ nRetVal = xnContextRegisterForShutdown(pContext, ContextShuttingDownCallback, this, &m_hShuttingDownCallback);
+ XN_ASSERT(nRetVal == XN_STATUS_OK);
+ }
+
+ m_pContext = pContext;
+ }
+
+ inline void TakeOwnership(XnContext* pContext)
+ {
+ SetHandle(pContext);
+
+ if (pContext != NULL)
+ {
+ xnContextRelease(pContext);
+ }
+ }
+
+ /** @cond */
+ inline XnStatus XN_API_DEPRECATED("Use other overload!") RunXmlScript(const XnChar* strScript, EnumerationErrors* pErrors = NULL)
+ {
+ m_bUsingDeprecatedAPI = TRUE;
+ #pragma warning (push)
+ #pragma warning (disable: XN_DEPRECATED_WARNING_IDS)
+ return xnContextRunXmlScript(m_pContext, strScript, pErrors == NULL ? NULL : pErrors->GetUnderlying());
+ #pragma warning (pop)
+ }
+
+ inline XnStatus XN_API_DEPRECATED("Use other overload!") RunXmlScriptFromFile(const XnChar* strFileName, EnumerationErrors* pErrors = NULL)
+ {
+ m_bUsingDeprecatedAPI = TRUE;
+ #pragma warning (push)
+ #pragma warning (disable: XN_DEPRECATED_WARNING_IDS)
+ return xnContextRunXmlScriptFromFile(m_pContext, strFileName, pErrors == NULL ? NULL : pErrors->GetUnderlying());
+ #pragma warning (pop)
+ }
+
+ inline XnStatus XN_API_DEPRECATED("Use other overload!") InitFromXmlFile(const XnChar* strFileName, EnumerationErrors* pErrors = NULL)
+ {
+ XnContext* pContext = NULL;
+ m_bUsingDeprecatedAPI = TRUE;
+
+ #pragma warning (push)
+ #pragma warning (disable: XN_DEPRECATED_WARNING_IDS)
+ XnStatus nRetVal = xnInitFromXmlFile(strFileName, &pContext, pErrors == NULL ? NULL : pErrors->GetUnderlying());
+ #pragma warning (pop)
+ XN_IS_STATUS_OK(nRetVal);
+
+ TakeOwnership(pContext);
+ m_bAllocated = TRUE;
+
+ return (XN_STATUS_OK);
+ }
+
+ inline XnStatus XN_API_DEPRECATED("Use other overload!") OpenFileRecording(const XnChar* strFileName)
+ {
+ m_bUsingDeprecatedAPI = TRUE;
+ #pragma warning (push)
+ #pragma warning (disable: XN_DEPRECATED_WARNING_IDS)
+ return xnContextOpenFileRecording(m_pContext, strFileName);
+ #pragma warning (pop)
+ }
+
+ inline void XN_API_DEPRECATED("You may use Release() instead, or count on dtor") Shutdown()
+ {
+ if (m_pContext != NULL)
+ {
+ #pragma warning (push)
+ #pragma warning (disable: XN_DEPRECATED_WARNING_IDS)
+ xnShutdown(m_pContext);
+ #pragma warning (pop)
+ m_pContext = NULL;
+ }
+ }
+
+ XnStatus XN_API_DEPRECATED("Please use other overload") CreateProductionTree(NodeInfo& Tree)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ XnNodeHandle hNode;
+ nRetVal = xnCreateProductionTree(m_pContext, Tree, &hNode);
+ XN_IS_STATUS_OK(nRetVal);
+
+ Tree.m_bOwnerOfNode = TRUE;
+
+ return (XN_STATUS_OK);
+ }
+ /** @endcond */
+
+ private:
+ typedef struct NodeCreationCookie
+ {
+ NodeCreationHandler pFunc;
+ void* pCookie;
+ XnCallbackHandle hUnderlyingCallback;
+ } NodeCreationCookie;
+
+ typedef struct NodeDestructionCookie
+ {
+ NodeDestructionHandler pFunc;
+ void* pCookie;
+ XnCallbackHandle hUnderlyingCallback;
+ } NodeDestructionCookie;
+
+ static void XN_CALLBACK_TYPE NodeCreationCallback(XnContext* pContext, XnNodeHandle hCreatedNode, void* pCookie)
+ {
+ NodeCreationCookie* pNodeCreationCookie = (NodeCreationCookie*)pCookie;
+ Context context(pContext);
+ ProductionNode createdNode(hCreatedNode);
+ pNodeCreationCookie->pFunc(context, createdNode, pNodeCreationCookie->pCookie);
+ }
+
+ static void XN_CALLBACK_TYPE NodeDestructionCallback(XnContext* pContext, const XnChar* strDestroyedNodeName, void* pCookie)
+ {
+ NodeDestructionCookie* pNodeCreationCookie = (NodeDestructionCookie*)pCookie;
+ Context context(pContext);
+ pNodeCreationCookie->pFunc(context, strDestroyedNodeName, pNodeCreationCookie->pCookie);
+ }
+
+ static void XN_CALLBACK_TYPE ContextShuttingDownCallback(XnContext* /*pContext*/, void* pCookie)
+ {
+ Context* pThis = (Context*)pCookie;
+ pThis->m_pContext = NULL;
+ }
+
+ XnContext* m_pContext;
+ XnBool m_bUsingDeprecatedAPI;
+ XnBool m_bAllocated;
+ XnCallbackHandle m_hShuttingDownCallback;
+ };
+
+ /**
+ * @ingroup cppref_misc
+ * A utility class for resolution info
+ */
+ class Resolution
+ {
+ public:
+ /**
+ * Creates a @ref Resolution object.
+ *
+ * @param [in] res Resolution
+ */
+ inline Resolution(XnResolution res) : m_Res(res)
+ {
+ m_nXRes = xnResolutionGetXRes(res);
+ m_nYRes = xnResolutionGetYRes(res);
+ m_strName = xnResolutionGetName(res);
+ }
+
+ /**
+ * Creates a @ref Resolution object out of X and Y resolutions.
+ *
+ * @param [in] xRes X resolution
+ * @param [in] yRes Y resolution
+ */
+ inline Resolution(XnUInt32 xRes, XnUInt32 yRes) : m_nXRes(xRes), m_nYRes(yRes)
+ {
+ m_Res = xnResolutionGetFromXYRes(xRes, yRes);
+ m_strName = xnResolutionGetName(m_Res);
+ }
+
+ /**
+ * Creates a @ref Resolution object out of its name
+ *
+ * @param [in] strName name of the resolution
+ */
+ inline Resolution(const XnChar* strName)
+ {
+ m_Res = xnResolutionGetFromName(strName);
+ m_nXRes = xnResolutionGetXRes(m_Res);
+ m_nYRes = xnResolutionGetYRes(m_Res);
+ m_strName = xnResolutionGetName(m_Res);
+ }
+
+ /**
+ * Gets the resolution
+ */
+ inline XnResolution GetResolution() const { return m_Res; }
+ /**
+ * Gets the X resolution
+ */
+ inline XnUInt32 GetXResolution() const { return m_nXRes; }
+ /**
+ * Gets the Y resolution
+ */
+ inline XnUInt32 GetYResolution() const { return m_nYRes; }
+ /**
+ * Gets the name of the resolution
+ */
+ inline const XnChar* GetName() const { return m_strName; }
+
+ private:
+ XnResolution m_Res;
+ XnUInt32 m_nXRes;
+ XnUInt32 m_nYRes;
+ const XnChar* m_strName;
+ };
+
+ //---------------------------------------------------------------------------
+ // Functions Implementation
+ //---------------------------------------------------------------------------
+ inline XnStatus NodeInfoList::FilterList(Context& context, Query& query)
+ {
+ return xnNodeQueryFilterList(context.GetUnderlyingObject(), query.GetUnderlyingObject(), m_pList);
+ }
+
+ inline void ProductionNode::GetContext(Context& context) const
+ {
+ context.TakeOwnership(xnGetRefContextFromNodeHandle(GetHandle()));
+ }
+
+ inline Context ProductionNode::GetContext() const
+ {
+ XnContext* pContext = xnGetRefContextFromNodeHandle(GetHandle());
+ Context result(pContext);
+ xnContextRelease(pContext);
+ return result;
+ }
+
+ inline NodeInfoList& NodeInfo::GetNeededNodes() const
+ {
+ if (m_pNeededNodes == NULL)
+ {
+ XnNodeInfoList* pList = xnNodeInfoGetNeededNodes(m_pInfo);
+ m_pNeededNodes = XN_NEW(NodeInfoList, pList);
+ }
+
+ return *m_pNeededNodes;
+ }
+
+ inline void NodeInfo::SetUnderlyingObject(XnNodeInfo* pInfo)
+ {
+ if (m_pNeededNodes != NULL)
+ {
+ XN_DELETE(m_pNeededNodes);
+ }
+
+ m_bOwnerOfNode = FALSE;
+ m_pInfo = pInfo;
+ m_pNeededNodes = NULL;
+ }
+
+ inline XnBool FrameSyncCapability::CanFrameSyncWith(Generator& other) const
+ {
+ return xnCanFrameSyncWith(GetHandle(), other.GetHandle());
+ }
+
+ inline XnStatus FrameSyncCapability::FrameSyncWith(Generator& other)
+ {
+ return xnFrameSyncWith(GetHandle(), other.GetHandle());
+ }
+
+ inline XnStatus FrameSyncCapability::StopFrameSyncWith(Generator& other)
+ {
+ return xnStopFrameSyncWith(GetHandle(), other.GetHandle());
+ }
+
+ inline XnBool FrameSyncCapability::IsFrameSyncedWith(Generator& other) const
+ {
+ return xnIsFrameSyncedWith(GetHandle(), other.GetHandle());
+ }
+
+ inline XnStatus NodeInfo::GetInstance(ProductionNode& node) const
+ {
+ if (m_pInfo == NULL)
+ {
+ return XN_STATUS_INVALID_OPERATION;
+ }
+
+ XnNodeHandle hNode = xnNodeInfoGetRefHandle(m_pInfo);
+ node.TakeOwnership(hNode);
+
+ if (m_bOwnerOfNode)
+ {
+ xnProductionNodeRelease(hNode);
+ }
+
+ return (XN_STATUS_OK);
+ }
+
+ //---------------------------------------------------------------------------
+ // Node creation functions
+ //---------------------------------------------------------------------------
+
+ inline XnStatus Device::Create(Context& context, Query* pQuery/*=NULL*/, EnumerationErrors* pErrors/*=NULL*/)
+ {
+ XnNodeHandle hNode;
+ XnStatus nRetVal = xnCreateDevice(context.GetUnderlyingObject(), &hNode, pQuery == NULL ? NULL : pQuery->GetUnderlyingObject(), pErrors == NULL ? NULL : pErrors->GetUnderlying());
+ XN_IS_STATUS_OK(nRetVal);
+ TakeOwnership(hNode);
+ return (XN_STATUS_OK);
+ }
+
+ inline XnStatus Recorder::Create(Context& context, const XnChar* strFormatName /*= NULL*/)
+ {
+ XnNodeHandle hNode;
+ XnStatus nRetVal = xnCreateRecorder(context.GetUnderlyingObject(), strFormatName, &hNode);
+ XN_IS_STATUS_OK(nRetVal);
+ TakeOwnership(hNode);
+ return (XN_STATUS_OK);
+ }
+
+ inline XnStatus Player::Create(Context& context, const XnChar* strFormatName)
+ {
+ XnNodeHandle hNode;
+ XnStatus nRetVal = xnCreatePlayer(context.GetUnderlyingObject(), strFormatName, &hNode);
+ XN_IS_STATUS_OK(nRetVal);
+ TakeOwnership(hNode);
+ return (XN_STATUS_OK);
+ }
+
+ inline XnStatus DepthGenerator::Create(Context& context, Query* pQuery/*=NULL*/, EnumerationErrors* pErrors/*=NULL*/)
+ {
+ XnNodeHandle hNode;
+ XnStatus nRetVal = xnCreateDepthGenerator(context.GetUnderlyingObject(), &hNode, pQuery == NULL ? NULL : pQuery->GetUnderlyingObject(), pErrors == NULL ? NULL : pErrors->GetUnderlying());
+ XN_IS_STATUS_OK(nRetVal);
+ TakeOwnership(hNode);
+ return (XN_STATUS_OK);
+ }
+
+ inline XnStatus MockDepthGenerator::Create(Context& context, const XnChar* strName /* = NULL */)
+ {
+ XnNodeHandle hNode;
+ XnStatus nRetVal = xnCreateMockNode(context.GetUnderlyingObject(), XN_NODE_TYPE_DEPTH, strName, &hNode);
+ XN_IS_STATUS_OK(nRetVal);
+ TakeOwnership(hNode);
+ return (XN_STATUS_OK);
+ }
+
+ inline XnStatus MockDepthGenerator::CreateBasedOn(DepthGenerator& other, const XnChar* strName /* = NULL */)
+ {
+ Context context;
+ other.GetContext(context);
+ XnNodeHandle hNode;
+ XnStatus nRetVal = xnCreateMockNodeBasedOn(context.GetUnderlyingObject(), other.GetHandle(), strName, &hNode);
+ XN_IS_STATUS_OK(nRetVal);
+ TakeOwnership(hNode);
+ return (XN_STATUS_OK);
+ }
+
+ inline XnStatus ImageGenerator::Create(Context& context, Query* pQuery/*=NULL*/, EnumerationErrors* pErrors/*=NULL*/)
+ {
+ XnNodeHandle hNode;
+ XnStatus nRetVal = xnCreateImageGenerator(context.GetUnderlyingObject(), &hNode, pQuery == NULL ? NULL : pQuery->GetUnderlyingObject(), pErrors == NULL ? NULL : pErrors->GetUnderlying());
+ XN_IS_STATUS_OK(nRetVal);
+ TakeOwnership(hNode);
+ return (XN_STATUS_OK);
+ }
+
+ inline XnStatus MockImageGenerator::Create(Context& context, const XnChar* strName /* = NULL */)
+ {
+ XnNodeHandle hNode;
+ XnStatus nRetVal = xnCreateMockNode(context.GetUnderlyingObject(), XN_NODE_TYPE_IMAGE, strName, &hNode);
+ XN_IS_STATUS_OK(nRetVal);
+ TakeOwnership(hNode);
+ return (XN_STATUS_OK);
+ }
+
+ inline XnStatus MockImageGenerator::CreateBasedOn(ImageGenerator& other, const XnChar* strName /* = NULL */)
+ {
+ Context context;
+ other.GetContext(context);
+ XnNodeHandle hNode;
+ XnStatus nRetVal = xnCreateMockNodeBasedOn(context.GetUnderlyingObject(), other.GetHandle(), strName, &hNode);
+ XN_IS_STATUS_OK(nRetVal);
+ TakeOwnership(hNode);
+ return (XN_STATUS_OK);
+ }
+
+ inline XnStatus IRGenerator::Create(Context& context, Query* pQuery/*=NULL*/, EnumerationErrors* pErrors/*=NULL*/)
+ {
+ XnNodeHandle hNode;
+ XnStatus nRetVal = xnCreateIRGenerator(context.GetUnderlyingObject(), &hNode, pQuery == NULL ? NULL : pQuery->GetUnderlyingObject(), pErrors == NULL ? NULL : pErrors->GetUnderlying());
+ XN_IS_STATUS_OK(nRetVal);
+ TakeOwnership(hNode);
+ return (XN_STATUS_OK);
+ }
+
+ inline XnStatus MockIRGenerator::Create(Context& context, const XnChar* strName /* = NULL */)
+ {
+ XnNodeHandle hNode;
+ XnStatus nRetVal = xnCreateMockNode(context.GetUnderlyingObject(), XN_NODE_TYPE_IR, strName, &hNode);
+ XN_IS_STATUS_OK(nRetVal);
+ TakeOwnership(hNode);
+ return (XN_STATUS_OK);
+ }
+
+ inline XnStatus MockIRGenerator::CreateBasedOn(IRGenerator& other, const XnChar* strName /* = NULL */)
+ {
+ Context context;
+ other.GetContext(context);
+ XnNodeHandle hNode;
+ XnStatus nRetVal = xnCreateMockNodeBasedOn(context.GetUnderlyingObject(), other.GetHandle(), strName, &hNode);
+ XN_IS_STATUS_OK(nRetVal);
+ TakeOwnership(hNode);
+ return (XN_STATUS_OK);
+ }
+
+ inline XnStatus GestureGenerator::Create(Context& context, Query* pQuery/*=NULL*/, EnumerationErrors* pErrors/*=NULL*/)
+ {
+ XnNodeHandle hNode;
+ XnStatus nRetVal = xnCreateGestureGenerator(context.GetUnderlyingObject(), &hNode, pQuery == NULL ? NULL : pQuery->GetUnderlyingObject(), pErrors == NULL ? NULL : pErrors->GetUnderlying());
+ XN_IS_STATUS_OK(nRetVal);
+ TakeOwnership(hNode);
+ return (XN_STATUS_OK);
+ }
+
+ inline XnStatus SceneAnalyzer::Create(Context& context, Query* pQuery/*=NULL*/, EnumerationErrors* pErrors/*=NULL*/)
+ {
+ //You're creating a scene!
+ XnNodeHandle hNode;
+ XnStatus nRetVal = xnCreateSceneAnalyzer(context.GetUnderlyingObject(), &hNode, pQuery == NULL ? NULL : pQuery->GetUnderlyingObject(), pErrors == NULL ? NULL : pErrors->GetUnderlying());
+ XN_IS_STATUS_OK(nRetVal);
+ TakeOwnership(hNode);
+ return (XN_STATUS_OK);
+ }
+
+ inline XnStatus HandsGenerator::Create(Context& context, Query* pQuery/*=NULL*/, EnumerationErrors* pErrors/*=NULL*/)
+ {
+ XnNodeHandle hNode;
+ XnStatus nRetVal = xnCreateHandsGenerator(context.GetUnderlyingObject(), &hNode, pQuery == NULL ? NULL : pQuery->GetUnderlyingObject(), pErrors == NULL ? NULL : pErrors->GetUnderlying());
+ XN_IS_STATUS_OK(nRetVal);
+ TakeOwnership(hNode);
+ return (XN_STATUS_OK);
+ }
+
+ inline XnStatus UserGenerator::Create(Context& context, Query* pQuery/*=NULL*/, EnumerationErrors* pErrors/*=NULL*/)
+ {
+ XnNodeHandle hNode;
+ XnStatus nRetVal = xnCreateUserGenerator(context.GetUnderlyingObject(), &hNode, pQuery == NULL ? NULL : pQuery->GetUnderlyingObject(), pErrors == NULL ? NULL : pErrors->GetUnderlying());
+ XN_IS_STATUS_OK(nRetVal);
+ TakeOwnership(hNode);
+ return (XN_STATUS_OK);
+ }
+
+ inline XnStatus AudioGenerator::Create(Context& context, Query* pQuery/*=NULL*/, EnumerationErrors* pErrors/*=NULL*/)
+ {
+ XnNodeHandle hNode;
+ XnStatus nRetVal = xnCreateAudioGenerator(context.GetUnderlyingObject(), &hNode, pQuery == NULL ? NULL : pQuery->GetUnderlyingObject(), pErrors == NULL ? NULL : pErrors->GetUnderlying());
+ XN_IS_STATUS_OK(nRetVal);
+ TakeOwnership(hNode);
+ return (XN_STATUS_OK);
+ }
+
+ inline XnStatus MockAudioGenerator::Create(Context& context, const XnChar* strName /* = NULL */)
+ {
+ XnNodeHandle hNode;
+ XnStatus nRetVal = xnCreateMockNode(context.GetUnderlyingObject(), XN_NODE_TYPE_AUDIO, strName, &hNode);
+ XN_IS_STATUS_OK(nRetVal);
+ TakeOwnership(hNode);
+ return (XN_STATUS_OK);
+ }
+
+ inline XnStatus MockAudioGenerator::CreateBasedOn(AudioGenerator& other, const XnChar* strName /* = NULL */)
+ {
+ Context context;
+ other.GetContext(context);
+ XnNodeHandle hNode;
+ XnStatus nRetVal = xnCreateMockNodeBasedOn(context.GetUnderlyingObject(), other.GetHandle(), strName, &hNode);
+ XN_IS_STATUS_OK(nRetVal);
+ TakeOwnership(hNode);
+ return (XN_STATUS_OK);
+ }
+
+ inline XnStatus MockRawGenerator::Create(Context& context, const XnChar* strName /*= NULL*/)
+ {
+ XnNodeHandle hNode;
+ XnStatus nRetVal = xnCreateMockNode(context.GetUnderlyingObject(), XN_NODE_TYPE_GENERATOR, strName, &hNode);
+ XN_IS_STATUS_OK(nRetVal);
+ TakeOwnership(hNode);
+ return (XN_STATUS_OK);
+ }
+
+ inline XnStatus Codec::Create(Context& context, XnCodecID codecID, ProductionNode& initializerNode)
+ {
+ XnNodeHandle hNode;
+ XnStatus nRetVal = xnCreateCodec(context.GetUnderlyingObject(), codecID, initializerNode.GetHandle(), &hNode);
+ XN_IS_STATUS_OK(nRetVal);
+ TakeOwnership(hNode);
+ return (XN_STATUS_OK);
+ }
+
+ inline XnStatus ScriptNode::Run(EnumerationErrors* pErrors)
+ {
+ return xnScriptNodeRun(GetHandle(), pErrors == NULL ? NULL : pErrors->GetUnderlying());
+ }
+
+ inline XnStatus ScriptNode::Create(Context& context, const XnChar* strFormat)
+ {
+ XnNodeHandle hNode;
+ XnStatus nRetVal = xnCreateScriptNode(context.GetUnderlyingObject(), strFormat, &hNode);
+ XN_IS_STATUS_OK(nRetVal);
+ TakeOwnership(hNode);
+ return (XN_STATUS_OK);
+ }
+
+ //---------------------------------------------------------------------------
+ // Global Helper Functions
+ //---------------------------------------------------------------------------
+
+ inline void XN_API_DEPRECATED("Use xn::Version::Current() instead") GetVersion(XnVersion& Version)
+ {
+ xnGetVersion(&Version);
+ }
+
+ //---------------------------------------------------------------------------
+ // Internal Helper Classes and Functions
+ //---------------------------------------------------------------------------
+
+ class StateChangedCallbackTranslator
+ {
+ public:
+ StateChangedCallbackTranslator(StateChangedHandler handler, void* pCookie) : m_UserHandler(handler), m_pUserCookie(pCookie), m_hCallback(NULL) {}
+
+ XnStatus Register(_XnRegisterStateChangeFuncPtr xnFunc, XnNodeHandle hNode)
+ {
+ return xnFunc(hNode, StateChangedCallback, this, &m_hCallback);
+ }
+
+ void Unregister(_XnUnregisterStateChangeFuncPtr xnFunc, XnNodeHandle hNode)
+ {
+ xnFunc(hNode, m_hCallback);
+ }
+
+ static XnStatus RegisterToUnderlying(_XnRegisterStateChangeFuncPtr xnFunc, XnNodeHandle hNode, StateChangedHandler handler, void* pCookie, XnCallbackHandle& hCallback)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ StateChangedCallbackTranslator* pTrans;
+ XN_VALIDATE_NEW(pTrans, StateChangedCallbackTranslator, handler, pCookie);
+
+ nRetVal = pTrans->Register(xnFunc, hNode);
+ if (nRetVal != XN_STATUS_OK)
+ {
+ XN_DELETE(pTrans);
+ return (nRetVal);
+ }
+
+ hCallback = pTrans;
+
+ return (XN_STATUS_OK);
+ }
+
+ static XnStatus UnregisterFromUnderlying(_XnUnregisterStateChangeFuncPtr xnFunc, XnNodeHandle hNode, XnCallbackHandle hCallback)
+ {
+ StateChangedCallbackTranslator* pTrans = (StateChangedCallbackTranslator*)hCallback;
+ pTrans->Unregister(xnFunc, hNode);
+ XN_DELETE(pTrans);
+ return XN_STATUS_OK;
+ }
+
+ private:
+ friend class GeneralIntCapability;
+
+ typedef struct StateChangeCookie
+ {
+ StateChangedHandler userHandler;
+ void* pUserCookie;
+ XnCallbackHandle hCallback;
+ } StateChangeCookie;
+
+ static void XN_CALLBACK_TYPE StateChangedCallback(XnNodeHandle hNode, void* pCookie)
+ {
+ StateChangedCallbackTranslator* pTrans = (StateChangedCallbackTranslator*)pCookie;
+ ProductionNode node(hNode);
+ pTrans->m_UserHandler(node, pTrans->m_pUserCookie);
+ }
+
+ StateChangedHandler m_UserHandler;
+ void* m_pUserCookie;
+ XnCallbackHandle m_hCallback;
+ };
+
+ static XnStatus _RegisterToStateChange(_XnRegisterStateChangeFuncPtr xnFunc, XnNodeHandle hNode, StateChangedHandler handler, void* pCookie, XnCallbackHandle& hCallback)
+ {
+ return StateChangedCallbackTranslator::RegisterToUnderlying(xnFunc, hNode, handler, pCookie, hCallback);
+ }
+
+ static void _UnregisterFromStateChange(_XnUnregisterStateChangeFuncPtr xnFunc, XnNodeHandle hNode, XnCallbackHandle hCallback)
+ {
+ StateChangedCallbackTranslator::UnregisterFromUnderlying(xnFunc, hNode, hCallback);
+ }
+
+ inline XnStatus GeneralIntCapability::RegisterToValueChange(StateChangedHandler handler, void* pCookie, XnCallbackHandle& hCallback)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ StateChangedCallbackTranslator* pTrans;
+ XN_VALIDATE_NEW(pTrans, StateChangedCallbackTranslator, handler, pCookie);
+
+ nRetVal = xnRegisterToGeneralIntValueChange(GetHandle(), m_strCap, pTrans->StateChangedCallback, pTrans, &pTrans->m_hCallback);
+ if (nRetVal != XN_STATUS_OK)
+ {
+ XN_DELETE(pTrans);
+ return (nRetVal);
+ }
+
+ hCallback = pTrans;
+
+ return (XN_STATUS_OK);
+ }
+
+ inline void GeneralIntCapability::UnregisterFromValueChange(XnCallbackHandle hCallback)
+ {
+ StateChangedCallbackTranslator* pTrans = (StateChangedCallbackTranslator*)hCallback;
+ xnUnregisterFromGeneralIntValueChange(GetHandle(), m_strCap, pTrans->m_hCallback);
+ XN_DELETE(pTrans);
+ }
+};
+
+#endif // __XN_CPP_WRAPPER_H__
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnCyclicQueueT.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnCyclicQueueT.h
new file mode 100644
index 00000000..6e323d3f
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnCyclicQueueT.h
@@ -0,0 +1,79 @@
+#ifndef _XN_CYCLIC_QUEUE_T_H_
+#define _XN_CYCLIC_QUEUE_T_H_
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include "XnQueueT.h"
+
+//---------------------------------------------------------------------------
+// Code
+//---------------------------------------------------------------------------
+
+template<class T, XnUInt32 TDefaultMaxDepth, class TAlloc = XnLinkedNodeDefaultAllocatorT<T> >
+class XnCyclicQueueT : protected XnQueueT<T, TAlloc>
+{
+public:
+ typedef XnQueueT<T, TAlloc> Base;
+
+ XnCyclicQueueT(XnUInt32 nMaxDepth = TDefaultMaxDepth) : Base(), m_nMaxDepth(nMaxDepth) {}
+
+ XnCyclicQueueT(const XnCyclicQueueT& other) : Base(other)
+ {
+ *this = other;
+ }
+
+ XnCyclicQueueT& operator=(const XnCyclicQueueT& other)
+ {
+ Base::operator=(other);
+ m_nMaxDepth = other.m_nMaxDepth;
+ return *this;
+ }
+
+ ~XnCyclicQueueT() {}
+
+ using Base::ConstIterator;
+ using Base::IsEmpty;
+ using Base::Size;
+
+ XnStatus SetMaxSize(XnUInt32 nMaxSize)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ while (Size() > nMaxSize)
+ {
+ nRetVal = Remove(this->Begin());
+ XN_IS_STATUS_OK(nRetVal);
+ }
+
+ m_nMaxDepth = nMaxSize;
+
+ return (XN_STATUS_OK);
+ }
+
+ XnStatus Push(T const& value)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+ if (Size() == m_nMaxDepth)
+ {
+ nRetVal = Remove(this->Begin());
+ XN_IS_STATUS_OK(nRetVal);
+ }
+
+ nRetVal = Base::Push(value);
+ XN_IS_STATUS_OK(nRetVal);
+
+ return (XN_STATUS_OK);
+ }
+
+ using Base::Pop;
+ using Base::Top;
+ using Base::Begin;
+ using Base::End;
+
+protected:
+ XnUInt32 m_nMaxDepth;
+};
+
+
+#endif // _XN_CYCLIC_QUEUE_T_H_ \ No newline at end of file
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnCyclicStackT.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnCyclicStackT.h
new file mode 100644
index 00000000..39d8ebca
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnCyclicStackT.h
@@ -0,0 +1,80 @@
+#ifndef _XN_CYCLIC_STACK_T_H_
+#define _XN_CYCLIC_STACK_T_H_
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include "XnStackT.h"
+
+//---------------------------------------------------------------------------
+// Code
+//---------------------------------------------------------------------------
+
+template<class T, XnUInt32 TDefaultMaxDepth, class TAlloc = XnLinkedNodeDefaultAllocatorT<T> >
+class XnCyclicStackT : protected XnStackT<T, TAlloc>
+{
+public:
+ typedef XnStackT<T, TAlloc> Base;
+
+ XnCyclicStackT(XnUInt32 nMaxDepth = TDefaultMaxDepth) : Base(), m_nMaxDepth(nMaxDepth) {}
+
+ XnCyclicStackT(const XnCyclicStackT& other) : Base(other)
+ {
+ *this = other;
+ }
+
+ XnCyclicStackT& operator=(const XnCyclicStackT& other)
+ {
+ Base::operator=(other);
+ m_nMaxDepth = other.m_nMaxDepth;
+ return *this;
+ }
+
+ ~XnCyclicStackT() {}
+
+ using typename Base::ConstIterator;
+ using Base::Remove;
+ using Base::IsEmpty;
+ using Base::Size;
+
+ XnStatus SetMaxSize(XnUInt32 nMaxSize)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ while (Size() > nMaxSize)
+ {
+ nRetVal = Remove(this->ReverseBegin());
+ XN_IS_STATUS_OK(nRetVal);
+ }
+
+ m_nMaxDepth = nMaxSize;
+
+ return (XN_STATUS_OK);
+ }
+
+ XnStatus Push(T const& value)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+ if (Size() == m_nMaxDepth)
+ {
+ nRetVal = Remove(this->ReverseBegin());
+ XN_IS_STATUS_OK(nRetVal);
+ }
+
+ nRetVal = Base::Push(value);
+ XN_IS_STATUS_OK(nRetVal);
+
+ return (XN_STATUS_OK);
+ }
+
+ using Base::Pop;
+ using Base::Top;
+ using Base::Begin;
+ using Base::End;
+
+protected:
+ XnUInt32 m_nMaxDepth;
+};
+
+
+#endif // _XN_CYCLIC_STACK_T_H_
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnDataTypes.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnDataTypes.h
new file mode 100644
index 00000000..fcc3296c
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnDataTypes.h
@@ -0,0 +1,120 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef _XN_DATA_TYPES_H_
+#define _XN_DATA_TYPES_H_
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include "XnOS.h"
+
+//---------------------------------------------------------------------------
+// Types
+//---------------------------------------------------------------------------
+/**
+ * The value type for all general data structures
+ */
+typedef void* XnValue;
+
+/**
+ * Declares a translator from @a Type to XnValue, with a name @a ClassName. The class is declared
+ * with the @a decl declspec.
+ */
+#define XN_DECLARE_DEFAULT_VALUE_TRANSLATOR_DECL(decl, Type, ClassName) \
+ class decl ClassName \
+ { \
+ public: \
+ XN_PRAGMA_START_DISABLED_WARNING_SECTION(XN_CONDITION_IS_CONST_WARNING_ID) \
+ \
+ static XnValue CreateValueCopy(Type const& orig) \
+ { \
+ if (sizeof(Type) > sizeof(XnValue)) \
+ { \
+ Type* pNew = XN_NEW(Type, orig); \
+ return (XnValue)pNew; \
+ } \
+ else \
+ { \
+ XnValue result = 0; \
+ xnOSMemCopy(&result, &orig, sizeof(Type)); \
+ return result; \
+ } \
+ } \
+ static void FreeValue(XnValue& Value) \
+ { \
+ if (sizeof(Type) > sizeof(XnValue)) \
+ { \
+ Type* p = (Type*)Value; \
+ XN_DELETE(p); \
+ } \
+ } \
+ static XnValue GetAsValue(Type const& orig) \
+ { \
+ if (sizeof(Type) > sizeof(XnValue)) \
+ { \
+ return (XnValue)&orig; \
+ } \
+ else \
+ { \
+ XnValue result = 0; \
+ xnOSMemCopy(&result, &orig, sizeof(Type)); \
+ return result; \
+ } \
+ } \
+ static Type const& GetFromValue(const XnValue& Value) \
+ { \
+ if (sizeof(Type) > sizeof(XnValue)) \
+ { \
+ Type const* p = (Type const*)Value; \
+ return *p; \
+ } \
+ else \
+ { \
+ Type const* p = (Type const*)&Value; \
+ return *p; \
+ } \
+ } \
+ static Type& GetFromValue(XnValue& Value) \
+ { \
+ if (sizeof(Type) > sizeof(XnValue)) \
+ { \
+ Type* p = (Type*)Value; \
+ return *p; \
+ } \
+ else \
+ { \
+ Type* p = (Type*)&Value; \
+ return *p; \
+ } \
+ } \
+ XN_PRAGMA_STOP_DISABLED_WARNING_SECTION \
+ };
+
+/**
+ * Declares a translator from @a Type to XnValue, with a name @a ClassName.
+ */
+#define XN_DECLARE_DEFAULT_VALUE_TRANSLATOR(Type, ClassName) \
+ XN_DECLARE_DEFAULT_VALUE_TRANSLATOR_DECL(, Type, ClassName)
+
+#define XN_DEFAULT_TRANSLATOR_NAME(ClassName) ClassName ## Translator
+
+#endif // _XN_DATA_TYPES_H_
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnDerivedCast.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnDerivedCast.h
new file mode 100644
index 00000000..7b11ee17
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnDerivedCast.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+/****************************************************************************
+* *
+* OpenNI 1.1 Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/\
+
+#ifndef __XN_DERIVED_CAST_H__
+#define __XN_DERIVED_CAST_H__
+
+// derived_cast Acts as dynamic_cast without the need for RTTI. used in platforms that not implement RTTI well like Linux-Arm.
+template<class T>
+static T derived_cast(ModuleProductionNode* pPrdNode);
+
+#define DERIVED_CAST_IMPL(T, enm) \
+ template<> \
+ T* derived_cast<T*>(ModuleProductionNode* pPrdNode) \
+ { \
+ return (T*)pPrdNode->m_aInterfaces[enm]; \
+ }
+
+DERIVED_CAST_IMPL(ModuleDevice, XN_NODE_TYPE_DEVICE)
+DERIVED_CAST_IMPL(ModuleRecorder, XN_NODE_TYPE_RECORDER)
+DERIVED_CAST_IMPL(ModulePlayer, XN_NODE_TYPE_PLAYER)
+DERIVED_CAST_IMPL(ModuleCodec, XN_NODE_TYPE_CODEC)
+DERIVED_CAST_IMPL(ModuleScriptNode, XN_NODE_TYPE_SCRIPT)
+DERIVED_CAST_IMPL(ModuleGenerator, XN_NODE_TYPE_GENERATOR)
+DERIVED_CAST_IMPL(ModuleUserGenerator, XN_NODE_TYPE_USER)
+DERIVED_CAST_IMPL(ModuleHandsGenerator, XN_NODE_TYPE_HANDS)
+DERIVED_CAST_IMPL(ModuleGestureGenerator, XN_NODE_TYPE_GESTURE)
+DERIVED_CAST_IMPL(ModuleAudioGenerator, XN_NODE_TYPE_AUDIO)
+DERIVED_CAST_IMPL(ModuleMapGenerator, XN_NODE_TYPE_MAP_GENERATOR)
+DERIVED_CAST_IMPL(ModuleDepthGenerator, XN_NODE_TYPE_DEPTH)
+DERIVED_CAST_IMPL(ModuleImageGenerator, XN_NODE_TYPE_IMAGE)
+DERIVED_CAST_IMPL(ModuleIRGenerator, XN_NODE_TYPE_IR)
+DERIVED_CAST_IMPL(ModuleSceneAnalyzer, XN_NODE_TYPE_SCENE)
+
+#ifdef dynamic_cast
+#undef dynamic_cast
+#endif
+
+#define dynamic_cast derived_cast
+
+#endif
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnDump.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnDump.h
new file mode 100644
index 00000000..d0423c68
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnDump.h
@@ -0,0 +1,202 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef __XN_DUMP_H__
+#define __XN_DUMP_H__
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include "XnPlatform.h"
+#include "XnStatus.h"
+
+//---------------------------------------------------------------------------
+// Types
+//---------------------------------------------------------------------------
+struct XnDumpFile;
+typedef struct XnDumpFile XnDumpFile;
+
+//---------------------------------------------------------------------------
+// Functions
+//---------------------------------------------------------------------------
+
+/**
+* Configures if a specific dump mask is enabled.
+*
+* @param strMask [in] The mask to set.
+* @param bEnabled [in] TRUE to enable this dump, FALSE otherwise.
+*/
+XN_C_API XnStatus XN_C_DECL xnDumpSetMaskState(const XnChar* strMask, XnBool bEnabled);
+
+/**
+* This function checks if a dump mask is enabled
+*
+* @param strDumpMask [in] The mask that should be checked.
+*/
+XN_C_API XnBool XN_C_DECL xnLogIsDumpMaskEnabled(const XnChar* strDumpMask);
+
+/**
+* Opens a file for writing dump.
+*
+* @param strDumpName [in] Name of the dump mask this file belongs to.
+* @param strNameFormat [in] A format string for the name of the file.
+*
+* @returns a file handle for writing data. The file should be closed using @ref xnDumpFileClose().
+*/
+XN_C_API XnDumpFile* XN_C_DECL xnDumpFileOpen(const XnChar* strDumpName, const XnChar* strNameFormat, ...);
+
+/**
+* Opens a file for writing dump using some advanced options.
+*
+* You would usually prefer to use @ref xnDumpFileOpen().
+*
+* @param strDumpName [in] Name of the dump mask this file belongs to.
+* @param bForce [in] When TRUE, file will be created even if dump is currently off.
+* @param bSessionDump [in] When TRUE, file will be created with current session timestamp as a prefix to its name.
+* @param strNameFormat [in] A format string for the name of the file.
+*
+* @returns a file handle for writing data. The file should be closed using @ref xnDumpFileClose().
+*/
+XN_C_API XnDumpFile* XN_C_DECL xnDumpFileOpenEx(const XnChar* strDumpName, XnBool bForce, XnBool bSessionDump, const XnChar* strNameFormat, ...);
+
+/**
+* Writes a buffer to a dump file.
+*
+* @param pFile [in] Dump file to write to. A pointer retrieved from @ref xnDumpFileOpen.
+* @param pBuffer [in] Data to be written to file.
+* @param nBufferSize [in] Size of the buffer.
+*/
+XN_C_API void XN_C_DECL _xnDumpFileWriteBuffer(XnDumpFile* pFile, const void* pBuffer, XnUInt32 nBufferSize);
+
+/**
+* Writes a formatted string to a dump file.
+*
+* @param pFile [in] Dump file to write to. A pointer retrieved from @ref xnDumpFileOpen.
+* @param strFormat [in] Format string.
+*
+* NOTE: the total length of the string must not exceed 8 KB. If it does, it will be truncated.
+*/
+XN_C_API void XN_C_DECL _xnDumpFileWriteString(XnDumpFile* pFile, const XnChar* strFormat, ...);
+
+/**
+* Closes a dump file.
+*
+* @param hFile [in] Dump file to close. A pointer retrieved from @ref xnDumpFileOpen.
+*/
+XN_C_API void XN_C_DECL _xnDumpFileClose(XnDumpFile* pFile);
+
+#define xnDumpFileWriteBuffer(pFile, pBuffer, nBufferSize) \
+ if ((pFile) != NULL) \
+ { \
+ _xnDumpFileWriteBuffer(pFile, pBuffer, nBufferSize); \
+ } \
+
+#define xnDumpFileClose(pFile) \
+ if ((pFile) != NULL) \
+ { \
+ _xnDumpFileClose(pFile); \
+ pFile = NULL; \
+ } \
+
+#if XN_PLATFORM_VAARGS_TYPE == XN_PLATFORM_USE_WIN32_VAARGS_STYLE
+ #define xnDumpFileWriteString(pFile, strFormat, ...) \
+ if ((pFile) != NULL) \
+ { \
+ _xnDumpFileWriteString(pFile, strFormat, __VA_ARGS__); \
+ }
+#elif XN_PLATFORM_VAARGS_TYPE == XN_PLATFORM_USE_GCC_VAARGS_STYLE
+ #define xnDumpFileWriteString(pFile, strFormat, ...) \
+ if ((pFile) != NULL) \
+ { \
+ _xnDumpFileWriteString(pFile, strFormat, ##__VA_ARGS__);\
+ }
+#elif XN_PLATFORM_VAARGS_TYPE == XN_PLATFORM_USE_ARC_VAARGS_STYLE
+ #define xnDumpFileWriteString(pFile, strFormat, ...) \
+ if ((pFile) != NULL) \
+ { \
+ _xnDumpFileWriteString(pFile, strFormat); \
+ }
+#elif XN_PLATFORM_VAARGS_TYPE == XN_PLATFORM_USE_NO_VAARGS
+ #define xnDumpFileWriteString(pFile, strFormat, arg) \
+ if ((pFile) != NULL) \
+ { \
+ _xnDumpFileWriteString(pFile, strFormat,arg); \
+ }
+#else
+ #error Xiron Log - Unknown VAARGS type!
+#endif
+
+
+//---------------------------------------------------------------------------
+// Backwards Compatibility Stuff
+//---------------------------------------------------------------------------
+
+#ifndef __XN_NO_BC__
+
+#include "XnOS.h"
+
+typedef struct XnDump
+{
+ XN_FILE_HANDLE hFile;
+} XnDump;
+
+const XnDump XN_DUMP_CLOSED = { XN_INVALID_FILE_HANDLE };
+
+XN_C_API void XN_API_DEPRECATED("Use xnDumpFileX methods instead") XN_C_DECL xnDumpInit(XnDump* pDump, const XnChar* csDumpMask, const XnChar* csHeader, const XnChar* csFileNameFormat, ...);
+XN_C_API void XN_API_DEPRECATED("Use xnDumpFileX methods instead") XN_C_DECL xnDumpForceInit(XnDump* pDump, const XnChar* csHeader, const XnChar* csFileNameFormat, ...);
+XN_C_API void XN_API_DEPRECATED("Use xnDumpFileX methods instead") XN_C_DECL xnDumpClose(XnDump* pDump);
+XN_C_API void XN_API_DEPRECATED("Use xnDumpFileX methods instead") XN_C_DECL xnDumpWriteBufferImpl(XnDump dump, const void* pBuffer, XnUInt32 nBufferSize);
+XN_C_API void XN_API_DEPRECATED("Use xnDumpFileX methods instead") XN_C_DECL xnDumpWriteStringImpl(XnDump dump, const XnChar* csFormat, ...);
+XN_C_API void XN_API_DEPRECATED("Use xnDumpFileX methods instead") XN_C_DECL xnDumpFlush(XnDump dump);
+
+#define xnDumpWriteBuffer(dump, pBuffer, nBufferSize) \
+ if (dump.hFile != XN_INVALID_FILE_HANDLE) \
+ { \
+ xnDumpWriteBufferImpl(dump, pBuffer, nBufferSize); \
+ }
+
+#if XN_PLATFORM_VAARGS_TYPE == XN_PLATFORM_USE_WIN32_VAARGS_STYLE
+ #define xnDumpWriteString(dump, csFormat, ...) \
+ if ((dump).hFile != XN_INVALID_FILE_HANDLE) { \
+ xnDumpWriteStringImpl((dump), csFormat, __VA_ARGS__); \
+ }
+#elif XN_PLATFORM_VAARGS_TYPE == XN_PLATFORM_USE_GCC_VAARGS_STYLE
+ #define xnDumpWriteString(dump, csFormat, ...) \
+ if ((dump).hFile != XN_INVALID_FILE_HANDLE) { \
+ xnDumpWriteStringImpl((dump), csFormat, ##__VA_ARGS__); \
+ }
+#elif XN_PLATFORM_VAARGS_TYPE == XN_PLATFORM_USE_ARC_VAARGS_STYLE
+ #define xnDumpWriteString(dump, csFormat...) \
+ if ((dump).hFile != XN_INVALID_FILE_HANDLE) { \
+ xnDumpWriteStringImpl((dump), csFormat); \
+ }
+#elif XN_PLATFORM_VAARGS_TYPE == XN_PLATFORM_USE_NO_VAARGS
+ #define xnDumpWriteString(dump, csFormat, arg) \
+ if ((dump).hFile != XN_INVALID_FILE_HANDLE) { \
+ xnDumpWriteStringImpl((dump), csFormat, arg); \
+ }
+#else
+ #error Xiron Log - Unknown VAARGS type!
+#endif
+
+#endif // #ifndef __XN_NO_BC__
+
+#endif // __XN_DUMP_H__ \ No newline at end of file
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnDumpWriters.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnDumpWriters.h
new file mode 100644
index 00000000..0a641dbb
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnDumpWriters.h
@@ -0,0 +1,127 @@
+#ifndef __XN_DUMP_WRITERS_H__
+#define __XN_DUMP_WRITERS_H__
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include "XnDump.h"
+
+//---------------------------------------------------------------------------
+// Types
+//---------------------------------------------------------------------------
+typedef struct XnDumpWriterFileHandle
+{
+ void* pInternal;
+} XnDumpWriterFileHandle;
+
+typedef struct XnDumpWriter
+{
+ void* pCookie;
+ XnDumpWriterFileHandle (XN_CALLBACK_TYPE* OpenFile)(void* pCookie, const XnChar* strDumpName, XnBool bSessionDump, const XnChar* strFileName);
+ void (XN_CALLBACK_TYPE* Write)(void* pCookie, XnDumpWriterFileHandle hFile, const void* pBuffer, XnUInt32 nBufferSize);
+ void (XN_CALLBACK_TYPE* CloseFile)(void* pCookie, XnDumpWriterFileHandle hFile);
+} XnDumpWriter;
+
+//---------------------------------------------------------------------------
+// Functions
+//---------------------------------------------------------------------------
+XN_C_API XnStatus XN_C_DECL xnDumpRegisterWriter(XnDumpWriter* pWriter);
+
+XN_C_API void XN_C_DECL xnDumpUnregisterWriter(XnDumpWriter* pWriter);
+
+XN_C_API XnStatus XN_C_DECL xnDumpSetFilesOutput(XnBool bOn);
+
+//---------------------------------------------------------------------------
+// Helpers
+//---------------------------------------------------------------------------
+#ifdef __cplusplus
+
+class XnDumpWriterBase
+{
+public:
+ XnDumpWriterBase() : m_bRegistered(FALSE)
+ {
+ m_cObject.pCookie = this;
+ m_cObject.OpenFile = OpenFileCallback;
+ m_cObject.Write = WriteCallback;
+ m_cObject.CloseFile = CloseFileCallback;
+ }
+
+ virtual ~XnDumpWriterBase()
+ {
+ Unregister();
+ }
+
+ XnStatus Register()
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ if (!m_bRegistered)
+ {
+ OnRegister();
+
+ nRetVal = xnDumpRegisterWriter(&m_cObject);
+ if (nRetVal != XN_STATUS_OK)
+ {
+ OnUnregister();
+ return (nRetVal);
+ }
+
+ m_bRegistered = TRUE;
+ }
+
+ return (XN_STATUS_OK);
+ }
+
+ void Unregister()
+ {
+ if (m_bRegistered)
+ {
+ xnDumpUnregisterWriter(&m_cObject);
+ m_bRegistered = FALSE;
+
+ OnUnregister();
+ }
+ }
+
+ inline XnBool IsRegistered() { return m_bRegistered; }
+
+ virtual XnDumpWriterFileHandle OpenFile(const XnChar* strDumpName, XnBool bSessionDump, const XnChar* strFileName) = 0;
+ virtual void Write(XnDumpWriterFileHandle hFile, const void* pBuffer, XnUInt32 nBufferSize) = 0;
+ virtual void CloseFile(XnDumpWriterFileHandle hFile) = 0;
+
+ operator const XnDumpWriter*() const
+ {
+ return &m_cObject;
+ }
+
+protected:
+ virtual void OnRegister() {}
+ virtual void OnUnregister() {}
+
+private:
+ static XnDumpWriterFileHandle XN_CALLBACK_TYPE OpenFileCallback(void* pCookie, const XnChar* strDumpName, XnBool bSessionDump, const XnChar* strFileName)
+ {
+ XnDumpWriterBase* pThis = (XnDumpWriterBase*)pCookie;
+ return pThis->OpenFile(strDumpName, bSessionDump, strFileName);
+ }
+
+ static void XN_CALLBACK_TYPE WriteCallback(void* pCookie, XnDumpWriterFileHandle hFile, const void* pBuffer, XnUInt32 nBufferSize)
+ {
+ XnDumpWriterBase* pThis = (XnDumpWriterBase*)pCookie;
+ return pThis->Write(hFile, pBuffer, nBufferSize);
+ }
+
+ static void XN_CALLBACK_TYPE CloseFileCallback(void* pCookie, XnDumpWriterFileHandle hFile)
+ {
+ XnDumpWriterBase* pThis = (XnDumpWriterBase*)pCookie;
+ return pThis->CloseFile(hFile);
+ }
+
+ XnDumpWriter m_cObject;
+ XnBool m_bRegistered;
+};
+
+#endif
+
+#endif // __XN_DUMP_WRITERS_H__ \ No newline at end of file
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnEnumerationErrors.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnEnumerationErrors.h
new file mode 100644
index 00000000..4a1d77ce
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnEnumerationErrors.h
@@ -0,0 +1,142 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef __XN_ENUMERATION_ERRORS_H__
+#define __XN_ENUMERATION_ERRORS_H__
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include <XnTypes.h>
+
+/**
+ * @ingroup cref
+ * @defgroup enum_errors Enumeration Errors
+ * This page details functions for managing an Enumeration Errors object.
+ *
+ * @section enum Enumeration
+ *
+ * The following code iterates over an enumeration errors object:
+ * @code
+for (XnEnumerationErrorsIterator it = xnEnumerationErrorsGetFirst(pList);
+ xnEnumerationErrorsIteratorIsValid(it);
+ it = xnEnumerationErrorsGetNext(it))
+{
+ const XnProductionNodeDescription* pCurrDesc = xnEnumerationErrorsGetCurrentDescription(it);
+ XnStatus nCurrError = xnEnumerationErrorsGetCurrentError(it);
+ ...
+}
+ * @endcode
+ * @{
+ */
+
+//---------------------------------------------------------------------------
+// Types
+//---------------------------------------------------------------------------
+/**
+ * Represents an iterator for an @ref XnEnumerationErrors object.
+ */
+typedef struct XnModuleError* XnEnumerationErrorsIterator;
+
+//---------------------------------------------------------------------------
+// Functions
+//---------------------------------------------------------------------------
+
+
+/**
+ * Allocates an enumeration errors object.
+ *
+ * @param ppErrors [out] The allocated object
+ */
+XN_C_API XnStatus XN_C_DECL xnEnumerationErrorsAllocate(XnEnumerationErrors** ppErrors);
+
+/**
+ * Frees an enumeration errors object
+ *
+ * @param pErrors [in] Parameter description
+ */
+XN_C_API void XN_C_DECL xnEnumerationErrorsFree(const XnEnumerationErrors* pErrors);
+
+/**
+ * Adds an error to the object.
+ *
+ * @param pErrors [in] Enumeration Errors object.
+ * @param pDesc [in] Description of the failing module.
+ * @param nError [in] The enumeration error that occurred.
+ */
+XN_C_API XnStatus XN_C_DECL xnEnumerationErrorsAdd(XnEnumerationErrors* pErrors, const XnProductionNodeDescription* pDesc, XnStatus nError);
+
+/**
+ * Returns a string representation of the Enumeration Errors object.
+ *
+ * @param pErrors [in] Enumeration Errors object.
+ * @param csBuffer [in] A char buffer to be filled.
+ * @param nSize [in] Size of the char buffer.
+ */
+XN_C_API XnStatus XN_C_DECL xnEnumerationErrorsToString(const XnEnumerationErrors* pErrors, XnChar* csBuffer, XnUInt32 nSize);
+
+/**
+ * Clears an Enumeration Errors object from all errors in it.
+ *
+ * @param pErrors [in] Enumeration Errors object.
+ */
+XN_C_API XnStatus XN_C_DECL xnEnumerationErrorsClear(XnEnumerationErrors* pErrors);
+
+/**
+ * Gets an iterator to the first error in the object.
+ *
+ * @param pErrors [in] Enumeration Errors object.
+ */
+XN_C_API XnEnumerationErrorsIterator XN_C_DECL xnEnumerationErrorsGetFirst(const XnEnumerationErrors* pErrors);
+
+/**
+ * Gets an iterator to the next error in the object.
+ *
+ * @param it [in] An iterator to an error in the object.
+ */
+XN_C_API XnEnumerationErrorsIterator XN_C_DECL xnEnumerationErrorsGetNext(XnEnumerationErrorsIterator it);
+
+/**
+ * Checks if an iterator is valid (i.e. points to a real error)
+ *
+ * @param it [in] The iterator to check.
+ */
+XN_C_API XnBool XN_C_DECL xnEnumerationErrorsIteratorIsValid(XnEnumerationErrorsIterator it);
+
+/**
+ * Gets the description of the node from current error.
+ *
+ * @param it [in] The iterator to the error.
+ */
+XN_C_API const XnProductionNodeDescription* XN_C_DECL xnEnumerationErrorsGetCurrentDescription(XnEnumerationErrorsIterator it);
+
+/**
+ * Gets the enumeration error caused when enumerating the node.
+ *
+ * @param it [in] The iterator to the error.
+ */
+XN_C_API XnStatus XN_C_DECL xnEnumerationErrorsGetCurrentError(XnEnumerationErrorsIterator it);
+
+/**
+ * @}
+ */
+
+#endif // __XN_ENUMERATION_ERRORS_H__
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnEvent.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnEvent.h
new file mode 100644
index 00000000..f915b6aa
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnEvent.h
@@ -0,0 +1,301 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef __XN_EVENT_H__
+#define __XN_EVENT_H__
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include "XnCallback.h"
+#include "XnList.h"
+#include "XnTypes.h"
+#include "XnOSCpp.h"
+
+//---------------------------------------------------------------------------
+// Types
+//---------------------------------------------------------------------------
+class XnEventInterface
+{
+public:
+ XnEventInterface() {}
+ virtual ~XnEventInterface() {}
+
+ typedef XnStatus (XN_CALLBACK_TYPE* HandlerPtr)(void* pCookie);
+
+ virtual XnStatus Register(HandlerPtr pFunc, void* pCookie, XnCallbackHandle* pHandle = NULL) = 0;
+ virtual XnStatus Unregister(XnCallbackHandle handle) = 0;
+};
+
+class XnEvent : public XnEventInterface
+{
+public:
+ XnEvent() : m_hLock(0)
+ {
+ xnOSCreateCriticalSection(&m_hLock);
+ }
+
+ virtual ~XnEvent()
+ {
+ Clear();
+ xnOSCloseCriticalSection(&m_hLock);
+ }
+
+ XnStatus Register(HandlerPtr pFunc, void* pCookie, XnCallbackHandle* pHandle)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ XN_VALIDATE_INPUT_PTR(pFunc);
+
+ XnCallback* pCallback = NULL;
+ XN_VALIDATE_NEW(pCallback, XnCallback, (XnFuncPtr)pFunc, pCookie);
+
+ // always add to list of added (actual list will be updated in Raise method, to allow registering
+ // from a callback).
+ {
+ XnAutoCSLocker lock(m_hLock);
+ nRetVal = m_ToBeAdded.AddLast(pCallback);
+ }
+
+ if (nRetVal != XN_STATUS_OK)
+ {
+ XN_DELETE(pCallback);
+ return (nRetVal);
+ }
+
+ // return handle
+ if (pHandle != NULL)
+ {
+ *pHandle = pCallback;
+ }
+
+ return XN_STATUS_OK;
+ }
+
+ XnStatus Unregister(XnCallbackHandle handle)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ XnCallback* pObject = (XnCallback*)handle;
+
+ // add it to a temp list, to allow unregistering from a callback (actual list will be updated in raise
+ // function).
+ {
+ XnAutoCSLocker lock(m_hLock);
+
+ // try to remove it from the ToBeAdded list.
+ if (!RemoveCallback(m_ToBeAdded, pObject))
+ {
+ // it's not in this list, so it's probably in the main list
+ nRetVal = m_ToBeRemoved.AddLast(pObject);
+ }
+ }
+ XN_IS_STATUS_OK(nRetVal);
+
+ return XN_STATUS_OK;
+ }
+
+ XnStatus Clear()
+ {
+ ApplyListChanges();
+
+ for (XnCallbackPtrList::ConstIterator it = m_Handlers.begin(); it != m_Handlers.end(); ++it)
+ {
+ XnCallback* pCallback = *it;
+ XN_DELETE(pCallback);
+ }
+
+ m_Handlers.Clear();
+ m_ToBeRemoved.Clear();
+ m_ToBeAdded.Clear();
+ return (XN_STATUS_OK);
+ }
+
+protected:
+ XnStatus ApplyListChanges()
+ {
+ // first add all
+ for (XnCallbackPtrList::ConstIterator it = m_ToBeAdded.begin(); it != m_ToBeAdded.end(); ++it)
+ {
+ m_Handlers.AddLast(*it);
+ }
+ m_ToBeAdded.Clear();
+
+ // and now remove
+ for (XnCallbackPtrList::ConstIterator it = m_ToBeRemoved.begin(); it != m_ToBeRemoved.end(); ++it)
+ {
+ XnCallback* pCallback = *it;
+ RemoveCallback(m_Handlers, pCallback);
+ }
+ m_ToBeRemoved.Clear();
+
+ return (XN_STATUS_OK);
+ }
+
+#if (XN_PLATFORM == XN_PLATFORM_WIN32)
+#pragma warning (push)
+#pragma warning (disable: 4127)
+#endif
+
+ XN_DECLARE_LIST(XnCallback*, XnCallbackPtrList)
+
+#if (XN_PLATFORM == XN_PLATFORM_WIN32)
+#pragma warning (pop)
+#endif
+
+ XN_CRITICAL_SECTION_HANDLE m_hLock;
+ XnCallbackPtrList m_Handlers;
+ XnCallbackPtrList m_ToBeAdded;
+ XnCallbackPtrList m_ToBeRemoved;
+
+private:
+ XnBool RemoveCallback(XnCallbackPtrList& list, XnCallback* pCallback)
+ {
+ XnCallbackPtrList::Iterator handlerIt = list.Find(pCallback);
+ if (handlerIt != list.end())
+ {
+ list.Remove(handlerIt);
+ XN_DELETE(pCallback);
+ return TRUE;
+ }
+
+ return FALSE;
+ }
+};
+
+#define _XN_RAISE_WITH_RET_CODE(args) \
+ { \
+ XnStatus nRetVal = pFunc(args pCallback->pCookie); \
+ if (nRetVal != XN_STATUS_OK) \
+ { \
+ XnEvent::ApplyListChanges(); \
+ return (nRetVal); \
+ } \
+ }
+
+#define _XN_RAISE_NO_RET_CODE(args) \
+ pFunc(args pCallback->pCookie);
+
+/**
+* Declares a class inheriting from XnEvent, that can be used as an event with specific signature.
+* It is highly recommended not to use this macro directly.
+*/
+#define _XN_DECLARE_EVENT_CLASS(_class, _interface, _retVal, _raise, _signature, _raise_sign) \
+ XN_PRAGMA_START_DISABLED_WARNING_SECTION(XN_HIDES_PARENT_METHOD_WARNING_ID) \
+ class _interface : protected XnEvent \
+ { \
+ public: \
+ typedef _retVal (XN_CALLBACK_TYPE* HandlerPtr)(_signature); \
+ virtual XnStatus Register(HandlerPtr pFunc, void* pCookie, XnCallbackHandle* pHandle = NULL) = 0; \
+ virtual XnStatus Unregister(XnCallbackHandle handle) = 0; \
+ }; \
+ class _class : public _interface \
+ { \
+ public: \
+ XnStatus Register(HandlerPtr pFunc, void* pCookie, XnCallbackHandle* pHandle = NULL) \
+ { \
+ return XnEvent::Register((XnEvent::HandlerPtr)pFunc, pCookie, pHandle); \
+ } \
+ XnStatus Unregister(XnCallbackHandle handle) \
+ { \
+ return XnEvent::Unregister(handle); \
+ } \
+ XnStatus Raise(_raise_sign) \
+ { \
+ XnAutoCSLocker lock(m_hLock); \
+ XnEvent::ApplyListChanges(); \
+ XnEvent::XnCallbackPtrList::Iterator it = XnEvent::m_Handlers.begin(); \
+ for (; it != XnEvent::m_Handlers.end(); ++it) \
+ { \
+ XnCallback* pCallback = *it; \
+ HandlerPtr pFunc = (HandlerPtr)pCallback->pFuncPtr; \
+ _raise \
+ } \
+ XnEvent::ApplyListChanges(); \
+ return (XN_STATUS_OK); \
+ } \
+ XnStatus Clear() { return XnEvent::Clear(); } \
+ }; \
+ XN_PRAGMA_STOP_DISABLED_WARNING_SECTION
+
+
+#define _XN_SIGNATURE_0ARG()
+#define _XN_FULL_SIGNATURE_0ARG() void* pCookie
+#define _XN_ARGS_0ARG()
+
+#define _XN_SIGNATURE_1ARG(_type1, _name1) _type1 _name1
+#define _XN_FULL_SIGNATURE_1ARG(_type1, _name1) _type1 _name1, void* pCookie
+#define _XN_ARGS_1ARG(_name1) _name1,
+
+#define _XN_SIGNATURE_2ARG(_type1, _name1, _type2, _name2) _type1 _name1, _type2 _name2
+#define _XN_FULL_SIGNATURE_2ARG(_type1, _name1, _type2, _name2) _type1 _name1, _type2 _name2, void* pCookie
+#define _XN_ARGS_2ARG(_name1, _name2) _name1, _name2,
+
+#define _XN_SIGNATURE_3ARG(_type1, _name1, _type2, _name2, _type3, _name3) _type1 _name1, _type2 _name2, _type3 _name3
+#define _XN_FULL_SIGNATURE_3ARG(_type1, _name1, _type2, _name2, _type3, _name3) _type1 _name1, _type2 _name2, _type3 _name3, void* pCookie
+#define _XN_ARGS_3ARG(_name1, _name2, _name3) _name1, _name2, _name3,
+
+#define _XN_SIGNATURE_4ARG(_type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4) _type1 _name1, _type2 _name2, _type3 _name3, _type4 _name4
+#define _XN_FULL_SIGNATURE_4ARG(_type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4) _type1 _name1, _type2 _name2, _type3 _name3, _type4 _name4, void* pCookie
+#define _XN_ARGS_4ARG(_name1, _name2, _name3, _name4) _name1, _name2, _name3, _name4,
+
+#define _XN_SIGNATURE_5ARG(_type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4, _type5, _name5) _type1 _name1, _type2 _name2, _type3 _name3, _type4 _name4, _type5 _name5
+#define _XN_FULL_SIGNATURE_5ARG(_type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4, _type5, _name5) _type1 _name1, _type2 _name2, _type3 _name3, _type4 _name4, _type5 _name5, void* pCookie
+#define _XN_ARGS_5ARG(_name1, _name2, _name3, _name4, _name5) _name1, _name2, _name3, _name4, _name5,
+
+/** Declares an event class */
+#define XN_DECLARE_EVENT_0ARG(_class, _interface) \
+ _XN_DECLARE_EVENT_CLASS(_class, _interface, void, _XN_RAISE_NO_RET_CODE(_XN_ARGS_0ARG()), _XN_FULL_SIGNATURE_0ARG(), _XN_SIGNATURE_0ARG())
+
+#define XN_DECLARE_EVENT_0ARG_RETVAL(_class, _interface) \
+ _XN_DECLARE_EVENT_CLASS(_class, _interface, XnStatus, _XN_RAISE_WITH_RET_CODE(_XN_ARGS_0ARG()), _XN_FULL_SIGNATURE_0ARG(), _XN_SIGNATURE_0ARG())
+
+#define XN_DECLARE_EVENT_1ARG(_class, _interface, _type1, _name1) \
+ _XN_DECLARE_EVENT_CLASS(_class, _interface, void, _XN_RAISE_NO_RET_CODE(_XN_ARGS_1ARG(_name1)), _XN_FULL_SIGNATURE_1ARG(_type1, _name1), _XN_SIGNATURE_1ARG(_type1, _name1))
+
+#define XN_DECLARE_EVENT_1ARG_RETVAL(_class, _interface, _type1, _name1) \
+ _XN_DECLARE_EVENT_CLASS(_class, _interface, XnStatus, _XN_RAISE_WITH_RET_CODE(_XN_ARGS_1ARG(_name1)), _XN_FULL_SIGNATURE_1ARG(_type1, _name1), _XN_SIGNATURE_1ARG(_type1, _name1))
+
+#define XN_DECLARE_EVENT_2ARG(_class, _interface, _type1, _name1, _type2, _name2) \
+ _XN_DECLARE_EVENT_CLASS(_class, _interface, void, _XN_RAISE_NO_RET_CODE(_XN_ARGS_2ARG(_name1, _name2)), _XN_FULL_SIGNATURE_2ARG(_type1, _name1, _type2, _name2), _XN_SIGNATURE_2ARG(_type1, _name1, _type2, _name2))
+
+#define XN_DECLARE_EVENT_2ARG_RETVAL(_class, _interface, _type1, _name1, _type2, _name2) \
+ _XN_DECLARE_EVENT_CLASS(_class, _interface, XnStatus, _XN_RAISE_WITH_RET_CODE(_XN_ARGS_2ARG(_name1, _name2)), _XN_FULL_SIGNATURE_2ARG(_type1, _name1, _type2, _name2), _XN_SIGNATURE_2ARG(_type1, _name1, _type2, _name2))
+
+#define XN_DECLARE_EVENT_3ARG(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3) \
+ _XN_DECLARE_EVENT_CLASS(_class, _interface, void, _XN_RAISE_NO_RET_CODE(_XN_ARGS_3ARG(_name1, _name2, _name3)), _XN_FULL_SIGNATURE_3ARG(_type1, _name1, _type2, _name2, _type3, _name3), _XN_SIGNATURE_3ARG(_type1, _name1, _type2, _name2, _type3, _name3))
+
+#define XN_DECLARE_EVENT_3ARG_RETVAL(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3) \
+ _XN_DECLARE_EVENT_CLASS(_class, _interface, XnStatus, _XN_RAISE_WITH_RET_CODE(_XN_ARGS_3ARG(_name1, _name2, _name3)), _XN_FULL_SIGNATURE_3ARG(_type1, _name1, _type2, _name2, _type3, _name3), _XN_SIGNATURE_3ARG(_type1, _name1, _type2, _name2, _type3, _name3))
+
+#define XN_DECLARE_EVENT_4ARG(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4) \
+ _XN_DECLARE_EVENT_CLASS(_class, _interface, void, _XN_RAISE_NO_RET_CODE(_XN_ARGS_4ARG(_name1, _name2, _name3, _name4)), _XN_FULL_SIGNATURE_4ARG(_type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4), _XN_SIGNATURE_4ARG(_type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4))
+
+#define XN_DECLARE_EVENT_4ARG_RETVAL(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4) \
+ _XN_DECLARE_EVENT_CLASS(_class, _interface, XnStatus, _XN_RAISE_WITH_RET_CODE(_XN_ARGS_4ARG(_name1, _name2, _name3, _name4)), _XN_FULL_SIGNATURE_4ARG(_type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4), _XN_SIGNATURE_4ARG(_type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4))
+
+#define XN_DECLARE_EVENT_5ARG(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4, _type5, _name5) \
+ _XN_DECLARE_EVENT_CLASS(_class, _interface, void, _XN_RAISE_NO_RET_CODE(_XN_ARGS_5ARG(_name1, _name2, _name3, _name4, _name5)), _XN_FULL_SIGNATURE_5ARG(_type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4, _type5, _name5), _XN_SIGNATURE_5ARG(_type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4, _type5, _name5))
+
+#define XN_DECLARE_EVENT_5ARG_RETVAL(_class, _interface, _type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4, _type5, _name5) \
+ _XN_DECLARE_EVENT_CLASS(_class, _interface, XnStatus, _XN_RAISE_WITH_RET_CODE(_XN_ARGS_5ARG(_name1, _name2, _name3, _name4, _name5)), _XN_FULL_SIGNATURE_5ARG(_type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4, _type5, _name5), _XN_SIGNATURE_5ARG(_type1, _name1, _type2, _name2, _type3, _name3, _type4, _name4, _type5, _name5))
+
+#endif //__XN_EVENT_H__
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnEventT.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnEventT.h
new file mode 100644
index 00000000..f0b6379d
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnEventT.h
@@ -0,0 +1,393 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef _XN_EVENT_T_H_
+#define _XN_EVENT_T_H_
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include "XnOSCpp.h"
+#include "XnListT.h"
+#include "XnTypes.h"
+
+//---------------------------------------------------------------------------
+// Types
+//---------------------------------------------------------------------------
+
+/**
+* A struct for holding a callback function with its cookie
+*
+* @tparam FuncPtr The callback signature
+*/
+template<typename FuncPtr>
+struct XnCallbackT
+{
+ XnCallbackT(FuncPtr func, void* cookie) : pFunc(func), pCookie(cookie) {}
+
+ FuncPtr pFunc;
+ void* pCookie;
+};
+
+/**
+* A class that contains the interface of an event (i.e. Register and Unregister)
+*
+* @tparam FuncPtr The callback signature
+*/
+template<typename FuncPtr>
+class XnEventInterfaceT
+{
+public:
+ typedef FuncPtr HandlerPtr;
+ typedef XnCallbackT<FuncPtr> TCallback;
+ typedef XnEventInterfaceT TInterface;
+
+ ~XnEventInterfaceT()
+ {
+ Clear();
+ xnOSCloseCriticalSection(&m_hLock);
+ }
+
+ XnStatus Register(FuncPtr pFunc, void* pCookie, XnCallbackHandle& hCallback)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ XN_VALIDATE_INPUT_PTR(pFunc);
+
+ TCallback* pCallback = NULL;
+ XN_VALIDATE_NEW(pCallback, TCallback, pFunc, pCookie);
+
+ // always add to list of added (actual list will be updated in Raise method, to allow registering
+ // from a callback).
+ {
+ XnAutoCSLocker locker(m_hLock);
+ nRetVal = m_toAdd.AddLast(pCallback);
+ }
+
+ if (nRetVal != XN_STATUS_OK)
+ {
+ XN_DELETE(pCallback);
+ return nRetVal;
+ }
+
+ // return handle
+ hCallback = (XnCallbackHandle)pCallback;
+
+ return XN_STATUS_OK;
+ }
+
+ XnStatus Unregister(XnCallbackHandle hCallback)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ TCallback* pCallback = (TCallback*)hCallback;
+
+ // add it to a temp list, to allow unregistering from a callback (actual list will be updated in raise
+ // function).
+ {
+ XnAutoCSLocker locker(m_hLock);
+
+ // try to remove it from the ToBeAdded list.
+ if (!RemoveCallback(m_toAdd, pCallback))
+ {
+ // it's not in this list, so it's probably in the main list
+ nRetVal = m_toRemove.AddLast(pCallback);
+ }
+ }
+ XN_IS_STATUS_OK(nRetVal);
+
+ return XN_STATUS_OK;
+ }
+
+protected:
+ typedef XnListT<TCallback*> CallbackPtrList;
+
+ // Constructors are protected, so that this class cannot be instantiated directly.
+ XnEventInterfaceT()
+ {
+ Init();
+ }
+
+ XnEventInterfaceT(const XnEventInterfaceT& other)
+ {
+ Init();
+ *this = other;
+ }
+
+ XnEventInterfaceT& operator=(const XnEventInterfaceT& other)
+ {
+ Clear();
+
+ // lock other one (so it won't change while being copied)
+ XnAutoCSLocker otherLocker(other.m_hLock);
+ // lock this one (we're making changes)
+ XnAutoCSLocker locker(m_hLock);
+
+ m_callbacks = other.m_callbacks;
+ m_toAdd = other.m_toAdd;
+ m_toRemove = other.m_toRemove;
+
+ ApplyListChanges();
+
+ return *this;
+ }
+
+ XnStatus Clear()
+ {
+ XnAutoCSLocker locker(m_hLock);
+ ApplyListChanges();
+
+ for (typename CallbackPtrList::ConstIterator it = m_callbacks.Begin(); it != m_callbacks.End(); ++it)
+ {
+ TCallback* pCallback = *it;
+ XN_DELETE(pCallback);
+ }
+
+ m_callbacks.Clear();
+ m_toRemove.Clear();
+ m_toAdd.Clear();
+ return (XN_STATUS_OK);
+ }
+
+ XnStatus ApplyListChanges()
+ {
+ XnAutoCSLocker locker(m_hLock);
+
+ // first add all
+ for (typename CallbackPtrList::ConstIterator it = m_toAdd.Begin(); it != m_toAdd.End(); ++it)
+ {
+ m_callbacks.AddLast(*it);
+ }
+ m_toAdd.Clear();
+
+ // and now remove
+ for (typename CallbackPtrList::ConstIterator it = m_toRemove.Begin(); it != m_toRemove.End(); ++it)
+ {
+ TCallback* pCallback = *it;
+ RemoveCallback(m_callbacks, pCallback);
+ }
+ m_toRemove.Clear();
+
+ return (XN_STATUS_OK);
+ }
+
+ XnBool RemoveCallback(CallbackPtrList& list, TCallback* pCallback)
+ {
+ typename CallbackPtrList::Iterator it = list.Find(pCallback);
+ if (it != list.End())
+ {
+ list.Remove(it);
+ XN_DELETE(pCallback);
+ return TRUE;
+ }
+
+ return FALSE;
+ }
+
+ XN_CRITICAL_SECTION_HANDLE m_hLock;
+ CallbackPtrList m_callbacks;
+ CallbackPtrList m_toAdd;
+ CallbackPtrList m_toRemove;
+
+private:
+ void Init()
+ {
+ m_hLock = NULL;
+ XnStatus nRetVal = xnOSCreateCriticalSection(&m_hLock);
+ if (nRetVal != XN_STATUS_OK)
+ {
+ XN_ASSERT(FALSE);
+ }
+ }
+};
+
+// Handlers
+struct XnHandlerFuncNoArgs
+{
+ typedef void (XN_CALLBACK_TYPE* FuncPtr)(void* pCookie);
+};
+
+template<class TArg1>
+struct XnHandlerFunc1Arg
+{
+ typedef void (XN_CALLBACK_TYPE* FuncPtr)(TArg1 arg1, void* pCookie);
+};
+
+template<class TArg1, class TArg2>
+struct XnHandlerFunc2Args
+{
+ typedef void (XN_CALLBACK_TYPE* FuncPtr)(TArg1 arg1, TArg2 arg2, void* pCookie);
+};
+
+template<class TArg1, class TArg2, class TArg3>
+struct XnHandlerFunc3Args
+{
+ typedef void (XN_CALLBACK_TYPE* FuncPtr)(TArg1 arg1, TArg2 arg2, TArg3 arg3, void* pCookie);
+};
+
+template<class TArg1, class TArg2, class TArg3, class TArg4>
+struct XnHandlerFunc4Args
+{
+ typedef void (XN_CALLBACK_TYPE* FuncPtr)(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, void* pCookie);
+};
+
+template<class TArg1, class TArg2, class TArg3, class TArg4, class TArg5>
+struct XnHandlerFunc5Args
+{
+ typedef void (XN_CALLBACK_TYPE* FuncPtr)(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5, void* pCookie);
+};
+
+// Event classes (there's a class per number of arguments)
+class XnEventNoArgs : public XnEventInterfaceT<XnHandlerFuncNoArgs::FuncPtr>
+{
+public:
+ XnStatus Raise()
+ {
+ XnAutoCSLocker locker(this->m_hLock);
+ ApplyListChanges();
+
+ for (CallbackPtrList::ConstIterator it = m_callbacks.Begin(); it != m_callbacks.End(); ++it)
+ {
+ TCallback* pCallback = *it;
+ pCallback->pFunc(pCallback->pCookie);
+ }
+
+ ApplyListChanges();
+ return (XN_STATUS_OK);
+ }
+};
+
+
+template<class TArg1>
+class XnEvent1Arg : public XnEventInterfaceT<typename XnHandlerFunc1Arg<TArg1>::FuncPtr>
+{
+ typedef XnEventInterfaceT<typename XnHandlerFunc1Arg<TArg1>::FuncPtr> Base;
+
+public:
+ XnStatus Raise(TArg1 arg)
+ {
+ XnAutoCSLocker locker(this->m_hLock);
+ this->ApplyListChanges();
+
+ for (typename Base::CallbackPtrList::ConstIterator it = this->m_callbacks.Begin(); it != this->m_callbacks.End(); ++it)
+ {
+ typename Base::TCallback* pCallback = *it;
+ pCallback->pFunc(arg, pCallback->pCookie);
+ }
+
+ this->ApplyListChanges();
+ return (XN_STATUS_OK);
+ }
+};
+
+template<class TEventArgs>
+class XnEventT : public XnEvent1Arg<const TEventArgs&>
+{};
+
+template<class TArg1, class TArg2>
+class XnEvent2Args : public XnEventInterfaceT<typename XnHandlerFunc2Args<TArg1, TArg2>::FuncPtr>
+{
+ typedef XnEventInterfaceT<typename XnHandlerFunc2Args<TArg1, TArg2>::FuncPtr> Base;
+
+public:
+ XnStatus Raise(TArg1 arg1, TArg2 arg2)
+ {
+ XnAutoCSLocker locker(this->m_hLock);
+ this->ApplyListChanges();
+
+ for (typename Base::CallbackPtrList::ConstIterator it = this->m_callbacks.Begin(); it != this->m_callbacks.End(); ++it)
+ {
+ typename Base::TCallback* pCallback = *it;
+ pCallback->pFunc(arg1, arg2, pCallback->pCookie);
+ }
+
+ this->ApplyListChanges();
+ return (XN_STATUS_OK);
+ }
+};
+
+template<class TArg1, class TArg2, class TArg3>
+class XnEvent3Args : public XnEventInterfaceT<typename XnHandlerFunc3Args<TArg1, TArg2, TArg3>::FuncPtr>
+{
+ typedef XnEventInterfaceT<typename XnHandlerFunc3Args<TArg1, TArg2, TArg3>::FuncPtr> Base;
+
+public:
+ XnStatus Raise(TArg1 arg1, TArg2 arg2, TArg3 arg3)
+ {
+ XnAutoCSLocker locker(this->m_hLock);
+ this->ApplyListChanges();
+
+ for (typename Base::CallbackPtrList::ConstIterator it = this->m_callbacks.Begin(); it != this->m_callbacks.End(); ++it)
+ {
+ typename Base::TCallback* pCallback = *it;
+ pCallback->pFunc(arg1, arg2, arg3, pCallback->pCookie);
+ }
+
+ this->ApplyListChanges();
+ return (XN_STATUS_OK);
+ }
+};
+
+template<class TArg1, class TArg2, class TArg3, class TArg4>
+class XnEvent4Args : public XnEventInterfaceT<typename XnHandlerFunc4Args<TArg1, TArg2, TArg3, TArg4>::FuncPtr>
+{
+ typedef XnEventInterfaceT<typename XnHandlerFunc4Args<TArg1, TArg2, TArg3, TArg4>::FuncPtr> Base;
+
+public:
+ XnStatus Raise(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4)
+ {
+ XnAutoCSLocker locker(this->m_hLock);
+ this->ApplyListChanges();
+
+ for (typename Base::CallbackPtrList::ConstIterator it = this->m_callbacks.Begin(); it != this->m_callbacks.End(); ++it)
+ {
+ typename Base::TCallback* pCallback = *it;
+ pCallback->pFunc(arg1, arg2, arg3, arg4, pCallback->pCookie);
+ }
+
+ this->ApplyListChanges();
+ return (XN_STATUS_OK);
+ }
+};
+
+template<class TArg1, class TArg2, class TArg3, class TArg4, class TArg5>
+class XnEvent5Args : public XnEventInterfaceT<typename XnHandlerFunc5Args<TArg1, TArg2, TArg3, TArg4, TArg5>::FuncPtr>
+{
+ typedef XnEventInterfaceT<typename XnHandlerFunc5Args<TArg1, TArg2, TArg3, TArg4, TArg5>::FuncPtr> Base;
+
+public:
+ XnStatus Raise(TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4, TArg5 arg5)
+ {
+ XnAutoCSLocker locker(this->m_hLock);
+ this->ApplyListChanges();
+
+ for (typename Base::CallbackPtrList::ConstIterator it = this->m_callbacks.Begin(); it != this->m_callbacks.End(); ++it)
+ {
+ typename Base::TCallback* pCallback = *it;
+ pCallback->pFunc(arg1, arg2, arg3, arg4, arg5, pCallback->pCookie);
+ }
+
+ this->ApplyListChanges();
+ return (XN_STATUS_OK);
+ }
+};
+
+#endif // _XN_EVENT_T_H_ \ No newline at end of file
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnFPSCalculator.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnFPSCalculator.h
new file mode 100644
index 00000000..036694b7
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnFPSCalculator.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef __XN_FPS_CALCULATOR_H__
+#define __XN_FPS_CALCULATOR_H__
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include <XnPlatform.h>
+#include <XnStatus.h>
+
+//---------------------------------------------------------------------------
+// Types
+//---------------------------------------------------------------------------
+struct XnFPSDataImpl;
+typedef struct XnFPSDataImpl* XnFPSData;
+
+//---------------------------------------------------------------------------
+// Exported Functions
+//---------------------------------------------------------------------------
+/**
+* This function initializes the FPS calculator.
+*
+* @param pFPS [in] A pointer to an XnFPSData struct.
+* @param nSamplesCount [in] The number of last frames to be kept.
+*/
+XN_C_API XnStatus XN_C_DECL xnFPSInit(XnFPSData* pFPS, XnUInt32 nSamplesCount);
+
+/**
+* This function marks that another frame was processed.
+*
+* @param pFPS [in] A pointer to an XnFPSData struct.
+* @param nNow [in] Optional. Current time. When not provided, function will take it itself.
+*/
+XN_C_API XnStatus XN_C_DECL xnFPSMarkFrame(XnFPSData* pFPS, XnUInt64 nNow = 0);
+
+/**
+* This function calculates the average FPS over the last frames.
+*
+* @param pFPS [in] A pointer to an XnFPSData struct.
+* @param nAverageOver [in] The number of milliseconds to average over.
+* @param nNow [in] Optional. Current time. When not provided, function will take it itself.
+*/
+XN_C_API XnDouble XN_C_DECL xnFPSCalc(XnFPSData* pFPS, XnUInt32 nAverageOver = 3000, XnUInt64 nNow = 0);
+
+/**
+* This function frees the FPS calculator.
+*
+* @param pFPS [in] A pointer to an XnFPSData struct.
+*/
+XN_C_API XnStatus XN_C_DECL xnFPSFree(XnFPSData* pFPS);
+
+#endif //__XN_FPS_CALCULATOR_H__
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnGeneralBuffer.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnGeneralBuffer.h
new file mode 100644
index 00000000..4c6b3c77
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnGeneralBuffer.h
@@ -0,0 +1,119 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef __XN_GENERAL_BUFFER_H__
+#define __XN_GENERAL_BUFFER_H__
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include "XnPlatform.h"
+#include "XnOS.h"
+#include "XnStatusCodes.h"
+
+//---------------------------------------------------------------------------
+// Types
+//---------------------------------------------------------------------------
+
+/* Describes a general buffer. */
+typedef struct XnGeneralBuffer
+{
+ /* A pointer to the actual data. */
+ void* pData;
+ /* The size of the data in bytes. */
+ XnUInt32 nDataSize;
+} XnGeneralBuffer;
+
+//---------------------------------------------------------------------------
+// Exported Functions
+//---------------------------------------------------------------------------
+
+/**
+* Packs a pointer and a size into an XnGeneralBuffer struct.
+*/
+inline XnGeneralBuffer XnGeneralBufferPack(void* pData, XnUInt32 nDataSize)
+{
+ XnGeneralBuffer result;
+ result.pData = pData;
+ result.nDataSize = nDataSize;
+ return result;
+}
+
+/**
+* Copies one general buffer into another.
+*/
+inline XnStatus XnGeneralBufferCopy(XnGeneralBuffer* pDest, const XnGeneralBuffer* pSrc)
+{
+ XN_VALIDATE_INPUT_PTR(pDest);
+ XN_VALIDATE_INPUT_PTR(pSrc);
+
+ if (pSrc->nDataSize > pDest->nDataSize)
+ return XN_STATUS_OUTPUT_BUFFER_OVERFLOW;
+
+ xnOSMemCopy(pDest->pData, pSrc->pData, pSrc->nDataSize);
+ pDest->nDataSize = pSrc->nDataSize;
+ return XN_STATUS_OK;
+}
+
+inline XnStatus XnGeneralBufferAlloc(XnGeneralBuffer* pDest, XnUInt32 nSize)
+{
+ XN_VALIDATE_INPUT_PTR(pDest);
+
+ void* pData;
+ pData = xnOSMalloc(nSize);
+ XN_VALIDATE_ALLOC_PTR(pData);
+
+ pDest->pData = pData;
+ pDest->nDataSize = nSize;
+ return XN_STATUS_OK;
+}
+
+inline XnStatus XnGeneralBufferRealloc(XnGeneralBuffer* pDest, XnUInt32 nSize)
+{
+ XN_VALIDATE_INPUT_PTR(pDest);
+
+ void* pData;
+ pData = xnOSRealloc(pDest, nSize);
+ XN_VALIDATE_ALLOC_PTR(pData);
+
+ pDest->pData = pData;
+ pDest->nDataSize = nSize;
+ return XN_STATUS_OK;
+}
+
+inline void XnGeneralBufferFree(XnGeneralBuffer* pDest)
+{
+ XN_FREE_AND_NULL(pDest->pData);
+ pDest->nDataSize = 0;
+}
+
+//---------------------------------------------------------------------------
+// Helper Macros
+//---------------------------------------------------------------------------
+#define XN_PACK_GENERAL_BUFFER(x) XnGeneralBufferPack(&x, sizeof(x))
+
+#define XN_VALIDATE_GENERAL_BUFFER_TYPE(gb, t) \
+ if ((gb).nDataSize != sizeof(t)) \
+ { \
+ return XN_STATUS_INVALID_BUFFER_SIZE; \
+ }
+
+#endif //__XN_GENERAL_BUFFER_H__ \ No newline at end of file
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnHash.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnHash.h
new file mode 100644
index 00000000..7cc719f2
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnHash.h
@@ -0,0 +1,1014 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef _XN_HASH_H
+#define _XN_HASH_H
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include "XnList.h"
+
+//---------------------------------------------------------------------------
+// Defines
+//---------------------------------------------------------------------------
+#define XN_HASH_LAST_BIN 256
+#define XN_HASH_NUM_BINS (XN_HASH_LAST_BIN + 1)
+//---------------------------------------------------------------------------
+// Types
+//---------------------------------------------------------------------------
+/**
+* The key to the hash
+*/
+typedef XnValue XnKey;
+
+/**
+* The hash value - the output of the hash function
+*/
+typedef XnUInt8 XnHashValue;
+
+/**
+* Default Hash function
+*/
+static XnHashValue XnDefaultHashFunction(const XnKey& key)
+{
+ return (XnSizeT(key) & 0xff);
+}
+
+/**
+* Default Compare function
+*/
+static XnInt32 XnDefaultCompareFunction(const XnKey& key1, const XnKey& key2)
+{
+ return XnInt32(XnSizeT(key1)-XnSizeT(key2));
+}
+
+/**
+ * The hash - associative array
+ */
+class XnHash
+{
+public:
+ /**
+ * Iterator to the XnHash
+ */
+ class ConstIterator
+ {
+ public:
+ friend class XnHash;
+
+ /**
+ * Copy constructor
+ *
+ * @param other [in] instance to copy from
+ */
+ ConstIterator(const ConstIterator& other) :
+ m_pHash(other.m_pHash), m_nCurrentBin(other.m_nCurrentBin), m_Iterator(other.m_Iterator) {}
+
+ /**
+ * Support ++iterator, go to the next object in the hash
+ */
+ ConstIterator& operator++()
+ {
+ ++m_Iterator;
+
+ while (m_Iterator == m_pHash->m_Bins[m_nCurrentBin]->end() &&
+ m_Iterator != m_pHash->m_Bins[XN_HASH_LAST_BIN]->end())
+ {
+ do
+ {
+ m_nCurrentBin++;
+ } while (m_pHash->m_Bins[m_nCurrentBin] == NULL);
+ m_Iterator = m_pHash->m_Bins[m_nCurrentBin]->begin();
+ }
+ return *this;
+ }
+
+ /**
+ * Support iterator++, go to the next object in the hash, returning the old value
+ */
+ ConstIterator operator++(int)
+ {
+ XnHash::ConstIterator other(*this);
+ ++*this;
+ return other;
+ }
+
+ /**
+ * Support --iterator, go to the previous object in the hash
+ */
+ ConstIterator& operator--()
+ {
+ --m_Iterator;
+
+ while (m_Iterator == m_pHash->m_Bins[m_nCurrentBin]->end() &&
+ m_Iterator != m_pHash->m_Bins[XN_HASH_LAST_BIN]->end())
+ {
+ do
+ {
+ if (m_nCurrentBin == 0)
+ {
+ m_nCurrentBin = XN_HASH_LAST_BIN;
+ m_Iterator = m_pHash->m_Bins[XN_HASH_LAST_BIN]->end();
+ return *this;
+ }
+ m_nCurrentBin--;
+ } while (m_pHash->m_Bins[m_nCurrentBin] == NULL);
+ m_Iterator = m_pHash->m_Bins[m_nCurrentBin]->rbegin();
+ }
+ return *this;
+ }
+
+ /**
+ * Support iterator--, go to the previous object in the hash, returning the old value
+ */
+ ConstIterator operator--(int)
+ {
+ ConstIterator other(*this);
+ --*this;
+ return other;
+ }
+
+ /**
+ * Operator to check if 2 iterators point to the same object
+ *
+ * @param other [in] instance to compare with
+ */
+ XnBool operator==(const ConstIterator& other) const
+ {
+ return m_Iterator == other.m_Iterator;
+ }
+
+ /**
+ * Operator to check if 2 iterators point to different objects
+ *
+ * @param other [in] instance to compare with
+ */
+ XnBool operator!=(const ConstIterator& other) const
+ {
+ return m_Iterator != other.m_Iterator;
+ }
+
+ /**
+ * Get the key of the current object (const version)
+ */
+ const XnKey& Key() const
+ {
+ return ((XnNode*)(*m_Iterator))->Data();
+ }
+
+ /**
+ * Get the value of the current object (const version)
+ */
+ const XnValue& Value() const
+ {
+ return ((XnNode*)(*m_Iterator))->Next()->Data();
+ }
+
+ /**
+ * Get the entire current object (non-const version)
+ */
+ XnNode* GetNode()
+ {
+ return m_Iterator.GetNode();
+ }
+
+ /**
+ * Get the entire current object (const version)
+ */
+ const XnNode* GetNode() const
+ {
+ return m_Iterator.GetNode();
+ }
+
+ protected:
+ /**
+ * constructor to be used from inside the XnHash
+ *
+ * @param pHash [in] The hash to which the iterator belongs
+ * @param nBin [in] The bin of the current object
+ * @param listIterator [in] Iterator on the bin (each bin is a XnList)
+ */
+ ConstIterator(const XnHash* pHash, XnUInt16 nBin, XnList::Iterator listIterator) :
+ m_pHash(pHash), m_nCurrentBin(nBin), m_Iterator(listIterator)
+ {
+ // Find the first valid
+ while (m_Iterator == m_pHash->m_Bins[m_nCurrentBin]->end() &&
+ m_Iterator != m_pHash->m_Bins[XN_HASH_LAST_BIN]->end())
+ {
+ do
+ {
+ m_nCurrentBin++;
+ } while (m_pHash->m_Bins[m_nCurrentBin] == NULL);
+ m_Iterator = m_pHash->m_Bins[m_nCurrentBin]->begin();
+ }
+ }
+
+ /**
+ * constructor to be used from inside the XnHash. It points to the first value in the hash.
+ *
+ * @param pHash [in] The hash to which the iterator belongs
+ */
+ ConstIterator(const XnHash* pHash) :
+ m_pHash(pHash), m_nCurrentBin(0), m_Iterator(m_pHash->m_Bins[XN_HASH_LAST_BIN]->end()) {}
+
+ /** The hash to which the iterator belongs */
+ const XnHash* m_pHash;
+ /** The bin of the current object */
+ XnUInt16 m_nCurrentBin;
+ /** Iterator for the specific bin */
+ XnList::Iterator m_Iterator;
+ };
+
+ /**
+ * Iterator to the XnHash
+ */
+ class Iterator : public ConstIterator
+ {
+ public:
+ friend class XnHash;
+
+ /**
+ * Copy constructor
+ *
+ * @param other [in] instance to copy from
+ */
+ inline Iterator(const Iterator& other) : ConstIterator(other) {}
+
+ /**
+ * Support ++iterator, go to the next object in the list
+ */
+ inline Iterator& operator++()
+ {
+ ++(*(ConstIterator*)this);
+ return (*this);
+ }
+ /**
+ * Support iterator++, go to the next object in the list, returning the old value
+ */
+ inline Iterator operator++(int)
+ {
+ Iterator result = *this;
+ ++*this;
+ return (result);
+ }
+
+ /**
+ * Support --iterator, go to the next object in the list
+ */
+ inline Iterator& operator--()
+ {
+ --(*(ConstIterator*)this);
+ return (*this);
+ }
+ /**
+ * Support iterator--, go to the next object in the list, returning the old value
+ */
+ inline Iterator operator--(int)
+ {
+ Iterator result = *this;
+ --*this;
+ return (result);
+ }
+
+ /**
+ * Get the key of the current object (const version)
+ */
+ XnKey& Key() const { return (XnKey&)ConstIterator::Key(); }
+
+ /**
+ * Get the value of the current object (const version)
+ */
+ XnValue& Value() const { return (XnValue&)ConstIterator::Value(); }
+
+ protected:
+ /**
+ * constructor to be used from inside the XnHash
+ *
+ * @param pHash [in] The hash to which the iterator belongs
+ * @param nBin [in] The bin of the current object
+ * @param listIterator [in] Iterator on the bin (each bin is a XnList)
+ */
+ Iterator(const XnHash* pHash, XnUInt16 nBin, XnList::Iterator listIterator) :
+ ConstIterator(pHash, nBin, listIterator)
+ {}
+
+ /**
+ * constructor to be used from inside the XnHash. It points to the first value in the hash.
+ *
+ * @param pHash [in] The hash to which the iterator belongs
+ */
+ Iterator(const XnHash* pHash) : ConstIterator(pHash) {}
+
+ Iterator(const ConstIterator& other) : ConstIterator(other) {}
+ };
+
+ friend class ConstIterator;
+
+public:
+ /**
+ * Definition of a hash function - receive key, and outputs HashValue
+ */
+ typedef XnHashValue (*XnHashFunction)(const XnKey& key);
+ /**
+ * Definition of comparison function - receives 2 keys, returns 0 on equality
+ */
+ typedef XnInt32 (*XnCompareFunction)(const XnKey& key1, const XnKey& key2);
+
+ /**
+ * Constructor. Initializes internal representations.
+ */
+ XnHash()
+ {
+ m_nInitStatus = Init();
+ }
+
+ /**
+ * Destructor. Destroys internal representations.
+ */
+ virtual ~XnHash()
+ {
+ if (m_Bins != NULL)
+ {
+ for (int i = 0; i < XN_HASH_NUM_BINS; ++i)
+ {
+ XN_DELETE(m_Bins[i]);
+ }
+ XN_DELETE_ARR(m_Bins);
+ }
+ }
+
+ /**
+ * Returns the status of the initialization of the hash.
+ * @returns XN_STATUS_OK if the hash was initialized successfully, or an error code otherwise
+ * (e.g. if memory could not be allocated).
+ */
+ XnStatus GetInitStatus() const
+ {
+ return m_nInitStatus;
+ }
+
+ /**
+ * Set a new key-value entry. If key exists, will replace value.
+ *
+ * @param key [in] The key to which to associate the value
+ * @param value [in] The value to add to the XnHash
+ */
+ XnStatus Set(const XnKey& key, const XnValue& value)
+ {
+ XnHashValue HashValue = (*m_HashFunction)(key);
+
+ // Check if key already exists
+ if (m_Bins[HashValue] != NULL)
+ {
+ Iterator hiter(this);
+ if (Find(key, HashValue, hiter) == XN_STATUS_OK)
+ {
+ // Replace value
+ hiter.Value() = value;
+ return XN_STATUS_OK;
+ }
+ }
+ else
+ {
+ // First time trying to access this bin, create it.
+ m_Bins[HashValue] = XN_NEW(XnList);
+ if (m_Bins[HashValue] == NULL)
+ {
+ return XN_STATUS_ALLOC_FAILED;
+ }
+ if (HashValue < m_nMinBin)
+ m_nMinBin = HashValue;
+ }
+
+ // Get a new node for the key
+ XnNode* pKeyNode = XnNode::Allocate();
+ if (pKeyNode == NULL)
+ {
+ return XN_STATUS_ALLOC_FAILED;
+ }
+ pKeyNode->Data() = key;
+
+ // Get a new node for the value
+ XnNode* pValueNode = XnNode::Allocate();
+ if (pValueNode == NULL)
+ {
+ XnNode::Deallocate(pKeyNode);
+ return XN_STATUS_ALLOC_FAILED;
+ }
+ pValueNode->Data() = value;
+
+ // Concatenate the value node to the key node
+ pKeyNode->Next() = pValueNode;
+ pValueNode->Next() = NULL;
+
+ // Add the 2 nodes as the value to the key's list
+ XnStatus ListStatus = m_Bins[HashValue]->AddLast(XnValue(pKeyNode));
+ if (ListStatus != XN_STATUS_OK)
+ {
+ // Add failed. return the 2 nodes to the pool
+ XnNode::Deallocate(pKeyNode);
+ XnNode::Deallocate(pValueNode);
+ return ListStatus;
+ }
+
+ return XN_STATUS_OK;
+ }
+
+ /**
+ * Get the value associated with the supplied key
+ *
+ * @param key [in] The key of the entry
+ * @param value [out] The retrieved value
+ *
+ * @return XN_STATUS_NO_MATCH if no such key exists
+ */
+ XnStatus Get(const XnKey& key, XnValue& value) const
+ {
+ // Check if key exists
+ Iterator hiter(this);
+ XnStatus FindStatus = Find(key, hiter);
+ if (FindStatus != XN_STATUS_OK)
+ {
+ // Key doesn't exist!
+ return FindStatus;
+ }
+ value = hiter.Value();
+
+ return XN_STATUS_OK;
+ }
+
+ /**
+ * Remove a key-value entry from the XnHash
+ *
+ * @param key [in] The key of the entry
+ * @param value [out] The value that was in the removed entry
+
+ * @return XN_STATUS_NO_MATCH if no such key exists
+ */
+ XnStatus Remove(const XnKey& key, XnValue& value)
+ {
+ // find the entry to which the key belongs
+ Iterator hiter(this);
+
+ XnStatus FindStatus = Find(key, hiter);
+ if (FindStatus != XN_STATUS_OK)
+ {
+ // no such entry!
+ return FindStatus;
+ }
+
+ // Remove by iterator
+ value = hiter.Value();
+ return Remove(hiter);
+ }
+
+ /**
+ * Remove an entry from the XnHash by iterator
+ *
+ * @param iter [in] Iterator pointing to an entry in the hash
+ * @param key [out] The key that was in the removed entry
+ * @param value [out] The value that was in the removed entry
+ *
+ * @return XN_STATUS_ILLEGAL_POSITION if iterator is invalid
+ */
+ XnStatus Remove(ConstIterator iter, XnKey& key, XnValue& value)
+ {
+ if (iter == end())
+ {
+ // Can't remove invalid node
+ return XN_STATUS_ILLEGAL_POSITION;
+ }
+
+ // Get value and key, to return to the caller
+ value = iter.Value();
+ key = iter.Key();
+
+ return Remove(iter);
+ }
+
+ /**
+ * Remove an entry from the XnHash by iterator
+ *
+ * @param iter [in] Iterator pointing to an entry in the hash
+ *
+ * @return XN_STATUS_ILLEGAL_POSITION if iterator is invalid
+ */
+ virtual XnStatus Remove(ConstIterator iter)
+ {
+ if (iter == end())
+ {
+ // Can't remove invalid node
+ return XN_STATUS_ILLEGAL_POSITION;
+ }
+
+ XnNode* pNode = iter.GetNode();
+
+ XnNode* pKeyNode = (XnNode*)(pNode->Data());
+ XnNode* pValueNode = pKeyNode->Next();
+
+ // Return the nodes to the pool
+ XnNode::Deallocate(pKeyNode);
+ XnNode::Deallocate(pValueNode);
+
+ pNode->Previous()->Next() = pNode->Next();
+ pNode->Next()->Previous() = pNode->Previous();
+
+ XnNode::Deallocate(pNode);
+
+ return XN_STATUS_OK;
+ }
+
+
+ /**
+ * Remove all entries from the XnHash.
+ */
+ XnStatus Clear()
+ {
+ while (begin() != end())
+ Remove(begin());
+
+ return XN_STATUS_OK;
+ }
+
+ /**
+ * Checks if hash is empty.
+ */
+ XnBool IsEmpty() const
+ {
+ return (begin() == end());
+ }
+
+ /**
+ * Gets the number of entries in the hash.
+ */
+ XnUInt32 Size() const
+ {
+ XnUInt32 nSize = 0;
+ for (Iterator iter = begin(); iter != end(); ++iter, ++nSize)
+ ;
+
+ return nSize;
+ }
+
+ /**
+ * Get an iterator pointing to the entry to which the key belongs
+ *
+ * @param key [in] The key of the entry
+ * @param hiter [out] Iterator to the entry described by key
+ *
+ * @return XN_STATUS_NO_MATCH No such key in the XnHash
+ */
+ XnStatus Find(const XnKey& key, ConstIterator& hiter) const
+ {
+ return ConstFind(key, hiter);
+ }
+
+ /**
+ * Get an iterator pointing to the entry to which the key belongs
+ *
+ * @param key [in] The key of the entry
+ * @param hiter [out] Iterator to the entry described by key
+ *
+ * @return XN_STATUS_NO_MATCH No such key in the XnHash
+ */
+ XnStatus Find(const XnKey& key, Iterator& hiter)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ ConstIterator& it = hiter;
+ nRetVal = ConstFind(key, it);
+ XN_IS_STATUS_OK(nRetVal);
+
+ return (XN_STATUS_OK);
+ }
+
+ /**
+ * Get an iterator to the beginning of the XnHash (non-const version)
+ */
+ Iterator begin()
+ {
+ return Iterator(this, m_nMinBin, m_Bins[m_nMinBin]->begin());
+ }
+
+ /**
+ * Get an iterator to the beginning of the XnHash (const version)
+ */
+ ConstIterator begin() const
+ {
+ return ConstIterator(this, m_nMinBin, m_Bins[m_nMinBin]->begin());
+ }
+
+ /**
+ * Get an iterator to the end of the XnHash (position is invalid) (non-const version)
+ */
+ Iterator end()
+ {
+ return Iterator(this, XN_HASH_LAST_BIN, m_Bins[XN_HASH_LAST_BIN]->end());
+ }
+
+ /**
+ * Get an iterator to the end of the XnHash (position is invalid) (const version)
+ */
+ ConstIterator end() const
+ {
+ return ConstIterator(this, XN_HASH_LAST_BIN, m_Bins[XN_HASH_LAST_BIN]->end());
+ }
+
+ /**
+ * Change the hash function. The XnHash must be empty for this to succeed.
+ *
+ * @param hashFunction [in] The new hash function
+ *
+ * @return XN_STATUS_IS_NOT_EMPTY if the XnHash isn't empty
+ */
+ XnStatus SetHashFunction(XnHashFunction hashFunction)
+ {
+ if (begin() != end())
+ {
+ return XN_STATUS_IS_NOT_EMPTY;
+ }
+ m_HashFunction = hashFunction;
+ return XN_STATUS_OK;
+ }
+
+ /**
+ * Change the comparison function. The XnHash must be empty for this to succeed.
+ *
+ * @param compareFunction [in] The new hash function
+ *
+ * @return XN_STATUS_IS_NOT_EMPTY if the XnHash isn't empty
+ */
+ XnStatus SetCompareFunction(XnCompareFunction compareFunction)
+ {
+ if (begin() != end())
+ {
+ return XN_STATUS_IS_NOT_EMPTY;
+ }
+ m_CompareFunction = compareFunction;
+ return XN_STATUS_OK;
+ }
+
+protected:
+
+ XnStatus Init()
+ {
+ m_Bins = XN_NEW_ARR(XnList*, XN_HASH_NUM_BINS);
+ XN_VALIDATE_ALLOC_PTR(m_Bins);
+
+ for (int i = 0; i < XN_HASH_NUM_BINS; i++)
+ {
+ m_Bins[i] = NULL;
+ }
+
+ m_Bins[XN_HASH_LAST_BIN] = XN_NEW(XnList); // We need this for an end() iterator
+ m_nMinBin = XN_HASH_LAST_BIN;
+
+ XN_VALIDATE_ALLOC_PTR(m_Bins[XN_HASH_LAST_BIN]);
+ m_CompareFunction = &XnDefaultCompareFunction;
+ m_HashFunction = &XnDefaultHashFunction;
+ return XN_STATUS_OK;
+ }
+
+ /**
+ * Get an iterator pointing to the entry to which the key belongs
+ *
+ * @param key [in] The key of the entry
+ * @param hashValue [in] The hash value of the key
+ * @param hiter [out] Iterator to the entry described by key
+ *
+ * @return XN_STATUS_NO_MATCH No such key in the XnHash
+ */
+ XnStatus Find(const XnKey& key, XnHashValue hashValue, ConstIterator& hiter) const
+ {
+ if (m_Bins[hashValue] != NULL)
+ {
+ hiter = ConstIterator(this, hashValue, m_Bins[hashValue]->begin());
+ for (XnList::ConstIterator iter = m_Bins[hashValue]->begin();
+ iter != m_Bins[hashValue]->end(); ++iter, ++hiter)
+ {
+ if ((*m_CompareFunction)(key, hiter.Key()) == 0)
+ return XN_STATUS_OK;
+ }
+ }
+
+ return XN_STATUS_NO_MATCH;
+ }
+
+
+ /** Each bin is a XnList */
+ XnList** m_Bins;
+
+ XnUInt16 m_nMinBin;
+
+ /* Status of initialization - could be an error if memory could not be allocated. */
+ XnStatus m_nInitStatus;
+
+ /** The current hash function */
+ XnHashFunction m_HashFunction;
+ /** The current comparison function */
+ XnCompareFunction m_CompareFunction;
+
+private:
+ XN_DISABLE_COPY_AND_ASSIGN(XnHash);
+
+ XnStatus ConstFind(const XnKey& key, ConstIterator& hiter) const
+ {
+ XnHashValue HashValue = (*m_HashFunction)(key);
+ return Find(key, HashValue, hiter);
+ }
+};
+
+/**
+* Declares a default Key Manager for type @a KeyType. It is given the name @a ClassName.
+* The manager uses the translator @a KeyTranslator, and is declared using the @a decl declspec.
+*/
+#define XN_DECLARE_DEFAULT_KEY_MANAGER_DECL(decl, KeyType, ClassName, KeyTranslator) \
+ class decl ClassName \
+ { \
+ public: \
+ inline static XnHashValue Hash(KeyType const& key) \
+ { \
+ const XnKey _key = KeyTranslator::GetAsValue(key); \
+ return XnDefaultHashFunction(_key); \
+ } \
+ inline static XnInt32 Compare(KeyType const& key1, KeyType const& key2) \
+ { \
+ const XnKey _key1 = KeyTranslator::GetAsValue(key1); \
+ const XnKey _key2 = KeyTranslator::GetAsValue(key2); \
+ return XnDefaultCompareFunction(_key1, _key2); \
+ } \
+ };
+
+/**
+* Declares a default Key Manager for type @a KeyType. It is given the name @a ClassName.
+* The manager uses the translator @a KeyTranslator.
+*/
+#define XN_DECLARE_DEFAULT_KEY_MANAGER(KeyType, ClassName, KeyTranslator) \
+ XN_DECLARE_DEFAULT_KEY_MANAGER_DECL(, KeyType, ClassName, KeyTranslator)
+
+/**
+* Declares a hash table from @a KeyType to @a ValueType named @a ClassName. The hash table uses
+* @a KeyTranslator and @a ValueTranslator for storing keys and values, and @a KeyManager for managing the keys.
+* It is declared using the @a decl declspec.
+*/
+#define XN_DECLARE_HASH_DECL(decl, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator, KeyManager) \
+ class decl ClassName : public XnHash \
+ { \
+ public: \
+ class decl ConstIterator : public XnHash::ConstIterator \
+ { \
+ public: \
+ friend class ClassName; \
+ inline ConstIterator(const ConstIterator& other) : XnHash::ConstIterator(other) {} \
+ inline ConstIterator& operator++() \
+ { \
+ ++(*(XnHash::ConstIterator*)this); \
+ return (*this); \
+ } \
+ inline ConstIterator operator++(int) \
+ { \
+ ConstIterator result = *this; \
+ ++*this; \
+ return result; \
+ } \
+ inline ConstIterator& operator--() \
+ { \
+ --(*(XnHash::ConstIterator*)this); \
+ return (*this); \
+ } \
+ inline ConstIterator operator--(int) \
+ { \
+ ConstIterator result = *this; \
+ --*this; \
+ return result; \
+ } \
+ inline KeyType const& Key() const \
+ { \
+ return KeyTranslator::GetFromValue(XnHash::ConstIterator::Key()); \
+ } \
+ inline ValueType const& Value() const \
+ { \
+ return ValueTranslator::GetFromValue(XnHash::ConstIterator::Value()); \
+ } \
+ protected: \
+ inline ConstIterator(const XnHash::ConstIterator& other) : \
+ XnHash::ConstIterator(other) {} \
+ }; \
+ class decl Iterator : public ConstIterator \
+ { \
+ public: \
+ friend class ClassName; \
+ inline Iterator(const Iterator& other) : ConstIterator(other) {} \
+ inline Iterator& operator++() \
+ { \
+ ++(*(ConstIterator*)this); \
+ return (*this); \
+ } \
+ inline Iterator operator++(int) \
+ { \
+ Iterator result = *this; \
+ ++*this; \
+ return result; \
+ } \
+ inline Iterator& operator--() \
+ { \
+ --(*(ConstIterator*)this); \
+ return (*this); \
+ } \
+ inline Iterator operator--(int) \
+ { \
+ Iterator result = *this; \
+ --*this; \
+ return result; \
+ } \
+ inline KeyType& Key() const \
+ { \
+ return (KeyType&)ConstIterator::Key(); \
+ } \
+ inline ValueType& Value() const \
+ { \
+ return (ValueType&)ConstIterator::Value(); \
+ } \
+ protected: \
+ inline Iterator(const XnHash::Iterator& other) : ConstIterator(other) {} \
+ }; \
+ public: \
+ ClassName() \
+ { \
+ SetHashFunction(Hash); \
+ SetCompareFunction(Compare); \
+ } \
+ virtual ~ClassName() \
+ { \
+ while (!IsEmpty()) \
+ Remove(begin()); \
+ } \
+ XnStatus Set(KeyType const& key, ValueType const& value) \
+ { \
+ Iterator oldIt = begin(); \
+ if (Find(key, oldIt) == XN_STATUS_OK) \
+ { \
+ oldIt.Value() = value; \
+ } \
+ else \
+ { \
+ XnKey _key = KeyTranslator::CreateValueCopy(key); \
+ XnValue _value = ValueTranslator::CreateValueCopy(value); \
+ XnStatus nRetVal = XnHash::Set(_key, _value); \
+ if (nRetVal != XN_STATUS_OK) \
+ { \
+ KeyTranslator::FreeValue(_key); \
+ ValueTranslator::FreeValue(_value); \
+ return (nRetVal); \
+ } \
+ } \
+ return XN_STATUS_OK; \
+ } \
+ XnStatus Get(KeyType const& key, ValueType& value) const \
+ { \
+ XnKey _key = KeyTranslator::GetAsValue(key); \
+ XnValue _value; \
+ XnStatus nRetVal = XnHash::Get(_key, _value); \
+ if (nRetVal != XN_STATUS_OK) return (nRetVal); \
+ value = ValueTranslator::GetFromValue(_value); \
+ return XN_STATUS_OK; \
+ } \
+ XnStatus Get(KeyType const& key, ValueType*& pValue) const \
+ { \
+ XnKey _key = KeyTranslator::GetAsValue(key); \
+ XnValue _value; \
+ XnStatus nRetVal = XnHash::Get(_key, _value); \
+ if (nRetVal != XN_STATUS_OK) return (nRetVal); \
+ pValue = &ValueTranslator::GetFromValue(_value); \
+ return XN_STATUS_OK; \
+ } \
+ XnStatus Remove(KeyType const& key) \
+ { \
+ ValueType dummy; \
+ return Remove(key, dummy); \
+ } \
+ XnStatus Remove(KeyType const& key, ValueType& value) \
+ { \
+ ConstIterator it = end(); \
+ XnStatus nRetVal = Find(key, it); \
+ if (nRetVal != XN_STATUS_OK) return (nRetVal); \
+ value = it.Value(); \
+ return Remove(it); \
+ } \
+ inline XnStatus Remove(ConstIterator iter) \
+ { \
+ XnKey key = KeyTranslator::GetAsValue(iter.Key()); \
+ XnValue value = ValueTranslator::GetAsValue(iter.Value()); \
+ XnStatus nRetVal = XnHash::Remove(iter); \
+ if (nRetVal != XN_STATUS_OK) return (nRetVal); \
+ KeyTranslator::FreeValue(key); \
+ ValueTranslator::FreeValue(value); \
+ return XN_STATUS_OK; \
+ } \
+ XnStatus Find(KeyType const& key, ConstIterator& hiter) const \
+ { \
+ XnKey _key = KeyTranslator::GetAsValue(key); \
+ XnHash::ConstIterator it = XnHash::end(); \
+ XnStatus nRetVal = XnHash::Find(_key, it); \
+ if (nRetVal != XN_STATUS_OK) return (nRetVal); \
+ hiter = it; \
+ return XN_STATUS_OK; \
+ } \
+ XnStatus Find(KeyType const& key, Iterator& hiter) \
+ { \
+ XnKey _key = KeyTranslator::GetAsValue(key); \
+ XnHash::Iterator it = XnHash::end(); \
+ XnStatus nRetVal = XnHash::Find(_key, it); \
+ if (nRetVal != XN_STATUS_OK) return (nRetVal); \
+ hiter = it; \
+ return XN_STATUS_OK; \
+ } \
+ inline Iterator begin() { return XnHash::begin(); } \
+ inline ConstIterator begin() const { return XnHash::begin(); } \
+ inline Iterator end() { return XnHash::end(); } \
+ inline ConstIterator end() const { return XnHash::end(); } \
+ protected: \
+ virtual XnStatus Remove(XnHash::ConstIterator iter) \
+ { \
+ return Remove(ConstIterator(iter)); \
+ } \
+ inline static XnHashValue Hash(const XnKey& key) \
+ { \
+ KeyType const& _key = KeyTranslator::GetFromValue(key); \
+ return KeyManager::Hash(_key); \
+ } \
+ inline static XnInt32 Compare(const XnKey& key1, const XnKey& key2) \
+ { \
+ KeyType const _key1 = KeyTranslator::GetFromValue(key1); \
+ KeyType const _key2 = KeyTranslator::GetFromValue(key2); \
+ return KeyManager::Compare(_key1, _key2); \
+ } \
+ private: \
+ XN_DISABLE_COPY_AND_ASSIGN(ClassName); \
+ };
+
+/**
+* Declares a hash table from @a KeyType to @a ValueType named @a ClassName. The hash table uses
+* @a KeyTranslator and @a ValueTranslator for storing keys and values, and @a KeyManager for managing the keys.
+*/
+#define XN_DECLARE_HASH(KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator, KeyManager) \
+ XN_DECLARE_HASH_DECL(, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator, KeyManager)
+
+#define _XN_DEFAULT_KEY_MANAGER_NAME(ClassName) _##ClassName##Manager
+
+/**
+* Declares a hash table from @a KeyType to @a ValueType named @a ClassName. The hash table uses
+* @a KeyTranslator and @a ValueTranslator for storing keys and values. It declares and uses a default manager.
+* It is declared using the @a decl declspec.
+*/
+#define XN_DECLARE_DEFAULT_MANAGER_HASH_DECL(decl, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator) \
+ XN_DECLARE_DEFAULT_KEY_MANAGER_DECL(decl, KeyType, _XN_DEFAULT_KEY_MANAGER_NAME(ClassName), KeyTranslator) \
+ XN_DECLARE_HASH_DECL(decl, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator, _XN_DEFAULT_KEY_MANAGER_NAME(ClassName))
+
+/**
+* Declares a hash table from @a KeyType to @a ValueType named @a ClassName. The hash table uses
+* @a KeyTranslator and @a ValueTranslator for storing keys and values. It declares and uses a default manager.
+*/
+#define XN_DECLARE_DEFAULT_MANAGER_HASH(decl, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator) \
+ XN_DECLARE_DEFAULT_MANAGER_HASH_DECL(, KeyType, ValueType, ClassName, KeyTranslator, ValueTranslator)
+
+#define _XN_DEFAULT_KEY_TRANSLATOR(ClassName) _##ClassName##KeyTranslator
+#define _XN_DEFAULT_VALUE_TRANSLATOR(ClassName) _##ClassName##ValueTranslator
+
+/**
+* Declares a hash table from @a KeyType to @a ValueType named @a ClassName. The hash table uses
+* default translators for storing keys and values. It declares and uses a default manager.
+* It is declared using the @a decl declspec.
+*/
+#define XN_DECLARE_DEFAULT_HASH_DECL(decl, KeyType, ValueType, ClassName) \
+ XN_DECLARE_DEFAULT_VALUE_TRANSLATOR_DECL(decl, KeyType, _XN_DEFAULT_KEY_TRANSLATOR(ClassName)) \
+ XN_DECLARE_DEFAULT_VALUE_TRANSLATOR_DECL(decl, ValueType, _XN_DEFAULT_VALUE_TRANSLATOR(ClassName)) \
+ XN_DECLARE_DEFAULT_MANAGER_HASH_DECL(decl, KeyType, ValueType, ClassName, _XN_DEFAULT_KEY_TRANSLATOR(ClassName), _XN_DEFAULT_VALUE_TRANSLATOR(ClassName))
+
+/**
+* Declares a hash table from @a KeyType to @a ValueType named @a ClassName. The hash table uses
+* default translators for storing keys and values. It declares and uses a default manager.
+*/
+#define XN_DECLARE_DEFAULT_HASH(KeyType, ValueType, ClassName) \
+ XN_DECLARE_DEFAULT_HASH_DECL(, KeyType, ValueType, ClassName)
+
+#endif // _XN_HASH_H
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnHashT.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnHashT.h
new file mode 100644
index 00000000..7708fd45
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnHashT.h
@@ -0,0 +1,668 @@
+#ifndef _XN_HASH_T_H_
+#define _XN_HASH_T_H_
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include <XnOS.h>
+#include <XnListT.h>
+
+//---------------------------------------------------------------------------
+// Defines
+//---------------------------------------------------------------------------
+typedef XnUInt8 XnHashCode;
+
+//---------------------------------------------------------------------------
+// Code
+//---------------------------------------------------------------------------
+template<class _TKey, class _TValue>
+struct XnKeyValuePair
+{
+ typedef _TKey TKey;
+ typedef _TValue TValue;
+
+ XnKeyValuePair() : key(TKey()), value(TValue()) {}
+ XnKeyValuePair(TKey key, TValue value) : key(key), value(value) {}
+ XnKeyValuePair(const XnKeyValuePair& other) : key(other.key), value(other.value) {}
+
+public:
+ TKey const& Key() const { return key; }
+ TValue const& Value() const { return value; }
+ TValue& Value() { return value; }
+
+private:
+ TKey key;
+ TValue value;
+};
+
+template<class TKey>
+class XnDefaultKeyManagerT
+{
+public:
+ static XnHashCode Hash(TKey const& key)
+ {
+ return (((XnSizeT)key) & 0xff);
+ }
+
+ static XnInt32 Compare(TKey const& key1, TKey const& key2)
+ {
+ return XnInt32(XnSizeT(key1)-XnSizeT(key2));
+ }
+};
+
+template<class TKey,
+ class TValue,
+ class TKeyManager = XnDefaultKeyManagerT<TKey>,
+ class TAlloc = XnLinkedNodeDefaultAllocatorT<XnKeyValuePair<TKey, TValue> > >
+class XnHashT
+{
+public:
+ typedef XnKeyValuePair<TKey, TValue> TPair;
+ typedef XnListT<TPair, TAlloc> TPairList;
+
+ enum
+ {
+ LAST_BIN = (1 << (sizeof(XnHashCode)*8)),
+ NUM_BINS = LAST_BIN + 1,
+ };
+
+ class ConstIterator
+ {
+ public:
+ ConstIterator() : m_ppBins(NULL), m_nCurrBin(0)
+ {}
+
+ ConstIterator(TPairList* const* apBins, XnUInt32 nCurrBin, typename TPairList::ConstIterator currIt)
+ : m_ppBins(apBins), m_nCurrBin(nCurrBin), m_currIt(currIt)
+ {
+ if (nCurrBin != LAST_BIN && m_currIt == m_ppBins[m_nCurrBin]->End())
+ {
+ // this does not point to an actual entry. run to next one.
+ ++*this;
+ }
+ }
+
+ ConstIterator(const ConstIterator& other)
+ : m_ppBins(other.m_ppBins), m_nCurrBin(other.m_nCurrBin), m_currIt(other.m_currIt)
+ {}
+
+ /**
+ * Support ++iterator, go to the next object in the list
+ */
+ ConstIterator& operator++()
+ {
+ XN_ASSERT(m_nCurrBin != LAST_BIN);
+
+ // increment internal bin iterator
+ if (m_currIt != m_ppBins[m_nCurrBin]->End())
+ {
+ ++m_currIt;
+ }
+
+ // check if we need to move to next bin
+ if (m_currIt == m_ppBins[m_nCurrBin]->End())
+ {
+ // go forward through bins, until we either reach the end or a non-empty bin
+ do
+ {
+ ++m_nCurrBin;
+ } while (m_nCurrBin < LAST_BIN &&
+ (m_ppBins[m_nCurrBin] == NULL || m_ppBins[m_nCurrBin]->IsEmpty()));
+
+ m_currIt = m_ppBins[m_nCurrBin]->Begin();
+ }
+
+ return *this;
+ }
+
+ /**
+ * Support iterator++, go to the next object in the list, returning the old value
+ */
+ ConstIterator operator++(int)
+ {
+ ConstIterator retVal(*this);
+ ++*this;
+ return retVal;
+ }
+
+ /**
+ * Support --iterator, go to the previous object in the hash
+ */
+ ConstIterator& operator--()
+ {
+ XN_ASSERT(m_nCurrBin != LAST_BIN);
+
+ // decrement internal bin iterator
+ if (m_currIt != m_ppBins[m_nCurrBin]->ReverseEnd())
+ {
+ --m_currIt;
+ }
+
+ // check if we need to move to previous bin
+ if (m_currIt == m_ppBins[m_nCurrBin]->ReverseEnd())
+ {
+ // go backwards through bins, until we either reach the end or a non-empty bin
+ do
+ {
+ if (m_nCurrBin == 0)
+ {
+ m_nCurrBin = LAST_BIN;
+ break;
+ }
+ else
+ {
+ --m_nCurrBin;
+ }
+ } while (m_ppBins[m_nCurrBin] == NULL || m_ppBins[m_nCurrBin]->IsEmpty());
+
+ m_currIt = m_ppBins[m_nCurrBin]->Begin();
+ }
+
+ return *this;
+ }
+
+ /**
+ * Support iterator--, go to the previous object in the hash, returning the old value
+ */
+ ConstIterator operator--(int)
+ {
+ ConstIterator retVal(*this);
+ --*this;
+ return retVal;
+ }
+
+ /**
+ * Operator to check if two iterators point to the same object
+ *
+ * @param other [in] instance to compare with
+ */
+ inline XnBool operator==(const ConstIterator& other) const
+ {
+ return m_currIt == other.m_currIt;
+ }
+
+ /**
+ * Operator to check if two iterators point to different objects
+ *
+ * @param other [in] instance to compare with
+ */
+ inline XnBool operator!=(const ConstIterator& other) const
+ {
+ return m_currIt != other.m_currIt;
+ }
+
+ /**
+ * Get the value of the current object (const version)
+ */
+ inline TPair const& operator*() const
+ {
+ return *m_currIt;
+ }
+
+ /**
+ * Get a pointer to the value of the current object (const version)
+ */
+ inline TPair const* operator->() const
+ {
+ return m_currIt.operator->();
+ }
+
+ protected:
+ friend class XnHashT;
+
+ TPairList* const* m_ppBins;
+ XnUInt32 m_nCurrBin;
+ typename TPairList::ConstIterator m_currIt;
+ };
+
+ class Iterator : public ConstIterator
+ {
+ public:
+ Iterator() : ConstIterator()
+ {}
+
+ Iterator(TPairList** apBins, XnUInt32 nCurrBin, typename TPairList::Iterator currIt)
+ : ConstIterator(apBins, nCurrBin, currIt)
+ {}
+
+ Iterator(const Iterator& other) : ConstIterator(other)
+ {}
+
+ /**
+ * Support ++iterator, go to the next object in the list
+ */
+ Iterator& operator++()
+ {
+ ++(*(ConstIterator*)this);
+ return (*this);
+ }
+
+ /**
+ * Support iterator++, go to the next object in the list, returning the old value
+ */
+ inline Iterator operator++(int)
+ {
+ Iterator retVal(*this);
+ ++*this;
+ return (retVal);
+ }
+
+ /**
+ * Support --iterator, go to the next object in the list
+ */
+ inline Iterator& operator--()
+ {
+ --(*(ConstIterator*)this);
+ return (*this);
+ }
+
+ /**
+ * Support iterator--, go to the next object in the list, returning the old value
+ */
+ inline Iterator operator--(int)
+ {
+ Iterator retVal(*this);
+ --*this;
+ return (retVal);
+ }
+
+ /**
+ * Get the value of the current object
+ */
+ inline TPair& operator*() const
+ {
+ return const_cast<TPair&>(*this->m_currIt);
+ }
+
+ /**
+ * Get a pointer to the value of the current object
+ */
+ inline TPair* operator->() const
+ {
+ return const_cast<TPair*>(this->m_currIt.operator->());
+ }
+ };
+
+ XnHashT()
+ {
+ Init();
+ }
+
+ XnHashT(const XnHashT& other)
+ {
+ Init();
+ *this = other;
+ }
+
+ XnHashT& operator=(const XnHashT& other)
+ {
+ Clear();
+
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ for (ConstIterator it = other.Begin(); it != other.End(); ++it)
+ {
+ nRetVal = Set(it->Key(), it->Value());
+ XN_ASSERT(nRetVal == XN_STATUS_OK);
+ }
+
+ return *this;
+ }
+
+ ~XnHashT()
+ {
+ // NOTE: we don't want to delete LAST_BIN (it points to the m_lastBin member)
+ for (XnUInt32 i = 0; i < LAST_BIN; ++i)
+ {
+ if (m_apBins[i] != NULL)
+ {
+ XN_DELETE(m_apBins[i]);
+ }
+ }
+ }
+
+ /**
+ * An iterator to the first entry of the list (non-const version)
+ */
+ Iterator Begin()
+ {
+ return Iterator(m_apBins, m_nMinBin, m_apBins[m_nMinBin]->Begin());
+ }
+
+ /**
+ * An iterator to the first entry of the list (const version)
+ */
+ ConstIterator Begin() const
+ {
+ return ConstIterator(m_apBins, m_nMinBin, m_apBins[m_nMinBin]->Begin());
+ }
+
+ /**
+ * An iterator 1to the end of the list (non-const version). The position is invalid.
+ */
+ Iterator End()
+ {
+ return Iterator(m_apBins, LAST_BIN, m_apBins[LAST_BIN]->Begin());
+ }
+
+ /**
+ * An iterator to the end of the list (const version). The position is invalid.
+ */
+ ConstIterator End() const
+ {
+ return ConstIterator(m_apBins, LAST_BIN, m_apBins[LAST_BIN]->Begin());
+ }
+
+ /**
+ * Set a new key-value entry. If key exists, will replace value.
+ *
+ * @param key [in] The key to which to associate the value
+ * @param value [in] The value to add to the XnHash
+ */
+ XnStatus Set(const TKey& key, const TValue& value)
+ {
+ XnHashCode nHash = TKeyManager::Hash(key);
+
+ // check if bin exists
+ if (m_apBins[nHash] == NULL)
+ {
+ // create it
+ XN_VALIDATE_NEW(m_apBins[nHash], TPairList);
+
+ if (nHash < m_nMinBin)
+ {
+ m_nMinBin = nHash;
+ }
+ }
+
+ // now check if key is already in the bin
+ for (typename TPairList::Iterator it = m_apBins[nHash]->Begin(); it != m_apBins[nHash]->End(); ++it)
+ {
+ if (TKeyManager::Compare(it->Key(), key) == 0)
+ {
+ // replace it
+ it->Value() = value;
+ return (XN_STATUS_OK);
+ }
+ }
+
+ // if we got here, key is not in bin. Add it.
+ return m_apBins[nHash]->AddLast(TPair(key, value));
+ }
+
+ /**
+ * Get an iterator pointing to the pair in the hash (const version).
+ *
+ * @param key [in] The searched key
+ *
+ * @return End() if value doesn't exist
+ */
+ ConstIterator Find(TKey const& key) const
+ {
+ XnUInt32 nBin = LAST_BIN;
+ typename TPairList::ConstIterator it;
+ if (TRUE == Find(key, nBin, it))
+ {
+ return ConstIterator(m_apBins, nBin, it);
+ }
+ else
+ {
+ return End();
+ }
+ }
+
+ /**
+ * Get an iterator pointing to the pair in the hash.
+ *
+ * @param key [in] The searched key
+ *
+ * @return End() if value doesn't exist
+ */
+ Iterator Find(TKey const& key)
+ {
+ XnUInt32 nBin = LAST_BIN;
+ typename TPairList::Iterator it;
+ if (TRUE == Find(key, nBin, it))
+ {
+ return Iterator(m_apBins, nBin, it);
+ }
+ else
+ {
+ return End();
+ }
+ }
+
+ /**
+ * Get an iterator pointing to the pair in the hash (const version).
+ *
+ * @param key [in] The searched key
+ * @param it [out] An iterator to the entry in the hash.
+ *
+ * @return XN_STATUS_NO_MATCH if value doesn't exist
+ */
+ XnStatus Find(TKey const& key, ConstIterator& it) const
+ {
+ it = Find(key);
+ return (it == End() ? XN_STATUS_NO_MATCH : XN_STATUS_OK);
+ }
+
+ /**
+ * Get an iterator pointing to the pair in the hash (const version).
+ *
+ * @param key [in] The searched key
+ * @param it [out] An iterator to the entry in the hash.
+ *
+ * @return XN_STATUS_NO_MATCH if value doesn't exist
+ */
+ XnStatus Find(TKey const& key, Iterator& it)
+ {
+ it = Find(key);
+ return (it == End() ? XN_STATUS_NO_MATCH : XN_STATUS_OK);
+ }
+
+ /**
+ * Get the value associated with the supplied key
+ *
+ * @param key [in] The key of the entry
+ * @param value [out] The retrieved value
+ *
+ * @return XN_STATUS_NO_MATCH if no such key exists
+ */
+ XnStatus Get(TKey const& key, TValue& value) const
+ {
+ ConstIterator it = Find(key);
+ if (it == End())
+ {
+ return XN_STATUS_NO_MATCH;
+ }
+ else
+ {
+ value = it->Value();
+ return XN_STATUS_OK;
+ }
+ }
+
+ /**
+ * Get a pointer to the value associated with the supplied key
+ *
+ * @param key [in] The key of the entry
+ * @param pValue [out] A const pointer to the value that is stored in the hash.
+ *
+ * @return XN_STATUS_NO_MATCH if no such key exists
+ */
+ XnStatus Get(TKey const& key, TValue const*& pValue) const
+ {
+ ConstIterator it = Find(key);
+ if (it == End())
+ {
+ return XN_STATUS_NO_MATCH;
+ }
+ else
+ {
+ pValue = &it->Value();
+ return XN_STATUS_OK;
+ }
+ }
+
+ /**
+ * Get the value associated with the supplied key
+ *
+ * @param key [in] The key of the entry
+ * @param value [out] The retrieved value
+ *
+ * @return XN_STATUS_NO_MATCH if no such key exists
+ */
+ XnStatus Get(TKey const& key, TValue& value)
+ {
+ Iterator it = Find(key);
+ if (it == End())
+ {
+ return XN_STATUS_NO_MATCH;
+ }
+ else
+ {
+ value = it->Value();
+ return XN_STATUS_OK;
+ }
+ }
+
+ /**
+ * Get a pointer to the value associated with the supplied key
+ *
+ * @param key [in] The key of the entry
+ * @param pValue [out] A pointer to the value that is stored in the hash
+ *
+ * @return XN_STATUS_NO_MATCH if no such key exists
+ */
+ XnStatus Get(TKey const& key, TValue*& pValue)
+ {
+ Iterator it = Find(key);
+ if (it == End())
+ {
+ return XN_STATUS_NO_MATCH;
+ }
+ else
+ {
+ pValue = &it->Value();
+ return XN_STATUS_OK;
+ }
+ }
+
+ /**
+ * Gets a reference to the value of a specific key. If this key is not in the hash, it will be added.
+ *
+ * @param key [in] The key of the entry.
+ */
+ TValue& operator[](TKey const& key)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+ Iterator it = Find(key);
+ if (it == End())
+ {
+ nRetVal = Set(key, TValue());
+ XN_ASSERT(nRetVal == XN_STATUS_OK);
+
+ it = Find(key);
+ XN_ASSERT(it != End());
+ }
+
+ return it->Value();
+ }
+
+ XnStatus Remove(ConstIterator it)
+ {
+ // Verify iterator is valid
+ if (it == End())
+ {
+ XN_ASSERT(FALSE);
+ return XN_STATUS_ILLEGAL_POSITION;
+ }
+
+ XN_ASSERT(m_apBins == it.m_ppBins);
+ XN_ASSERT(m_apBins[it.m_nCurrBin] != NULL);
+
+ return m_apBins[it.m_nCurrBin]->Remove(it.m_currIt);
+ }
+
+ XnStatus Remove(TKey const& key)
+ {
+ ConstIterator it = Find(key);
+ if (it != End())
+ {
+ return Remove(it);
+ }
+ else
+ {
+ return XN_STATUS_NO_MATCH;
+ }
+ }
+
+ /**
+ * Remove all entries from the XnHash.
+ */
+ XnStatus Clear()
+ {
+ while (Begin() != End())
+ Remove(Begin());
+
+ return XN_STATUS_OK;
+ }
+
+ /**
+ * Checks if hash is empty.
+ */
+ XnBool IsEmpty() const
+ {
+ return (Begin() == End());
+ }
+
+ /**
+ * Gets the number of entries in the hash.
+ */
+ XnUInt32 Size() const
+ {
+ XnUInt32 nSize = 0;
+ for (ConstIterator iter = Begin(); iter != End(); ++iter, ++nSize)
+ ;
+
+ return nSize;
+ }
+
+private:
+ XnBool Find(TKey const& key, XnUInt32& nBin, typename TPairList::ConstIterator& currIt) const
+ {
+ XnHashCode nHash = TKeyManager::Hash(key);
+
+ if (m_apBins[nHash] != NULL)
+ {
+ // look for value in bin
+ for (typename TPairList::ConstIterator it = m_apBins[nHash]->Begin(); it != m_apBins[nHash]->End(); ++it)
+ {
+ if (TKeyManager::Compare(it->Key(), key) == 0)
+ {
+ nBin = nHash;
+ currIt = it;
+ return TRUE;
+ }
+ }
+ }
+
+ // if we got here, key wasn't found
+ return FALSE;
+ }
+
+ void Init()
+ {
+ xnOSMemSet(m_apBins, 0, sizeof(m_apBins));
+ m_apBins[LAST_BIN] = &m_lastBin;
+ m_nMinBin = LAST_BIN;
+ }
+
+ TPairList* m_apBins[NUM_BINS];
+ TPairList m_lastBin;
+ XnUInt32 m_nMinBin;
+};
+
+
+
+#endif // _XN_HASH_T_H_ \ No newline at end of file
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnInternalDefs.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnInternalDefs.h
new file mode 100644
index 00000000..c14bb055
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnInternalDefs.h
@@ -0,0 +1,27 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef __NIINTERNALDEFS_H__
+#define __NIINTERNALDEFS_H__
+
+#define XN_MOCK_NODE_NAME "Mock"
+
+#endif // __NIINTERNALDEFS_H__ \ No newline at end of file
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnLicensing.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnLicensing.h
new file mode 100644
index 00000000..cc0f5b8f
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnLicensing.h
@@ -0,0 +1,72 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef __XN_LICENSING_H__
+#define __XN_LICENSING_H__
+
+/**
+ * @ingroup cref
+ * @defgroup lic Licenses
+ * This page details functions for license management.
+ * @{
+ */
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include <XnTypes.h>
+
+//---------------------------------------------------------------------------
+// Functions
+//---------------------------------------------------------------------------
+
+/**
+ * Adds a license to the context.
+ *
+ * @param pContext [in] OpenNI context.
+ * @param pLicense [in] A license key.
+ */
+XN_C_API XnStatus XN_C_DECL xnAddLicense(XnContext* pContext, const XnLicense* pLicense);
+
+/**
+ * Enumerates all licenses currently registered. The list of licenses should later be freed
+ * by calling @ref xnFreeLicensesList().
+ *
+ * @param pContext [in] OpenNI context.
+ * @param paLicenses [out] An array of license pointers.
+ * @param pnCount [out] The number of licenses in the array.
+ */
+XN_C_API XnStatus XN_C_DECL xnEnumerateLicenses(
+ XnContext* pContext,
+ XnLicense** paLicenses,
+ XnUInt32* pnCount
+ );
+
+/**
+ * Frees a list of licenses.
+ *
+ * @param aLicenses [in] The list to free.
+ */
+XN_C_API void XN_C_DECL xnFreeLicensesList(XnLicense* aLicenses);
+
+/** @} */
+
+#endif // __XN_LICENSING_H__
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnList.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnList.h
new file mode 100644
index 00000000..82665f83
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnList.h
@@ -0,0 +1,749 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef _XN_LIST_H
+#define _XN_LIST_H
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include <XnDataTypes.h>
+#include <IXnNodeAllocator.h>
+#include <XnNodeAllocator.h>
+#include <XnNode.h>
+#include <XnStatusCodes.h>
+
+//---------------------------------------------------------------------------
+// Types
+//---------------------------------------------------------------------------
+
+/**
+ * The linked list
+ */
+class XnList
+{
+public:
+ class ConstIterator
+ {
+ public:
+ friend class XnList;
+
+ /**
+ * Copy constructor
+ *
+ * @param other [in] instance to copy from
+ */
+ ConstIterator(const ConstIterator& other) : m_pCurrent(other.m_pCurrent) {}
+
+ /**
+ * Support ++iterator, go to the next object in the list
+ */
+ ConstIterator& operator++()
+ {
+ m_pCurrent = m_pCurrent->Next();
+ return *this;
+ }
+
+ /**
+ * Support iterator++, go to the next object in the list, returning the old value
+ */
+ ConstIterator operator++(int)
+ {
+ ConstIterator other(m_pCurrent);
+ m_pCurrent = m_pCurrent->Next();
+ return other;
+ }
+
+ /**
+ * Support --iterator, go to the next object in the list
+ */
+ ConstIterator& operator--()
+ {
+ m_pCurrent = m_pCurrent->Previous();
+ return *this;
+ }
+
+ /**
+ * Support iterator--, go to the next object in the list, returning the old value
+ */
+ ConstIterator operator--(int)
+ {
+ ConstIterator other = *this;
+ --*this;
+ return other;
+ }
+
+ /**
+ * Operator to check if 2 iterators point to the same object
+ *
+ * @param other [in] instance to compare with
+ */
+ XnBool operator==(const ConstIterator& other) const
+ {
+ return m_pCurrent == other.m_pCurrent;
+ }
+ /**
+ * Operator to check if 2 iterators point to different objects
+ *
+ * @param other [in] instance to compare with
+ */
+ XnBool operator!=(const ConstIterator& other) const
+ {
+ return m_pCurrent != other.m_pCurrent;
+ }
+
+ /**
+ * Get the value of the current object (const version)
+ */
+ const XnValue& operator*() const
+ {
+ return m_pCurrent->Data();
+ }
+
+
+ /**
+ * Get the entire current object (const version)
+ */
+ const XnNode* GetNode() const
+ {
+ return m_pCurrent;
+ }
+
+ /**
+ * Get the entire current object (non-const version)
+ */
+ XnNode* GetNode()
+ {
+ return m_pCurrent;
+ }
+
+ protected:
+ /**
+ * constructor to be used from inside the XnList. It points to the node supplied.
+ *
+ * @param pNode [in] The XnNode to which to currently point
+ */
+ ConstIterator(XnNode* pNode) : m_pCurrent(pNode) {}
+
+ /** The current XnNode */
+ XnNode* m_pCurrent;
+ };
+
+ /**
+ * Iterator to the XnList
+ */
+ class Iterator : public ConstIterator
+ {
+ public:
+ friend class XnList;
+
+ /**
+ * Copy constructor
+ *
+ * @param other [in] instance to copy from
+ */
+ inline Iterator(const Iterator& other) : ConstIterator(other) {}
+
+ /**
+ * Support ++iterator, go to the next object in the list
+ */
+ inline Iterator& operator++()
+ {
+ ++(*(ConstIterator*)this);
+ return (*this);
+ }
+ /**
+ * Support iterator++, go to the next object in the list, returning the old value
+ */
+ inline Iterator operator++(int)
+ {
+ Iterator result = *this;
+ ++*this;
+ return (result);
+ }
+
+ /**
+ * Support --iterator, go to the next object in the list
+ */
+ inline Iterator& operator--()
+ {
+ --(*(ConstIterator*)this);
+ return (*this);
+ }
+ /**
+ * Support iterator--, go to the next object in the list, returning the old value
+ */
+ inline Iterator operator--(int)
+ {
+ Iterator result = *this;
+ --*this;
+ return (result);
+ }
+
+ /**
+ * Get the value of the current object
+ */
+ inline XnValue& operator*() const { return ((XnValue&)**(ConstIterator*)this); }
+
+ protected:
+ /**
+ * constructor to be used from inside the XnList. It points to the node supplied.
+ *
+ * @param pNode [in] The XnNode to which to currently point
+ */
+ inline Iterator(XnNode* pNode) : ConstIterator(pNode) {}
+ };
+
+public:
+ /**
+ * Constructor. Initialize internal representations
+ */
+ XnList()
+ {
+ //Default node allocator is XnNodeAllocator
+ Init(XN_NEW(XnNodeAllocator));
+ m_bOwnsAllocator = TRUE;
+ }
+
+ /**
+ * Destructor. Destroy internal representations
+ */
+ virtual ~XnList()
+ {
+ Clear();
+
+ // Return base node to the pool
+ m_pNodeAllocator->Deallocate(m_pBase);
+
+ if (m_bOwnsAllocator)
+ {
+ //We created the allocator in this object, so we must release it
+ XN_DELETE(m_pNodeAllocator);
+ }
+ }
+
+ /**
+ * Add a new value at the beginning of list
+ *
+ * @param value [in] The value to add to the head of the list
+ *
+ * @return XN_STATUS_ALLOC_FAILED Failed to add to the list because no nodes are available.
+ */
+ XnStatus AddFirst(const XnValue& value)
+ {
+ return Add(m_pBase, value);
+ }
+
+ /**
+ * Add a new value at the end of the list
+ *
+ * @param value [in] The value to add to the tail of the list
+ *
+ * @return XN_STATUS_ALLOC_FAILED Failed to add to the list because no nodes are available.
+ */
+ XnStatus AddLast(const XnValue& value)
+ {
+ return Add(rbegin().m_pCurrent, value);
+ }
+
+ /**
+ * Add a new value after the object pointed to by the iterator
+ *
+ * @param where [in] iterator to the position after which to add the new value
+ * @param val [in] The value to add to the list
+ *
+ * @return XN_STATUS_ALLOC_FAILED Failed to add to the list because no nodes are available,
+ * XN_STATUS_ILLEGAL_POSITION iterator is invalid
+ */
+ XnStatus AddAfter(ConstIterator where, const XnValue& val)
+ {
+ if (where == end())
+ {
+ return XN_STATUS_ILLEGAL_POSITION;
+ }
+
+ return Add(where.m_pCurrent, val);
+ }
+
+ /**
+ * Add a new value before the object pointed to by the iterator
+ *
+ * @param where [in] iterator to the position before which to add the new value
+ * @param val [in] The value to add to the list
+ *
+ * @return XN_STATUS_ALLOC_FAILED Failed to add to the list because no nodes are available,
+ */
+ XnStatus AddBefore(ConstIterator where, const XnValue& val)
+ {
+ if (where == end())
+ {
+ return XN_STATUS_ILLEGAL_POSITION;
+ }
+
+ return Add(where.m_pCurrent->Previous(), val);
+ }
+
+
+ /**
+ * Get an iterator pointing to a value in the list.
+ *
+ * @param value [in] The searched value
+ *
+ * @return end() if value doesn't exist
+ */
+ Iterator Find(const XnValue& value)
+ {
+ if (IsEmpty())
+ {
+ return end();
+ }
+
+ Iterator iter = begin();
+ for (; iter != end(); ++iter)
+ {
+ if (*iter == value)
+ break;
+ }
+ return iter;
+ }
+
+
+ /**
+ * Get an iterator pointing to a value in the list.
+ *
+ * @param value [in] The searched value
+ *
+ * @return end() if value doesn't exist
+ */
+ ConstIterator Find(const XnValue& value) const
+ {
+ if (IsEmpty())
+ {
+ return end();
+ }
+
+ ConstIterator iter = begin();
+ for (; iter != end(); ++iter)
+ {
+ if (*iter == value)
+ break;
+ }
+ return iter;
+ }
+
+
+ /**
+ * Remove a value from the list
+ *
+ * @param where [in] Iterator pointing to an entry in the list
+ * @param value [out] The value that was in the removed entry
+ *
+ * @return XN_STATUS_ILLEGAL_POSITION iterator was invalid
+ */
+ XnStatus Remove(ConstIterator where, XnValue& value)
+ {
+ value = *where;
+ return Remove(where);
+ }
+
+ /**
+ * Remove a value from the list
+ *
+ * @param where [in] Iterator pointing to an entry in the list
+ *
+ * @return XN_STATUS_ILLEGAL_POSITION iterator was invalid
+ */
+ virtual XnStatus Remove(ConstIterator where)
+ {
+ // Verify iterator is valid
+ if (where == end())
+ {
+ return XN_STATUS_ILLEGAL_POSITION;
+ }
+ if (IsEmpty())
+ {
+ return XN_STATUS_IS_EMPTY;
+ }
+
+ XnNode* pToRemove = where.m_pCurrent;
+
+ // Connect other nodes to bypass the one removed
+ pToRemove->Previous()->Next() = pToRemove->Next();
+ pToRemove->Next()->Previous() = pToRemove->Previous();
+
+ // Return removed node to the pool
+ m_pNodeAllocator->Deallocate(pToRemove);
+
+ return XN_STATUS_OK;
+ }
+
+
+ /**
+ * Remove all entries from the list
+ */
+ XnStatus Clear()
+ {
+ while (!IsEmpty())
+ Remove(begin());
+
+ return XN_STATUS_OK;
+ }
+
+ /**
+ * Check if list is empty
+ */
+ XnBool IsEmpty() const
+ {
+ return (begin() == end());
+ }
+
+ /**
+ * Current size of the list
+ */
+ XnUInt32 Size() const
+ {
+ XnUInt32 nSize = 0;
+ for (ConstIterator iter = begin(); iter != end(); ++iter, ++nSize)
+ ;
+
+ return nSize;
+ }
+
+ /**
+ * An iterator to the first entry of the list (non-const version)
+ */
+ Iterator begin()
+ {
+ return Iterator(m_pBase->Next());
+ }
+
+ /**
+ * An iterator to the first entry of the list (const version)
+ */
+ ConstIterator begin() const
+ {
+ return ConstIterator(m_pBase->Next());
+ }
+
+ /**
+ * An iterator 1to the end of the list (non-const version). The position is invalid.
+ */
+ Iterator end()
+ {
+ return Iterator(m_pBase);
+ }
+
+ /**
+ * An iterator to the end of the list (const version). The position is invalid.
+ */
+ ConstIterator end() const
+ {
+ return ConstIterator(m_pBase);
+ }
+
+ /**
+ * An iterator to the last entry of the list (non-const version)
+ */
+ Iterator rbegin()
+ {
+ return Iterator(m_pBase->Previous());
+ }
+
+ /**
+ * An iterator to the last entry of the list (const version)
+ */
+ ConstIterator rbegin() const
+ {
+ return ConstIterator(m_pBase->Previous());
+ }
+
+ /**
+ * An iterator to the beginning of the list (non-const version). This position is invalid
+ */
+ Iterator rend()
+ {
+ return Iterator(m_pBase);
+ }
+
+ /**
+ * An iterator to the beginning of the list (const version). This position is invalid
+ */
+ ConstIterator rend() const
+ {
+ return ConstIterator(m_pBase);
+ }
+
+protected:
+ friend class XnNodeManager;
+
+ /**
+ * Constructor. Initialize internal representations
+ */
+ XnList(INiNodeAllocator* pNodeAllocator)
+ {
+ Init(pNodeAllocator);
+ m_bOwnsAllocator = FALSE;
+ }
+
+ void Init(INiNodeAllocator* pNodeAllocator)
+ {
+ m_pNodeAllocator = pNodeAllocator;
+ // Allocate a node to act as base node.
+ m_pBase = m_pNodeAllocator->Allocate();
+ if (m_pBase == NULL)
+ {
+ // OZOZ: Allocation failed in ctor...
+ }
+
+ m_pBase->Next() = m_pBase->Previous() = m_pBase;
+ }
+
+ /**
+ * Add a new value to the list
+ *
+ * @param pWhere [in] The XnNode after which to add the new value
+ * @param val [in] The value to add to the list
+ *
+ * @return XN_STATUS_ALLOC_FAILED Failed to add to the list because no nodes are available,
+ */
+ XnStatus Add(XnNode* pWhere, const XnValue& val)
+ {
+ // Get a node from the pool for the entry
+ XnNode* pNewNode = m_pNodeAllocator->Allocate();
+ if (pNewNode == NULL)
+ {
+ return XN_STATUS_ALLOC_FAILED;
+ }
+ // push new node to position
+ pNewNode->Data() = val;
+ pNewNode->Next() = pWhere->Next();
+ pNewNode->Previous() = pWhere;
+ pWhere->Next()->Previous() = pNewNode;
+ pWhere->Next() = pNewNode;
+
+ return XN_STATUS_OK;
+ }
+
+
+ /** The base node for the list */
+ XnNode* m_pBase;
+
+ INiNodeAllocator* m_pNodeAllocator;
+ XnBool m_bOwnsAllocator;
+
+private:
+ XN_DISABLE_COPY_AND_ASSIGN(XnList);
+};
+
+/**
+* Declares a list of type @a Type, which is named @a ClassName. The list uses translator @a Translator,
+* and is declared using the @a decl declspec.
+*/
+#define XN_DECLARE_LIST_WITH_TRANSLATOR_DECL(decl, Type, ClassName, Translator) \
+ class decl ClassName : public XnList \
+ { \
+ public: \
+ class decl ConstIterator : public XnList::ConstIterator \
+ { \
+ public: \
+ friend class ClassName; \
+ inline ConstIterator(const ConstIterator& other) : XnList::ConstIterator(other) {} \
+ inline ConstIterator& operator++() \
+ { \
+ ++(*(XnList::ConstIterator*)this); \
+ return (*this); \
+ } \
+ inline ConstIterator operator++(int) \
+ { \
+ ConstIterator result = *this; \
+ ++*this; \
+ return result; \
+ } \
+ inline ConstIterator& operator--() \
+ { \
+ --(*(XnList::ConstIterator*)this); \
+ return (*this); \
+ } \
+ inline ConstIterator operator--(int) \
+ { \
+ ConstIterator result = *this; \
+ --*this; \
+ return result; \
+ } \
+ inline Type const& operator*() const \
+ { \
+ return Translator::GetFromValue(**((XnList::ConstIterator*)this)); \
+ } \
+ inline Type const* operator->() const { return (&**this); } \
+ protected: \
+ inline ConstIterator(XnNode* pNode) : XnList::ConstIterator(pNode) {} \
+ inline ConstIterator(const XnList::ConstIterator& other) : \
+ XnList::ConstIterator(other) \
+ {} \
+ }; \
+ class decl Iterator : public ConstIterator \
+ { \
+ public: \
+ friend class ClassName; \
+ Iterator(const Iterator& other) : ConstIterator(other) {} \
+ inline Iterator& operator++() \
+ { \
+ ++(*(ConstIterator*)this); \
+ return (*this); \
+ } \
+ inline Iterator operator++(int) \
+ { \
+ Iterator result = *this; \
+ ++*this; \
+ return result; \
+ } \
+ inline Iterator& operator--() \
+ { \
+ --(*(ConstIterator*)this); \
+ return (*this); \
+ } \
+ inline Iterator operator--(int) \
+ { \
+ Iterator result = *this; \
+ --*this; \
+ return result; \
+ } \
+ inline Type& operator*() const { return ((Type&)**(ConstIterator*)this); } \
+ inline Type* operator->() const { return (&**this); } \
+ protected: \
+ inline Iterator(XnNode* pNode) : ConstIterator(pNode) {} \
+ inline Iterator(const XnList::Iterator& other) : ConstIterator(other) {} \
+ }; \
+ public: \
+ ClassName() \
+ { \
+ } \
+ ~ClassName() \
+ { \
+ while (!IsEmpty()) \
+ Remove(begin()); \
+ } \
+ inline XnStatus AddFirst(Type const& value) \
+ { \
+ XnValue val = Translator::CreateValueCopy(value); \
+ XnStatus nRetVal = XnList::AddFirst(val); \
+ if (nRetVal != XN_STATUS_OK) \
+ { \
+ Translator::FreeValue(val); \
+ return (nRetVal); \
+ } \
+ return XN_STATUS_OK; \
+ } \
+ inline XnStatus AddLast(Type const& value) \
+ { \
+ XnValue val = Translator::CreateValueCopy(value); \
+ XnStatus nRetVal = XnList::AddLast(val); \
+ if (nRetVal != XN_STATUS_OK) \
+ { \
+ Translator::FreeValue(val); \
+ return (nRetVal); \
+ } \
+ return XN_STATUS_OK; \
+ } \
+ inline XnStatus AddAfter(ConstIterator where, Type const& value) \
+ { \
+ XnValue val = Translator::CreateValueCopy(value); \
+ XnStatus nRetVal = XnList::AddAfter(where, val); \
+ if (nRetVal != XN_STATUS_OK) \
+ { \
+ Translator::FreeValue(val); \
+ return (nRetVal); \
+ } \
+ return XN_STATUS_OK; \
+ } \
+ inline XnStatus AddBefore(ConstIterator where, Type const& value) \
+ { \
+ XnValue val = Translator::CreateValueCopy(value); \
+ XnStatus nRetVal = XnList::AddBefore(where, val); \
+ if (nRetVal != XN_STATUS_OK) \
+ { \
+ Translator::FreeValue(val); \
+ return (nRetVal); \
+ } \
+ return XN_STATUS_OK; \
+ } \
+ inline ConstIterator Find(Type const& value) const \
+ { \
+ XnValue _value = Translator::GetAsValue(value); \
+ return XnList::Find(_value); \
+ } \
+ inline Iterator Find(Type const& value) \
+ { \
+ XnValue _value = Translator::GetAsValue(value); \
+ return XnList::Find(_value); \
+ } \
+ inline XnStatus Remove(ConstIterator where) \
+ { \
+ XnValue val = Translator::GetAsValue(*where); \
+ XnStatus nRetVal = XnList::Remove(where); \
+ if (nRetVal != XN_STATUS_OK) return (nRetVal); \
+ Translator::FreeValue(val); \
+ return XN_STATUS_OK; \
+ } \
+ inline XnStatus Remove(Type const& value) \
+ { \
+ Iterator it = Find(value); \
+ return Remove(it); \
+ } \
+ inline Iterator begin() { return XnList::begin(); } \
+ inline ConstIterator begin() const { return XnList::begin(); } \
+ inline Iterator end() { return XnList::end(); } \
+ inline ConstIterator end() const { return XnList::end(); } \
+ inline Iterator rbegin() { return XnList::rbegin(); } \
+ inline ConstIterator rbegin() const { return XnList::rbegin(); } \
+ inline Iterator rend() { return XnList::rend(); } \
+ inline ConstIterator rend() const { return XnList::rend(); } \
+ protected: \
+ virtual XnStatus Remove(XnList::ConstIterator where) \
+ { \
+ return Remove(ConstIterator(where)); \
+ } \
+ private: \
+ XN_DISABLE_COPY_AND_ASSIGN(ClassName); \
+ };
+
+/**
+* Declares a list of type @a Type, which is named @a ClassName. The list uses translator @a Translator.
+*/
+#define XN_DECLARE_LIST_WITH_TRANSLATOR(Type, ClassName, Translator) \
+ XN_DECLARE_LIST_WITH_TRANSLATOR_DECL(, Type, ClassName, Translator)
+
+/**
+* Declares a list of type @a Type, which is named @a ClassName. The list uses creates a default translator
+* and is declared using the @a decl declspec.
+*/
+#define XN_DECLARE_LIST_DECL(decl, Type, ClassName) \
+ XN_DECLARE_DEFAULT_VALUE_TRANSLATOR_DECL(decl, Type, XN_DEFAULT_TRANSLATOR_NAME(ClassName)) \
+ XN_DECLARE_LIST_WITH_TRANSLATOR_DECL(decl, Type, ClassName, XN_DEFAULT_TRANSLATOR_NAME(ClassName))
+
+/**
+* Declares a list of type @a Type, which is named @a ClassName. The list uses creates a default translator.
+*/
+#define XN_DECLARE_LIST(Type, ClassName) \
+ XN_DECLARE_LIST_DECL(, Type, ClassName)
+
+#endif // _XN_LIST_H
+
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnListT.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnListT.h
new file mode 100644
index 00000000..8cbe992d
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnListT.h
@@ -0,0 +1,556 @@
+#ifndef _XNLISTT_H_
+#define _XNLISTT_H_
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include <XnPlatform.h>
+#include <XnDataTypes.h>
+#include <XnOS.h>
+
+//---------------------------------------------------------------------------
+// Code
+//---------------------------------------------------------------------------
+
+/**
+ * A node in a linked list.
+ *
+ * @tparam T the type of value in the list.
+ */
+template<class T>
+struct XnLinkedNodeT
+{
+ XnLinkedNodeT() : pPrev(NULL), pNext(NULL) {}
+ XnLinkedNodeT(T const& value) : pPrev(NULL), pNext(NULL), value(value) {}
+
+ struct XnLinkedNodeT<T>* pPrev;
+ struct XnLinkedNodeT<T>* pNext;
+ T value;
+};
+
+/**
+ * A default allocator for nodes in the linked list. The default allocator calls 'new' for allocating
+ * new nodes and 'delete' for deallocating them.
+ *
+ * For information on how to use allocator, see @ref XnListT.
+ *
+ * @tparam T the type of value in the list.
+ */
+template<class T>
+class XnLinkedNodeDefaultAllocatorT
+{
+public:
+ typedef XnLinkedNodeT<T> LinkedNode;
+
+ static LinkedNode* Allocate(T const& value)
+ {
+ return XN_NEW(LinkedNode, value);
+ }
+
+ static void Deallocate(LinkedNode* pNode)
+ {
+ XN_DELETE(pNode);
+ }
+};
+
+/**
+ * A linked list.
+ *
+ * @tparam T The type of value in the list
+ * @tparam TAlloc [Optional] A class for allocating and deallocating nodes in the list.
+ * The allocator must have two static methods: Allocate() and Deallocate().
+ */
+template<class T, class TAlloc = XnLinkedNodeDefaultAllocatorT<T> >
+class XnListT
+{
+public:
+ typedef XnLinkedNodeT<T> LinkedNode;
+ typedef T TValue;
+ typedef TAlloc TAllocator;
+
+ /**
+ * An iterator for iterating the list without modifying values.
+ */
+ class ConstIterator
+ {
+ public:
+ inline ConstIterator() : m_pCurrent(NULL) {}
+
+ inline ConstIterator(LinkedNode* pNode) : m_pCurrent(pNode) {}
+
+ inline ConstIterator(const ConstIterator& other) : m_pCurrent(other.m_pCurrent) {}
+
+ /**
+ * Support ++iterator, go to the next object in the list
+ */
+ inline ConstIterator& operator++()
+ {
+ m_pCurrent = m_pCurrent->pNext;
+ return *this;
+ }
+
+ /**
+ * Support iterator++, go to the next object in the list, returning the old value
+ */
+ inline ConstIterator operator++(int)
+ {
+ ConstIterator retVal(*this);
+ ++*this;
+ return retVal;
+ }
+
+ /**
+ * Support --iterator, go to the next object in the list
+ */
+ inline ConstIterator& operator--()
+ {
+ m_pCurrent = m_pCurrent->pPrev;
+ return *this;
+ }
+
+ /**
+ * Support iterator--, go to the next object in the list, returning the old value
+ */
+ inline ConstIterator operator--(int)
+ {
+ ConstIterator retVal(*this);
+ --*this;
+ return retVal;
+ }
+
+ /**
+ * Operator to check if two iterators point to the same object
+ *
+ * @param other [in] instance to compare with
+ */
+ inline XnBool operator==(const ConstIterator& other) const
+ {
+ return m_pCurrent == other.m_pCurrent;
+ }
+
+ /**
+ * Operator to check if two iterators point to different objects
+ *
+ * @param other [in] instance to compare with
+ */
+ inline XnBool operator!=(const ConstIterator& other) const
+ {
+ return m_pCurrent != other.m_pCurrent;
+ }
+
+ /**
+ * Get the value of the current object (const version)
+ */
+ inline T const& operator*() const
+ {
+ return m_pCurrent->value;
+ }
+
+ /**
+ * Get a pointer to the value of the current object (const version)
+ */
+ inline T const* operator->() const
+ {
+ return &m_pCurrent->value;
+ }
+
+ protected:
+ friend class XnListT;
+
+ /** The current XnNode */
+ LinkedNode* m_pCurrent;
+ };
+
+ /**
+ * An iterator for iterating the list
+ */
+ class Iterator : public ConstIterator
+ {
+ public:
+ inline Iterator() : ConstIterator() {}
+
+ inline Iterator(LinkedNode* pNode) : ConstIterator(pNode) {}
+
+ inline Iterator(const Iterator& other) : ConstIterator(other) {}
+
+ /**
+ * Support ++iterator, go to the next object in the list
+ */
+ inline Iterator& operator++()
+ {
+ ++(*(ConstIterator*)this);
+ return (*this);
+ }
+
+ /**
+ * Support iterator++, go to the next object in the list, returning the old value
+ */
+ inline Iterator operator++(int)
+ {
+ Iterator retVal(*this);
+ ++*this;
+ return (retVal);
+ }
+
+ /**
+ * Support --iterator, go to the next object in the list
+ */
+ inline Iterator& operator--()
+ {
+ --(*(ConstIterator*)this);
+ return (*this);
+ }
+ /**
+ * Support iterator--, go to the next object in the list, returning the old value
+ */
+ inline Iterator operator--(int)
+ {
+ Iterator retVal(*this);
+ --*this;
+ return (retVal);
+ }
+
+ /**
+ * Get the value of the current object
+ */
+ inline T& operator*() const
+ {
+ return this->m_pCurrent->value;
+ }
+
+ /**
+ * Get a pointer to the value of the current object
+ */
+ inline T* operator->() const
+ {
+ return &this->m_pCurrent->value;
+ }
+ };
+
+public:
+ XnListT()
+ {
+ Init();
+ }
+
+ XnListT(const XnListT& other)
+ {
+ Init();
+ *this = other;
+ }
+
+ XnListT& operator=(const XnListT& other)
+ {
+ Clear();
+
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ for (ConstIterator it = other.Begin(); it != other.End(); ++it)
+ {
+ nRetVal = AddLast(*it);
+ XN_ASSERT(nRetVal == XN_STATUS_OK);
+ }
+
+ return *this;
+ }
+
+ ~XnListT()
+ {
+ Clear();
+ }
+
+ /**
+ * An iterator to the first entry of the list (non-const version)
+ */
+ Iterator Begin()
+ {
+ return Iterator(m_anchor.pNext);
+ }
+
+ /**
+ * An iterator to the first entry of the list (const version)
+ */
+ ConstIterator Begin() const
+ {
+ return ConstIterator(const_cast<LinkedNode*>(m_anchor.pNext));
+ }
+
+ /**
+ * An iterator 1to the end of the list (non-const version). This position is invalid.
+ */
+ Iterator End()
+ {
+ return Iterator(&m_anchor);
+ }
+
+ /**
+ * An iterator to the end of the list (const version). This position is invalid.
+ */
+ ConstIterator End() const
+ {
+ return ConstIterator(const_cast<LinkedNode*>(&m_anchor));
+ }
+
+ /**
+ * An iterator to the last entry of the list (non-const version)
+ */
+ Iterator ReverseBegin()
+ {
+ return Iterator(m_anchor.pPrev);
+ }
+
+ /**
+ * An iterator to the last entry of the list (const version)
+ */
+ ConstIterator ReverseBegin() const
+ {
+ return ConstIterator(const_cast<LinkedNode*>(m_anchor.pPrev));
+ }
+
+ /**
+ * An iterator to the beginning of the list (non-const version). This position is invalid.
+ */
+ Iterator ReverseEnd()
+ {
+ return Iterator(&m_anchor);
+ }
+
+ /**
+ * An iterator to the beginning of the list (const version). This position is invalid.
+ */
+ ConstIterator ReverseEnd() const
+ {
+ return ConstIterator(const_cast<LinkedNode*>(&m_anchor));
+ }
+
+ /**
+ * Add a new value after the object pointed to by the iterator
+ *
+ * @param where [in] iterator to the position after which to add the new value
+ * @param value [in] The value to add to the list
+ *
+ * @return XN_STATUS_ALLOC_FAILED failed to allocate new node
+ * XN_STATUS_ILLEGAL_POSITION iterator is invalid
+ */
+ XnStatus AddAfter(ConstIterator where, T const& value)
+ {
+ if (where == End())
+ {
+ return XN_STATUS_ILLEGAL_POSITION;
+ }
+
+ return InsertAfter(where.m_pCurrent, value);
+ }
+
+ /**
+ * Add a new value before the object pointed to by the iterator
+ *
+ * @param where [in] iterator to the position before which to add the new value
+ * @param value [in] The value to add to the list
+ *
+ * @return XN_STATUS_ALLOC_FAILED failed to allocate new node
+ * XN_STATUS_ILLEGAL_POSITION iterator is invalid
+ */
+ XnStatus AddBefore(ConstIterator where, T const& value)
+ {
+ if (where == End())
+ {
+ return XN_STATUS_ILLEGAL_POSITION;
+ }
+
+ return InsertAfter(where.m_pCurrent->pPrev, value);
+ }
+
+ /**
+ * Add a new value at the beginning of list
+ *
+ * @param value [in] The value to add to the head of the list
+ *
+ * @return XN_STATUS_ALLOC_FAILED failed to allocate new node
+ */
+ XnStatus AddFirst(T const& value)
+ {
+ return InsertAfter(&m_anchor, value);
+ }
+
+ /**
+ * Add a new value at the end of the list
+ *
+ * @param value [in] The value to add to the tail of the list
+ *
+ * @return XN_STATUS_ALLOC_FAILED failed to allocate new node
+ */
+ XnStatus AddLast(T const& value)
+ {
+ return InsertAfter(ReverseBegin().m_pCurrent, value);
+ }
+
+ /**
+ * Get an iterator pointing to a value in the list.
+ *
+ * @param value [in] The searched value
+ *
+ * @return End() if value doesn't exist
+ */
+ ConstIterator Find(T const& value) const
+ {
+ ConstIterator iter = Begin();
+ for (; iter != End(); ++iter)
+ {
+ if (*iter == value)
+ break;
+ }
+ return iter;
+ }
+
+ /**
+ * Get an iterator pointing to a value in the list.
+ *
+ * @param value [in] The searched value
+ *
+ * @return End() if value doesn't exist
+ */
+ Iterator Find(T const& value)
+ {
+ ConstIterator iter = const_cast<const XnListT<T>*>(this)->Find(value);
+ return Iterator(iter.m_pCurrent);
+ }
+
+ /**
+ * Remove a value from the list
+ *
+ * @param where [in] Iterator pointing to an entry in the list
+ *
+ * @return XN_STATUS_ILLEGAL_POSITION iterator was invalid
+ */
+ XnStatus Remove(ConstIterator where)
+ {
+ // Verify iterator is valid
+ if (where == End())
+ {
+ return XN_STATUS_ILLEGAL_POSITION;
+ }
+
+ XnLinkedNodeT<T>* pToRemove = where.m_pCurrent;
+
+ // Connect other nodes to bypass the one removed
+ pToRemove->pPrev->pNext = pToRemove->pNext;
+ pToRemove->pNext->pPrev = pToRemove->pPrev;
+
+ --m_nSize;
+
+ // Free memory
+ TAlloc::Deallocate(pToRemove);
+
+ return XN_STATUS_OK;
+ }
+
+ /**
+ * Removes the first occurrence of a value from the list
+ *
+ * @param value [in] The value to be removed
+ *
+ * @return XN_STATUS_NO_MATCH value wasn't found.
+ */
+ XnStatus Remove(T const& value)
+ {
+ ConstIterator it = Find(value);
+ if (it != End())
+ {
+ return Remove(it);
+ }
+ else
+ {
+ return XN_STATUS_NO_MATCH;
+ }
+ }
+
+ /**
+ * Remove all entries from the list
+ */
+ XnStatus Clear()
+ {
+ while (!IsEmpty())
+ Remove(Begin());
+
+ return XN_STATUS_OK;
+ }
+
+ /**
+ * Check if list is empty
+ */
+ XnBool IsEmpty() const
+ {
+ return (m_nSize == 0);
+ }
+
+ /**
+ * Gets the current size of the list
+ */
+ XnUInt32 Size() const
+ {
+ return m_nSize;
+ }
+
+ /**
+ * Copies all values in the list to an array.
+ *
+ * @param pArray A pre-allocated array that values should be copied to. The allocation size can be
+ determined using @ref Size().
+ */
+ void CopyTo(T* pArray) const
+ {
+ XN_ASSERT(pArray != NULL);
+
+ XnUInt32 i = 0;
+ for (ConstIterator iter = Begin(); iter != End(); ++iter, ++i)
+ {
+ pArray[i] = *iter;
+ }
+ }
+
+protected:
+ /**
+ * Add a new value to the list
+ *
+ * @param pAfter [in] The node after which to add the new value
+ * @param val [in] The value to add to the list
+ *
+ * @return XN_STATUS_ALLOC_FAILED Failed to add to the list because no nodes are available,
+ */
+ XnStatus InsertAfter(LinkedNode* pAfter, T const& val)
+ {
+ // Get a node from the pool for the entry
+ LinkedNode* pNewNode = TAlloc::Allocate(val);
+ if (pNewNode == NULL)
+ {
+ XN_ASSERT(FALSE);
+ return XN_STATUS_ALLOC_FAILED;
+ }
+ pNewNode->pPrev = pAfter;
+ pNewNode->pNext = pAfter->pNext;
+
+ // push new node to position
+ pAfter->pNext->pPrev = pNewNode;
+ pAfter->pNext = pNewNode;
+
+ ++m_nSize;
+
+ return XN_STATUS_OK;
+ }
+
+ // A dummy node, pointing to first node, and last node points back to it.
+ LinkedNode m_anchor;
+
+ XnUInt32 m_nSize;
+
+private:
+ void Init()
+ {
+ m_anchor.pNext = &m_anchor;
+ m_anchor.pPrev = &m_anchor;
+ m_nSize = 0;
+ }
+};
+
+#endif // _XNLISTT_H_ \ No newline at end of file
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnLog.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnLog.h
new file mode 100644
index 00000000..e26a0b50
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnLog.h
@@ -0,0 +1,545 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef _XN_LOG_H_
+#define _XN_LOG_H_
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include "XnOS.h"
+#include "XnLogTypes.h"
+#include "XnDump.h"
+
+//---------------------------------------------------------------------------
+// Exported Function Declaration
+//---------------------------------------------------------------------------
+
+/**
+ * @name Initialization
+ * Functions for initializing and shutting down the logger.
+ * @{
+ */
+
+/**
+* This function initializes the log system.
+*/
+XN_C_API XnStatus XN_C_DECL xnLogInitSystem();
+
+/**
+* This function initializes the log from an INI file.
+*
+* @param csINIFile [in] The name of the INI file.
+* @param csSectionName [in] The name of the section to read values from.
+*/
+XN_C_API XnStatus XN_C_DECL xnLogInitFromINIFile(const XnChar* csINIFile, const XnChar* csSectionName);
+
+/**
+* This function initializes the log from an XML file.
+*
+* @param strFileName [in] The name of the XML file.
+*/
+XN_C_API XnStatus XN_C_DECL xnLogInitFromXmlFile(const XnChar* strFileName);
+
+/**
+* This function closes the log.
+*/
+XN_C_API XnStatus XN_C_DECL xnLogClose();
+
+// @}
+
+/**
+ * @name Filtering Log Messages
+ * Functions for managing filters on the log system.
+ * @{
+ */
+
+/**
+* Sets the minimum severity to be output from a specific mask (logger name).
+*
+* @param strMask [in] Name of the logger.
+* @param minSeverity [in] Minimum severity to be output. Use @ref XN_LOG_SEVERITY_NONE to output nothing.
+*/
+XN_C_API XnStatus XN_C_DECL xnLogSetMaskMinSeverity(const XnChar* strMask, XnLogSeverity minSeverity);
+
+/**
+* Gets the minimum severity to be output from a specific mask (logger name).
+*
+* @param strMask [in] Name of the logger.
+*
+* @returns The minimum severity, or @ref XN_LOG_SEVERITY_NONE is mask will output nothing.
+*/
+XN_C_API XnLogSeverity XN_C_DECL xnLogGetMaskMinSeverity(const XnChar* strMask);
+
+// @}
+
+/**
+ * @name Log Writers
+ * Functions for managing which writers are active in the log system (i.e. which outputs
+ * will be generated).
+ * @{
+ */
+
+/**
+ * Registers a new Log Writer to receive log entries.
+ *
+ * @param pWriter [in] The writer to register
+ */
+XN_C_API XnStatus XN_C_DECL xnLogRegisterLogWriter(XnLogWriter* pWriter);
+
+/**
+ * Unregisters a Log Writer from receiving log entries.
+ *
+ * @param pWriter [in] The writer to unregister
+ */
+XN_C_API void XN_C_DECL xnLogUnregisterLogWriter(XnLogWriter* pWriter);
+
+/**
+* Configures if log entries will be printed to console.
+*
+* @param bConsoleOutput [in] TRUE to print log entries to console, FALSE otherwise.
+*/
+XN_C_API XnStatus XN_C_DECL xnLogSetConsoleOutput(XnBool bConsoleOutput);
+
+/**
+* Configures if log entries will be printed to a log file.
+*
+* @param bFileOutput [in] TRUE to print log entries to the file, FALSE otherwise.
+*/
+XN_C_API XnStatus XN_C_DECL xnLogSetFileOutput(XnBool bFileOutput);
+
+// @}
+
+/**
+ * @name File Output
+ * Functions for configuring how files are created.
+ * @{
+ */
+
+/**
+* This function closes current log file, and starts a new one (if file writer is currently active)
+*/
+XN_C_API XnStatus XN_C_DECL xnLogStartNewFile();
+
+/**
+* Configures if log entries in file will include the file and line that caused them.
+*
+* @param bLineInfo [in] TRUE to print file and line, FALSE otherwise
+*/
+XN_C_API XnStatus XN_C_DECL xnLogSetLineInfo(XnBool bLineInfo);
+
+/**
+ * Configures the folder under which logs will be written.
+ *
+ * @param strOutputFolder [in] Folder to write to
+ */
+XN_C_API XnStatus XN_C_DECL xnLogSetOutputFolder(const XnChar* strOutputFolder);
+
+/**
+ * Gets current log file name
+ *
+ * @param strFileName [in] A buffer to be filled
+ * @param nBufferSize [in] The size of the buffer
+ */
+XN_C_API XnStatus XN_C_DECL xnLogGetFileName(XnChar* strFileName, XnUInt32 nBufferSize);
+
+// @}
+
+/**
+ * @name Logger API
+ * Functions for writing entries to the log (used mainly by middleware developers)
+ * @{
+ */
+
+/**
+* Opens a logger for writing.
+*
+* @param strMask [in] Name of the logger to open.
+*/
+XN_C_API XnLogger* XN_C_DECL xnLoggerOpen(const XnChar* strMask);
+
+/**
+* Writes a single log entry.
+*
+* @param pLogger [in] Logger to write to
+* @param severity [in] Severity of the log entry
+* @param strFile [in] Name of the source file
+* @param nLine [in] Line in the source file
+* @param strFormat [in] Format string
+*
+* It is advised to use one of the @ref xnLoggerVerbose, @ref xnLoggerInfo, @ref xnLoggerWarning or
+* @ref xnLoggerError macros instead of calling this method directly.
+*/
+XN_C_API void XN_C_DECL xnLoggerWrite(XnLogger* pLogger, XnLogSeverity severity, const XnChar* strFile, XnUInt32 nLine, const XnChar* strFormat, ...);
+
+/**
+* Writes to a logger without an entry format (i.e. no timestamp, mask name, etc.)
+*
+* @param pLogger [in] Logger to write to
+* @param severity [in] Severity of the log entry
+* @param strFormat [in] Format string
+*/
+XN_C_API void XN_C_DECL xnLoggerWriteNoEntry(XnLogger* pLogger, XnLogSeverity severity, const XnChar* strFormat, ...);
+
+/**
+* Writes binary data to a logger, formatting it to readable text.
+*
+* @param pLogger [in] Logger to write to
+* @param severity [in] Severity of the log entry
+* @param strFile [in] Name of the source file
+* @param nLine [in] Line in the source file
+* @param pBinData [in] A pointer to the binary data to be written
+* @param nDataSize [in] The number of bytes to write
+* @param strFormat [in] Format string for the binary data header
+*/
+XN_C_API void XN_C_DECL xnLoggerWriteBinaryData(XnLogger* pLogger, XnLogSeverity severity, const XnChar* strFile, XnUInt32 nLine, XnUChar* pBinData, XnUInt32 nDataSize, const XnChar* strFormat, ...);
+
+/**
+* Checks if a specific severity is enabled for this logger.
+*
+* @param pLogger [in] Logger to check
+* @param severity [in] Severity to check.
+*/
+XN_C_API XnBool XN_C_DECL xnLoggerIsEnabled(XnLogger* pLogger, XnLogSeverity severity);
+
+/**
+* Closes a logger previsouly opened using @ref xnLoggerOpen().
+*
+* @param pLogger [in] The logger to be closed.
+*/
+XN_C_API void XN_C_DECL _xnLoggerClose(XnLogger* pLogger);
+
+/**
+* Closes a logger and NULLs the handle.
+*
+* @param pLogger [in] The logger to be closed.
+*/
+#define xnLoggerClose(pLogger) \
+ { \
+ _xnLoggerClose(pLogger); \
+ pLogger = NULL; \
+ }
+
+#if XN_PLATFORM_VAARGS_TYPE == XN_PLATFORM_USE_WIN32_VAARGS_STYLE
+ /**
+ * Helper macro for logging. Checks inline if logger is enabled and adds source file and line info.
+ */
+ #define xnLoggerWriteHelper(pLogger, severity, csFormat, ...) \
+ if (pLogger != NULL && severity >= pLogger->nMinSeverity) \
+ { \
+ xnLoggerWrite(pLogger, severity, __FILE__, __LINE__, csFormat, __VA_ARGS__); \
+ }
+
+ /**
+ * Helper macro for logging. Issues a verbose log entry.
+ */
+ #define xnLoggerVerbose(pLogger, csFormat, ...) xnLoggerWriteHelper(pLogger, XN_LOG_VERBOSE, csFormat, __VA_ARGS__)
+ /**
+ * Helper macro for logging. Issues an info log entry.
+ */
+ #define xnLoggerInfo(pLogger, csFormat, ...) xnLoggerWriteHelper(pLogger, XN_LOG_INFO, csFormat, __VA_ARGS__)
+ /**
+ * Helper macro for logging. Issues a warning log entry.
+ */
+ #define xnLoggerWarning(pLogger, csFormat, ...) xnLoggerWriteHelper(pLogger, XN_LOG_WARNING, csFormat, __VA_ARGS__)
+ /**
+ * Helper macro for logging. Issues an error log entry.
+ */
+ #define xnLoggerError(pLogger, csFormat, ...) xnLoggerWriteHelper(pLogger, XN_LOG_ERROR, csFormat, __VA_ARGS__)
+
+ /**
+ * Helper macro for returning from a function while logging
+ *
+ * @param pLogger [in] The logger to be closed.
+ * @param nRetVal [in] The return value from the function.
+ * @param severity [in] Severity of the log entry
+ * @param csFormat [in] Format string
+ */
+ #define XN_RETURN_WITH_LOG(pLogger, nRetVal, severity, csFormat, ...) \
+ { \
+ xnLoggerWriteHelper(pLogger, severity, csFormat, __VA_ARGS__); \
+ return (nRetVal); \
+ }
+
+ /**
+ * Helper macro for returning from a function while logging a warning
+ *
+ * @param pLogger [in] The logger to be closed.
+ * @param nRetVal [in] The return value from the function.
+ * @param csFormat [in] Format string
+ */
+ #define XN_RETURN_WITH_WARNING_LOG(pLogger, nRetVal, csFormat, ...) \
+ XN_RETURN_WITH_LOG(pLogger, nRetVal, XN_LOG_WARNING, csFormat, __VA_ARGS__)
+
+ /**
+ * Helper macro for returning from a function while logging an error
+ *
+ * @param pLogger [in] The logger to be closed.
+ * @param nRetVal [in] The return value from the function.
+ * @param csFormat [in] Format string
+ */
+ #define XN_RETURN_WITH_ERROR_LOG(pLogger, nRetVal, csFormat, ...) \
+ XN_RETURN_WITH_LOG(pLogger, nRetVal, XN_LOG_ERROR, csFormat, __VA_ARGS__)
+
+#elif XN_PLATFORM_VAARGS_TYPE == XN_PLATFORM_USE_GCC_VAARGS_STYLE
+ #define xnLoggerWriteHelper(pLogger, severity, csFormat, ...) \
+ if (pLogger != NULL && severity >= pLogger->nMinSeverity) \
+ { \
+ xnLoggerWrite(pLogger, severity, __FILE__, __LINE__, csFormat, ##__VA_ARGS__); \
+ }
+
+ #define xnLoggerVerbose(pLogger, csFormat, ...) xnLoggerWriteHelper(pLogger, XN_LOG_VERBOSE, csFormat,## __VA_ARGS__)
+ #define xnLoggerInfo(pLogger, csFormat, ...) xnLoggerWriteHelper(pLogger, XN_LOG_INFO, csFormat, ##__VA_ARGS__)
+ #define xnLoggerWarning(pLogger, csFormat, ...) xnLoggerWriteHelper(pLogger, XN_LOG_WARNING, csFormat, ##__VA_ARGS__)
+ #define xnLoggerError(pLogger, csFormat, ...) xnLoggerWriteHelper(pLogger, XN_LOG_ERROR, csFormat, ##__VA_ARGS__)
+
+ /* Writes to the log and returns nRetVal */
+ #define XN_RETURN_WITH_LOG(pLogger, nRetVal, severity, csFormat, ...) \
+ { \
+ xnLoggerWriteHelper(pLogger, severity, csFormat, ##__VA_ARGS__); \
+ return (nRetVal); \
+ }
+
+ /* Logs a warning and returns nRetVal */
+ #define XN_RETURN_WITH_WARNING_LOG(pLogger, nRetVal, csFormat, ...) \
+ XN_RETURN_WITH_LOG(pLogger, nRetVal, XN_LOG_WARNING, csFormat, ##__VA_ARGS__)
+
+ /* Logs an error and returns nRetVal */
+ #define XN_RETURN_WITH_ERROR_LOG(pLogger, nRetVal, csFormat, ...) \
+ XN_RETURN_WITH_LOG(pLogger, nRetVal, XN_LOG_ERROR, csFormat, ##__VA_ARGS__)
+
+#elif XN_PLATFORM_VAARGS_TYPE == XN_PLATFORM_USE_ARC_VAARGS_STYLE
+ #define xnLoggerWriteHelper(pLogger, severity, csFormat...) \
+ if (pLogger != NULL && severity >= pLogger->nMinSeverity) \
+ { \
+ xnLoggerWrite(pLogger, severity, __FILE__, __LINE__, csFormat); \
+ }
+
+ #define xnLoggerVerbose(pLogger, csFormat...) xnLoggerWriteHelper(pLogger, XN_LOG_VERBOSE, csFormat)
+ #define xnLoggerInfo(pLogger, csFormat...) xnLoggerWriteHelper(pLogger, XN_LOG_INFO, csFormat)
+ #define xnLoggerWarning(pLogger, csFormat...) xnLoggerWriteHelper(pLogger, XN_LOG_WARNING, csFormat)
+ #define xnLoggerError(pLogger, csFormat...) xnLoggerWriteHelper(pLogger, XN_LOG_ERROR, csFormat)
+
+ /* Writes to the log and returns nRetVal */
+ #define XN_RETURN_WITH_LOG(pLogger, nRetVal, severity, csFormat...) \
+ { \
+ xnLoggerWriteHelper(pLogger, severity, csFormat); \
+ return (nRetVal); \
+ }
+
+ /* Logs a warning and returns nRetVal */
+ #define XN_RETURN_WITH_WARNING_LOG(pLogger, nRetVal, csFormat...) \
+ XN_RETURN_WITH_LOG(pLogger, nRetVal, XN_LOG_WARNING, csFormat)
+
+ /* Logs an error and returns nRetVal */
+ #define XN_RETURN_WITH_ERROR_LOG(pLogger, nRetVal, csFormat...) \
+ XN_RETURN_WITH_LOG(pLogger, nRetVal, XN_LOG_ERROR, csFormat)
+
+#elif XN_PLATFORM_VAARGS_TYPE == XN_PLATFORM_USE_NO_VAARGS
+ #define xnLoggerWriteHelper(pLogger, severity, csFormat, arg) \
+ if (pLogger != NULL && severity >= pLogger->nMinSeverity) \
+ { \
+ xnLoggerWrite(pLogger, severity, __FILE__, __LINE__, csFormat, arg); \
+ }
+
+ #define xnLoggerVerbose(pLogger, csFormat, arg) xnLoggerWriteHelper(pLogger, XN_LOG_VERBOSE, csFormat, arg)
+ #define xnLoggerInfo(pLogger, csFormat, arg) xnLoggerWriteHelper(pLogger, XN_LOG_INFO, csFormat, arg)
+ #define xnLoggerWarning(pLogger, csFormat, arg) xnLoggerWriteHelper(pLogger, XN_LOG_WARNING, csFormat, arg)
+ #define xnLoggerError(pLogger, csFormat, arg) xnLoggerWriteHelper(pLogger, XN_LOG_ERROR, csFormat, arg)
+
+ /* Writes to the log and returns nRetVal */
+ #define XN_RETURN_WITH_LOG(pLogger, nRetVal, severity, csFormat) \
+ { \
+ xnLoggerWriteHelper(pLogger, severity, csFormat); \
+ return (nRetVal); \
+ }
+
+ /* Logs a warning and returns nRetVal */
+ #define XN_RETURN_WITH_WARNING_LOG(pLogger, nRetVal, csFormat) \
+ XN_RETURN_WITH_LOG(pLogger, nRetVal, XN_LOG_WARNING, csFormat)
+
+ /* Logs an error and returns nRetVal */
+ #define XN_RETURN_WITH_ERROR_LOG(pLogger, nRetVal, csFormat) \
+ XN_RETURN_WITH_LOG(pLogger, nRetVal, XN_LOG_ERROR, csFormat)
+
+#else
+ #error Xiron Log - Unknown VAARGS type!
+#endif
+
+// @}
+
+/**
+ * @name Misc.
+ * Miscellaneous functions regarding the log system.
+ * @{
+ */
+
+/**
+ * Creates a new file under the logs directory.
+ *
+ * @param strName [in] Name of the file to create
+ * @param bSessionBased [in] TRUE for a session-based file, FALSE otherwise. A session based
+ * file also includes the timestamp and process ID of the running
+ * process as a prefix to its name.
+ * @param csFullPath [in/out] A buffer to be filled with full path of the created file
+ * @param nPathBufferSize [in] The size of the <c>csFullPath</c> buffer
+ * @param phFile [out] The file handle
+ */
+XN_C_API XnStatus XN_C_DECL xnLogCreateNewFile(const XnChar* strName, XnBool bSessionBased, XnChar* csFullPath, XnUInt32 nPathBufferSize, XN_FILE_HANDLE* phFile);
+
+// @}
+
+#define XN_MASK_RETVAL_CHECKS "RetValChecks"
+
+#if XN_PLATFORM == XN_PLATFORM_ARC
+extern "C" XnLogger* XN_LOGGER_RETVAL_CHECKS;
+#else
+XN_C_API XnLogger* XN_LOGGER_RETVAL_CHECKS;
+#endif
+
+/** Validates return value and writes log message with appropriate status string **/
+#define XN_IS_STATUS_OK_LOG_ERROR(what, nRetVal) \
+ if (nRetVal != XN_STATUS_OK) \
+ { \
+ xnLoggerError(XN_LOGGER_RETVAL_CHECKS, "Failed to " what ": %s", xnGetStatusString(nRetVal)); \
+ XN_ASSERT(FALSE); \
+ return (nRetVal); \
+ }
+
+
+#ifndef __XN_NO_BC__
+
+XN_C_API XnStatus XN_API_DEPRECATED("Please use xnLogSetMaskMinSeverity() instead") XN_C_DECL xnLogSetMaskState(const XnChar* csMask, XnBool bEnabled);
+XN_C_API XnStatus XN_API_DEPRECATED("Please use xnLogSetMaskMinSeverity() instead") XN_C_DECL xnLogSetSeverityFilter(XnLogSeverity nMinSeverity);
+XN_C_API XnBool XN_C_DECL xnLogIsEnabled(const XnChar* csLogMask, XnLogSeverity nSeverity);
+XN_C_API void XN_C_DECL xnLogWrite(const XnChar* csLogMask, XnLogSeverity nSeverity, const XnChar* csFile, XnUInt32 nLine, const XnChar* csFormat, ...);
+XN_C_API void XN_C_DECL xnLogWriteNoEntry(const XnChar* csLogMask, XnLogSeverity nSeverity, const XnChar* csFormat, ...);
+XN_C_API void XN_C_DECL xnLogWriteBinaryData(const XnChar* csLogMask, XnLogSeverity nSeverity, const XnChar* csFile, XnUInt32 nLine, XnUChar* pBinData, XnUInt32 nDataSize, const XnChar* csFormat, ...);
+XN_C_API XnStatus XN_API_DEPRECATED("Use xnLogCreateNewFile() instead") XN_C_DECL xnLogCreateFile(const XnChar* strFileName, XN_FILE_HANDLE* phFile);
+XN_C_API XnStatus XN_API_DEPRECATED("Use xnLogCreateNewFile() instead") XN_C_DECL xnLogCreateFileEx(const XnChar* strFileName, XnBool bSessionBased, XN_FILE_HANDLE* phFile);
+
+#if XN_PLATFORM_VAARGS_TYPE == XN_PLATFORM_USE_WIN32_VAARGS_STYLE
+ #define xnLogVerbose(csLogMask, csFormat, ...) xnLogWrite(csLogMask, XN_LOG_VERBOSE, __FILE__, __LINE__, csFormat, __VA_ARGS__)
+ #define xnLogInfo(csLogMask, csFormat, ...) xnLogWrite(csLogMask, XN_LOG_INFO, __FILE__, __LINE__, csFormat, __VA_ARGS__)
+ #define xnLogWarning(csLogMask, csFormat, ...) xnLogWrite(csLogMask, XN_LOG_WARNING, __FILE__, __LINE__, csFormat, __VA_ARGS__)
+ #define xnLogError(csLogMask, csFormat, ...) xnLogWrite(csLogMask, XN_LOG_ERROR, __FILE__, __LINE__, csFormat, __VA_ARGS__)
+
+ /* Writes to the log and returns nRetVal */
+ #define XN_LOG_RETURN(nRetVal, nSeverity, csLogMask, csFormat, ...) \
+ { \
+ xnLogWrite(csLogMask, nSeverity, __FILE__, __LINE__, csFormat, __VA_ARGS__); \
+ return (nRetVal); \
+ }
+
+ /* Logs a warning and returns nRetVal */
+ #define XN_LOG_WARNING_RETURN(nRetVal, csLogMask, csFormat, ...) \
+ XN_LOG_RETURN(nRetVal, XN_LOG_WARNING, csLogMask, csFormat, __VA_ARGS__)
+
+ /* Logs a warning and returns nRetVal */
+ #define XN_LOG_ERROR_RETURN(nRetVal, csLogMask, csFormat, ...) \
+ XN_LOG_RETURN(nRetVal, XN_LOG_ERROR, csLogMask, csFormat, __VA_ARGS__)
+
+#elif XN_PLATFORM_VAARGS_TYPE == XN_PLATFORM_USE_GCC_VAARGS_STYLE
+ #define xnLogVerbose(csLogMask, csFormat, ...) xnLogWrite(csLogMask, XN_LOG_VERBOSE, __FILE__, __LINE__, csFormat, ##__VA_ARGS__)
+ #define xnLogInfo(csLogMask, csFormat, ...) xnLogWrite(csLogMask, XN_LOG_INFO, __FILE__, __LINE__, csFormat, ##__VA_ARGS__)
+ #define xnLogWarning(csLogMask, csFormat, ...) xnLogWrite(csLogMask, XN_LOG_WARNING, __FILE__, __LINE__, csFormat, ##__VA_ARGS__)
+ #define xnLogError(csLogMask, csFormat, ...) xnLogWrite(csLogMask, XN_LOG_ERROR, __FILE__, __LINE__, csFormat, ##__VA_ARGS__)
+
+ /* Writes to the log and returns nRetVal */
+ #define XN_LOG_RETURN(nRetVal, nSeverity, csLogMask, csFormat, ...) \
+ { \
+ xnLogWrite(csLogMask, nSeverity, __FILE__, __LINE__, csFormat, ##__VA_ARGS__); \
+ return (nRetVal); \
+ }
+
+ /* Logs a warning and returns nRetVal */
+ #define XN_LOG_WARNING_RETURN(nRetVal, csLogMask, csFormat, ...) \
+ XN_LOG_RETURN(nRetVal, XN_LOG_WARNING, csLogMask, csFormat, ##__VA_ARGS__)
+
+ /* Logs a warning and returns nRetVal */
+ #define XN_LOG_ERROR_RETURN(nRetVal, csLogMask, csFormat, ...) \
+ XN_LOG_RETURN(nRetVal, XN_LOG_ERROR, csLogMask, csFormat, ##__VA_ARGS__)
+
+#elif XN_PLATFORM_VAARGS_TYPE == XN_PLATFORM_USE_ARC_VAARGS_STYLE
+ #define xnLogVerbose(csLogMask, csFormat...) xnLogWrite(csLogMask, XN_LOG_VERBOSE, __FILE__, __LINE__, csFormat)
+ #define xnLogInfo(csLogMask, csFormat...) xnLogWrite(csLogMask, XN_LOG_INFO, __FILE__, __LINE__, csFormat)
+ #define xnLogWarning(csLogMask, csFormat...) xnLogWrite(csLogMask, XN_LOG_WARNING, __FILE__, __LINE__, csFormat)
+ #define xnLogError(csLogMask, csFormat...) xnLogWrite(csLogMask, XN_LOG_ERROR, __FILE__, __LINE__, csFormat)
+
+ /* Writes to the log and returns nRetVal */
+ #define XN_LOG_RETURN(nRetVal, nSeverity, csLogMask, csFormat...) \
+ { \
+ xnLogWrite(csLogMask, nSeverity, __FILE__, __LINE__, csFormat); \
+ return (nRetVal); \
+ }
+
+ /* Logs a warning and returns nRetVal */
+ #define XN_LOG_WARNING_RETURN(nRetVal, csLogMask, csFormat...) \
+ XN_LOG_RETURN(nRetVal, XN_LOG_WARNING, csLogMask, csFormat)
+
+ /* Logs a warning and returns nRetVal */
+ #define XN_LOG_ERROR_RETURN(nRetVal, csLogMask, csFormat...) \
+ XN_LOG_RETURN(nRetVal, XN_LOG_ERROR, csLogMask, csFormat)
+
+ /* If nRetVal is not ok, writes to the log and returns nRetVal */
+ #define XN_IS_STATUS_OK_LOG(nRetVal, nSeverity, csLogMask, csFormat...) \
+ if (nRetVal != XN_STATUS_OK) \
+ { \
+ XN_LOG_RETURN(nRetVal, nSeverity, csLogMask, csFormat) \
+ }
+
+ /* If nRetVal is not ok, logs a warning and returns nRetVal */
+ #define XN_IS_STATUS_OK_WARNING(nRetVal, csLogMask, csFormat...) \
+ XN_IS_STATUS_OK_LOG(nRetVal, XN_LOG_WARNING, csLogMask, csFormat)
+
+ /* If nRetVal is not ok, logs an error and returns nRetVal */
+ #define XN_IS_STATUS_OK_ERROR(nRetVal, csLogMask, csFormat...) \
+ XN_IS_STATUS_OK_LOG(nRetVal, XN_LOG_ERROR, csLogMask, csFormat)
+
+#elif XN_PLATFORM_VAARGS_TYPE == XN_PLATFORM_USE_NO_VAARGS
+ #define xnLogVerbose(csLogMask, csFormat, args) xnLogWrite(csLogMask, XN_LOG_VERBOSE, __FILE__, __LINE__, csFormat, args)
+ #define xnLogInfo(csLogMask, csFormat, args) xnLogWrite(csLogMask, XN_LOG_INFO, __FILE__, __LINE__, csFormat, args)
+ #define xnLogWarning(csLogMask, csFormat, args) xnLogWrite(csLogMask, XN_LOG_WARNING, __FILE__, __LINE__, csFormat, args)
+ #define xnLogError(csLogMask, csFormat, args) xnLogWrite(csLogMask, XN_LOG_ERROR, __FILE__, __LINE__, csFormat, args)
+
+ /* Writes to the log and returns nRetVal */
+ #define XN_LOG_RETURN(nRetVal, nSeverity csLogMask, csFormat, args) \
+ { \
+ xnLogWrite(csLogMask, nSeverity, __FILE__, __LINE__, csFormat, args); \
+ return (nRetVal); \
+ }
+
+ /* Logs a warning and returns nRetVal */
+ #define XN_LOG_WARNING_RETURN(nRetVal, csLogMask, csFormat, args) \
+ XN_LOG_RETURN(nRetVal, XN_LOG_WARNING, csLogMask, csFormat, args)
+
+ /* Logs an error and returns nRetVal */
+ #define XN_LOG_ERROR_RETURN(nRetVal, csLogMask, csFormat, args) \
+ XN_LOG_RETURN(nRetVal, XN_LOG_ERROR, csLogMask, csFormat, args)
+
+#else
+ #error Xiron Log - Unknown VAARGS type!
+#endif
+
+#endif // ifndef __XN_NO_BC__
+
+#endif //_XN_LOG_H_
+
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnLogTypes.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnLogTypes.h
new file mode 100644
index 00000000..c8da2b87
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnLogTypes.h
@@ -0,0 +1,80 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef __XN_LOG_TYPES_H__
+#define __XN_LOG_TYPES_H__
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include "XnPlatform.h"
+#include "XnTypes.h"
+
+//---------------------------------------------------------------------------
+// Defines
+//---------------------------------------------------------------------------
+#define XN_LOG_DIR_NAME "Log"
+#define XN_MASK_LOG "Log"
+#define XN_LOG_MASK_ALL "ALL"
+#define XN_LOG_MAX_MASK_NAME 16
+
+//---------------------------------------------------------------------------
+// Enums
+//---------------------------------------------------------------------------
+typedef enum XnLogSeverity
+{
+ XN_LOG_VERBOSE = 0,
+ XN_LOG_INFO = 1,
+ XN_LOG_WARNING = 2,
+ XN_LOG_ERROR = 3,
+ XN_LOG_SEVERITY_NONE = 10,
+} XnLogSeverity;
+
+//---------------------------------------------------------------------------
+// Structs
+//---------------------------------------------------------------------------
+typedef struct XnLogger
+{
+ volatile XnLogSeverity nMinSeverity;
+ void* pInternal;
+} XnLogger;
+
+typedef struct XnLogEntry
+{
+ XnUInt64 nTimestamp;
+ XnLogSeverity nSeverity;
+ const XnChar* strSeverity;
+ const XnChar* strMask;
+ const XnChar* strMessage;
+ const XnChar* strFile;
+ XnUInt32 nLine;
+} XnLogEntry;
+
+typedef struct XnLogWriter
+{
+ void* pCookie;
+ void (XN_CALLBACK_TYPE* WriteEntry)(const XnLogEntry* pEntry, void* pCookie);
+ void (XN_CALLBACK_TYPE* WriteUnformatted)(const XnChar* strMessage, void* pCookie);
+ void (XN_CALLBACK_TYPE* OnConfigurationChanged)(void* pCookie);
+ void (XN_CALLBACK_TYPE* OnClosing)(void* pCookie);
+} XnLogWriter;
+
+#endif // __XN_LOG_TYPES_H__ \ No newline at end of file
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnLogWriterBase.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnLogWriterBase.h
new file mode 100644
index 00000000..33bed1c6
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnLogWriterBase.h
@@ -0,0 +1,128 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef __XN_LOG_WRITER_BASE_H__
+#define __XN_LOG_WRITER_BASE_H__
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include <XnLogTypes.h>
+#include <XnLog.h>
+
+//---------------------------------------------------------------------------
+// Types
+//---------------------------------------------------------------------------
+class XnLogWriterBase
+{
+public:
+ XnLogWriterBase() : m_bRegistered(FALSE)
+ {
+ m_cObject.pCookie = this;
+ m_cObject.WriteEntry = WriteEntryCallback;
+ m_cObject.WriteUnformatted = WriteUnformattedCallback;
+ m_cObject.OnConfigurationChanged = OnConfigurationChangedCallback;
+ m_cObject.OnClosing = OnClosingCallback;
+ }
+
+ virtual ~XnLogWriterBase()
+ {
+ Unregister();
+ }
+
+ XnStatus Register()
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ if (!m_bRegistered)
+ {
+ OnRegister();
+
+ nRetVal = xnLogRegisterLogWriter(&m_cObject);
+ if (nRetVal != XN_STATUS_OK)
+ {
+ OnUnregister();
+ return (nRetVal);
+ }
+
+ m_bRegistered = TRUE;
+ }
+
+ return (XN_STATUS_OK);
+ }
+
+ void Unregister()
+ {
+ if (m_bRegistered)
+ {
+ xnLogUnregisterLogWriter(&m_cObject);
+ m_bRegistered = FALSE;
+
+ OnUnregister();
+ }
+ }
+
+ inline XnBool IsRegistered() { return m_bRegistered; }
+
+ virtual void WriteEntry(const XnLogEntry* pEntry) = 0;
+ virtual void WriteUnformatted(const XnChar* strMessage) = 0;
+ virtual void OnConfigurationChanged() {};
+ virtual void OnClosing()
+ {
+ Unregister();
+ };
+
+ operator const XnLogWriter*() const
+ {
+ return &m_cObject;
+ }
+
+protected:
+ virtual void OnRegister() {}
+ virtual void OnUnregister() {}
+
+private:
+ static void XN_CALLBACK_TYPE WriteEntryCallback(const XnLogEntry* pEntry, void* pCookie)
+ {
+ XnLogWriterBase* pThis = (XnLogWriterBase*)pCookie;
+ pThis->WriteEntry(pEntry);
+ }
+ static void XN_CALLBACK_TYPE WriteUnformattedCallback(const XnChar* strMessage, void* pCookie)
+ {
+ XnLogWriterBase* pThis = (XnLogWriterBase*)pCookie;
+ pThis->WriteUnformatted(strMessage);
+ }
+ static void XN_CALLBACK_TYPE OnConfigurationChangedCallback(void* pCookie)
+ {
+ XnLogWriterBase* pThis = (XnLogWriterBase*)pCookie;
+ pThis->OnConfigurationChanged();
+ }
+ static void XN_CALLBACK_TYPE OnClosingCallback(void* pCookie)
+ {
+ XnLogWriterBase* pThis = (XnLogWriterBase*)pCookie;
+ pThis->OnClosing();
+ }
+
+ XnLogWriter m_cObject;
+ XnBool m_bRegistered;
+};
+
+#endif // __XN_LOG_WRITER_BASE_H__
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnMacros.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnMacros.h
new file mode 100644
index 00000000..694bc2ad
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnMacros.h
@@ -0,0 +1,128 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef _XN_MACROS_H_
+#define _XN_MACROS_H_
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include "XnStatusCodes.h"
+
+//---------------------------------------------------------------------------
+// Macros
+//---------------------------------------------------------------------------
+
+/** Returns the (x)th power of 2. */
+#define XN_SETBITMASK(x) (1 << x-1)
+
+/** Returns Y if X is NULL. */
+#define XN_RET_IF_NULL(x, y) \
+ if (x == NULL) \
+ { \
+ return (y); \
+ }
+
+/** Returns Y if X isn't XN_STATUS_OK. */
+#define XN_IS_STATUS_OK_RET(x, y) \
+ if (x != XN_STATUS_OK) \
+ { \
+ return (y); \
+ }
+
+/** Jumps to the ErrorCleanUp label if X isn't XN_STATUS_OK and return Y. */
+#define XN_IS_STATUS_OK_GOCLEANUP_RET(x, y) \
+ if (x != XN_STATUS_OK) \
+ { \
+ x = y; \
+ goto ErrorCleanUp; \
+ }
+
+/** Returns X if X isn't XN_STATUS_OK. */
+#define XN_IS_STATUS_OK(x) \
+ XN_IS_STATUS_OK_RET(x, x)
+
+#define XN_IS_STATUS_OK_ASSERT(x) \
+ if (x != XN_STATUS_OK) \
+ { \
+ XN_ASSERT(FALSE); \
+ return (x); \
+ }
+
+
+/** Jumps to the ErrorCleanUp label if X isn't XN_STATUS_OK. */
+#define XN_IS_STATUS_OK_GOCLEANUP(x) \
+ if (x != XN_STATUS_OK) \
+ { \
+ goto ErrorCleanUp; \
+ }
+
+/** Returns Y if X isn't XN_STATUS_OK. */
+#define XN_IS_BOOL_OK_RET(x, y) \
+ if (x != TRUE) \
+ { \
+ return (y); \
+ }
+
+/** Jumps to the ErrorCleanUp label if X isn't XN_STATUS_OK and returns Y. */
+#define XN_IS_BOOL_OK_GOCLEANUP_RET(x, y) \
+ if (x != TRUE) \
+ { \
+ goto ErrorCleanUp; \
+ }
+
+/** Jumps to the ErrorCleanUp label if X isn't XN_STATUS_OK and returns Y. */
+#define XN_GOCLEANUP_RET(x, y) \
+ x = y; \
+ goto ErrorCleanUp;
+
+/** Returns Y if X is null. */
+#define XN_VALIDATE_PTR(x,y) \
+ if (x == NULL) \
+ { \
+ return (y); \
+ }
+
+/** Returns an output overflow error if x is beyond y */
+#define XN_CHECK_INPUT_OVERFLOW(x, y) \
+ if (x > y) \
+ { \
+ return (XN_STATUS_INPUT_BUFFER_OVERFLOW); \
+ }
+
+/** Returns an input overflow error if x is beyond y */
+#define XN_CHECK_OUTPUT_OVERFLOW(x, y) \
+ if (x > y) \
+ { \
+ return (XN_STATUS_OUTPUT_BUFFER_OVERFLOW); \
+ }
+
+/** Disables Copy ctor and assignment operator. Should be placed under "private:" section. */
+#define XN_DISABLE_COPY_AND_ASSIGN(TypeName) \
+ TypeName(const TypeName&); \
+ void operator=(const TypeName&);
+
+/** Disables the "local variable is initialized but not referenced" warning (if you need
+ to use this variable in an assert */
+#define XN_REFERENCE_VARIABLE(x) \
+ ((void)x)
+
+#endif //_XN_MACROS_H_
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnModuleCFunctions.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnModuleCFunctions.h
new file mode 100644
index 00000000..f588a0a0
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnModuleCFunctions.h
@@ -0,0 +1,1995 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef XN_MODULE_C_FUNCTIONS_H_
+#define XN_MODULE_C_FUNCTIONS_H_
+
+#include "XnModuleCppInterface.h"
+
+using namespace xn;
+
+#ifdef XN_NO_DYNAMIC_CAST
+#include "XnDerivedCast.h"
+#endif
+
+#define _XN_VALIDATE_CAPABILITY_INTERFACE_RET(capInterface, retVal) \
+ if (capInterface == NULL) \
+ return retVal;
+
+#define _XN_VALIDATE_CAPABILITY_INTERFACE(capInterface) \
+ _XN_VALIDATE_CAPABILITY_INTERFACE_RET(capInterface, XN_STATUS_INVALID_OPERATION)
+
+XnBool XN_CALLBACK_TYPE __ModuleIsCapabilitySupported(XnModuleNodeHandle hInstance, const XnChar* strCapabilityName)
+{
+ ModuleProductionNode* pNode = (ModuleProductionNode*)hInstance;
+ return pNode->IsCapabilitySupported(strCapabilityName);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleInitNotifications(XnModuleNodeHandle hInstance, XnNodeNotifications* pNotifications, void* pCookie)
+{
+ ModuleProductionNode* pNode = (ModuleProductionNode*)hInstance;
+ ModuleExtendedSerializationInterface* pInterface = pNode->GetExtendedSerializationInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->NotifyExState(pNotifications, pCookie);
+}
+void XN_CALLBACK_TYPE __ModuleStopNotifications(XnModuleNodeHandle hInstance)
+{
+ ModuleProductionNode* pNode = (ModuleProductionNode*)hInstance;
+ ModuleExtendedSerializationInterface* pInterface = pNode->GetExtendedSerializationInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE_RET(pInterface,);
+ pInterface->UnregisterExNotifications();
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleSetLockState(XnModuleNodeHandle hInstance, XnBool bLocked)
+{
+ ModuleProductionNode* pNode = (ModuleProductionNode*)hInstance;
+ ModuleLockAwareInterface* pInterface = pNode->GetLockAwareInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->SetLockState(bLocked);
+}
+
+XnBool XN_CALLBACK_TYPE __ModuleGetLockState(XnModuleNodeHandle hInstance)
+{
+ ModuleProductionNode* pNode = (ModuleProductionNode*)hInstance;
+ ModuleLockAwareInterface* pInterface = pNode->GetLockAwareInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE_RET(pInterface, FALSE);
+ return pInterface->GetLockState();
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleRegisterToLockChange(XnModuleNodeHandle hInstance, XnModuleStateChangedHandler handler, void* pCookie, XnCallbackHandle* phCallback)
+{
+ ModuleProductionNode* pNode = (ModuleProductionNode*)hInstance;
+ ModuleLockAwareInterface* pInterface = pNode->GetLockAwareInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->RegisterToLockChange(handler, pCookie, *phCallback);
+}
+
+void XN_CALLBACK_TYPE __ModuleUnregisterFromLockChange(XnModuleNodeHandle hInstance, XnCallbackHandle hCallback)
+{
+ ModuleProductionNode* pNode = (ModuleProductionNode*)hInstance;
+ ModuleLockAwareInterface* pInterface = pNode->GetLockAwareInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE_RET(pInterface,);
+ pInterface->UnregisterFromLockChange(hCallback);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleGetErrorState(XnModuleNodeHandle hInstance)
+{
+ ModuleProductionNode* pNode = (ModuleProductionNode*)hInstance;
+ ModuleErrorStateInterface* pInterface = pNode->GetErrorStateInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE_RET(pInterface, XN_STATUS_OK);
+ return pInterface->GetErrorState();
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleRegisterToErrorStateChange(XnModuleNodeHandle hInstance, XnModuleStateChangedHandler handler, void* pCookie, XnCallbackHandle* phCallback)
+{
+ ModuleProductionNode* pNode = (ModuleProductionNode*)hInstance;
+ ModuleErrorStateInterface* pInterface = pNode->GetErrorStateInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->RegisterToErrorStateChange(handler, pCookie, *phCallback);
+}
+
+void XN_CALLBACK_TYPE __ModuleUnregisterFromErrorStateChange(XnModuleNodeHandle hInstance, XnCallbackHandle hCallback)
+{
+ ModuleProductionNode* pNode = (ModuleProductionNode*)hInstance;
+ ModuleErrorStateInterface* pInterface = pNode->GetErrorStateInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE_RET(pInterface,);
+ pInterface->UnregisterFromErrorStateChange(hCallback);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleGeneralIntGetRange(XnModuleNodeHandle hInstance, const XnChar* strCap, XnInt32* pnMin, XnInt32* pnMax, XnInt32* pnStep, XnInt32* pnDefault, XnBool* pbIsAutoSupported)
+{
+ ModuleProductionNode* pNode = (ModuleProductionNode*)hInstance;
+ ModuleGeneralIntInterface* pInterface = pNode->GetGeneralIntInterface(strCap);
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->GetRange(strCap, *pnMin, *pnMax, *pnStep, *pnDefault, *pbIsAutoSupported);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleGeneralIntGet(XnModuleNodeHandle hInstance, const XnChar* strCap, XnInt32* pnValue)
+{
+ ModuleProductionNode* pNode = (ModuleProductionNode*)hInstance;
+ ModuleGeneralIntInterface* pInterface = pNode->GetGeneralIntInterface(strCap);
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->Get(strCap, *pnValue);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleGeneralIntSet(XnModuleNodeHandle hInstance, const XnChar* strCap, XnInt32 nValue)
+{
+ ModuleProductionNode* pNode = (ModuleProductionNode*)hInstance;
+ ModuleGeneralIntInterface* pInterface = pNode->GetGeneralIntInterface(strCap);
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->Set(strCap, nValue);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleGeneralIntRegisterToValueChange
+ (XnModuleNodeHandle hInstance, const XnChar* strCap, XnModuleStateChangedHandler handler,
+ void* pCookie, XnCallbackHandle* phCallback)
+{
+ ModuleProductionNode* pNode = (ModuleProductionNode*)hInstance;
+ ModuleGeneralIntInterface* pInterface = pNode->GetGeneralIntInterface(strCap);
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->RegisterToValueChange(strCap, handler, pCookie, *phCallback);
+}
+
+void XN_CALLBACK_TYPE __ModuleGeneralIntUnregisterFromValueChange
+ (XnModuleNodeHandle hInstance, const XnChar* strCap, XnCallbackHandle hCallback)
+{
+ ModuleProductionNode* pNode = (ModuleProductionNode*)hInstance;
+ ModuleGeneralIntInterface* pInterface = pNode->GetGeneralIntInterface(strCap);
+ _XN_VALIDATE_CAPABILITY_INTERFACE_RET(pInterface,);
+ pInterface->UnregisterFromValueChange(strCap, hCallback);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleSetIntProperty(XnModuleNodeHandle hInstance, const XnChar* strName, XnUInt64 nValue)
+{
+ ModuleProductionNode* pNode = (ModuleProductionNode*)hInstance;
+ return pNode->SetIntProperty(strName, nValue);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleSetRealProperty(XnModuleNodeHandle hInstance, const XnChar* strName, XnDouble dValue)
+{
+ ModuleProductionNode* pNode = (ModuleProductionNode*)hInstance;
+ return pNode->SetRealProperty(strName, dValue);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleSetStringProperty(XnModuleNodeHandle hInstance, const XnChar* strName, const XnChar* strValue)
+{
+ ModuleProductionNode* pNode = (ModuleProductionNode*)hInstance;
+ return pNode->SetStringProperty(strName, strValue);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleSetGeneralProperty(XnModuleNodeHandle hInstance, const XnChar* strName, XnUInt32 nBufferSize, const void* pBuffer)
+{
+ ModuleProductionNode* pNode = (ModuleProductionNode*)hInstance;
+ return pNode->SetGeneralProperty(strName, nBufferSize, pBuffer);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleGetIntProperty(XnModuleNodeHandle hInstance, const XnChar* strName, XnUInt64* pnValue)
+{
+ ModuleProductionNode* pNode = (ModuleProductionNode*)hInstance;
+ return pNode->GetIntProperty(strName, *pnValue);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleGetRealProperty(XnModuleNodeHandle hInstance, const XnChar* strName, XnDouble* pdValue)
+{
+ ModuleProductionNode* pNode = (ModuleProductionNode*)hInstance;
+ return pNode->GetRealProperty(strName, *pdValue);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleGetStringProperty(XnModuleNodeHandle hInstance, const XnChar* strName, XnChar* csValue, XnUInt32 nBufSize)
+{
+ ModuleProductionNode* pNode = (ModuleProductionNode*)hInstance;
+ return pNode->GetStringProperty(strName, csValue, nBufSize);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleGetGeneralProperty(XnModuleNodeHandle hInstance, const XnChar* strName, XnUInt32 nBufferSize, void* pBuffer)
+{
+ ModuleProductionNode* pNode = (ModuleProductionNode*)hInstance;
+ return pNode->GetGeneralProperty(strName, nBufferSize, pBuffer);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleSetOutputStream(XnModuleNodeHandle hInstance, void *pCookie, XnRecorderOutputStreamInterface *pStream)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hInstance;
+ ModuleRecorder* pNode = dynamic_cast<ModuleRecorder*>(pProdNode);
+ return pNode->SetOutputStream(pCookie, pStream);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleSetInputStream(XnModuleNodeHandle hInstance, void *pStreamCookie, XnPlayerInputStreamInterface *pStream)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hInstance;
+ ModulePlayer* pNode = dynamic_cast<ModulePlayer*>(pProdNode);
+ return pNode->SetInputStream(pStreamCookie, pStream);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleReadNext(XnModuleNodeHandle hInstance)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hInstance;
+ ModulePlayer* pNode = dynamic_cast<ModulePlayer*>(pProdNode);
+ return pNode->ReadNext();
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleSetRepeat(XnModuleNodeHandle hInstance, XnBool bRepeat)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hInstance;
+ ModulePlayer* pNode = dynamic_cast<ModulePlayer*>(pProdNode);
+ return pNode->SetRepeat(bRepeat);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleSeekToTimeStamp(XnModuleNodeHandle hInstance, XnInt64 nTimeOffset, XnPlayerSeekOrigin origin)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hInstance;
+ ModulePlayer* pNode = dynamic_cast<ModulePlayer*>(pProdNode);
+ return pNode->SeekToTimeStamp(nTimeOffset, origin);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleSeekToFrame(XnModuleNodeHandle hInstance, const XnChar* strNodeName, XnInt32 nFrameOffset, XnPlayerSeekOrigin origin)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hInstance;
+ ModulePlayer* pNode = dynamic_cast<ModulePlayer*>(pProdNode);
+ return pNode->SeekToFrame(strNodeName, nFrameOffset, origin);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleTellTimestamp(XnModuleNodeHandle hInstance, XnUInt64* pnTimestamp)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hInstance;
+ ModulePlayer* pNode = dynamic_cast<ModulePlayer*>(pProdNode);
+ return pNode->TellTimestamp(*pnTimestamp);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleTellFrame(XnModuleNodeHandle hInstance, const XnChar* strNodeName, XnUInt32* pnFrame)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hInstance;
+ ModulePlayer* pNode = dynamic_cast<ModulePlayer*>(pProdNode);
+ return pNode->TellFrame(strNodeName, *pnFrame);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleGetNumFrames(XnModuleNodeHandle hInstance, const XnChar* strNodeName, XnUInt32* pnFrames)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hInstance;
+ ModulePlayer* pNode = dynamic_cast<ModulePlayer*>(pProdNode);
+ return pNode->GetNumFrames(strNodeName, *pnFrames);
+}
+
+const XnChar* XN_CALLBACK_TYPE __ModuleGetSupportedFormat(XnModuleNodeHandle hInstance)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hInstance;
+ ModulePlayer* pNode = dynamic_cast<ModulePlayer*>(pProdNode);
+ return pNode->GetSupportedFormat();
+}
+
+XnBool XN_CALLBACK_TYPE __ModuleIsEOF(XnModuleNodeHandle hGenerator)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModulePlayer* pNode = dynamic_cast<ModulePlayer*>(pProdNode);
+ return pNode->IsEOF();
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleRegisterToEndOfFileReached(XnModuleNodeHandle hGenerator, XnModuleStateChangedHandler handler, void* pCookie, XnCallbackHandle* phCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModulePlayer* pNode = dynamic_cast<ModulePlayer*>(pProdNode);
+ return pNode->RegisterToEndOfFileReached(handler, pCookie, *phCallback);
+}
+
+void XN_CALLBACK_TYPE __ModuleUnregisterFromEndOfFileReached(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModulePlayer* pNode = dynamic_cast<ModulePlayer*>(pProdNode);
+ pNode->UnregisterFromEndOfFileReached(hCallback);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleSetNodeNotifications(XnModuleNodeHandle hInstance, void *pNodeNotificationsCookie, XnNodeNotifications *pNodeNotifications)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hInstance;
+ ModulePlayer* pNode = dynamic_cast<ModulePlayer*>(pProdNode);
+ return pNode->SetNodeNotifications(pNodeNotificationsCookie, pNodeNotifications);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleOnNodeAdded(XnModuleNodeHandle hGenerator, const XnChar *strNodeName, XnProductionNodeType type, XnCodecID compression)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleRecorder* pNode = dynamic_cast<ModuleRecorder*>(pProdNode);
+ return pNode->OnNodeAdded(strNodeName, type, compression);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleOnNodeRemoved(XnModuleNodeHandle hGenerator, const XnChar *strNodeName)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleRecorder* pNode = dynamic_cast<ModuleRecorder*>(pProdNode);
+ return pNode->OnNodeRemoved(strNodeName);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleOnNodeIntPropChanged(XnModuleNodeHandle hGenerator, const XnChar *strNodeName, const XnChar* strPropName, XnUInt64 nValue)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleRecorder* pNode = dynamic_cast<ModuleRecorder*>(pProdNode);
+ return pNode->OnNodeIntPropChanged(strNodeName, strPropName, nValue);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleOnNodeRealPropChanged(XnModuleNodeHandle hGenerator, const XnChar *strNodeName, const XnChar* strPropName, XnDouble dValue)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleRecorder* pNode = dynamic_cast<ModuleRecorder*>(pProdNode);
+ return pNode->OnNodeRealPropChanged(strNodeName, strPropName, dValue);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleOnNodeStringPropChanged(XnModuleNodeHandle hGenerator, const XnChar *strNodeName, const XnChar* strPropName, const XnChar* strValue)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleRecorder* pNode = dynamic_cast<ModuleRecorder*>(pProdNode);
+ return pNode->OnNodeStringPropChanged(strNodeName, strPropName, strValue);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleOnNodeGeneralPropChanged(XnModuleNodeHandle hGenerator, const XnChar *strNodeName, const XnChar* strPropName, XnUInt32 nBufferSize, const void* pBuffer)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleRecorder* pNode = dynamic_cast<ModuleRecorder*>(pProdNode);
+ return pNode->OnNodeGeneralPropChanged(strNodeName, strPropName, nBufferSize, pBuffer);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleOnNodeNewData(XnModuleNodeHandle hGenerator, const XnChar *strNodeName, XnUInt64 nTimeStamp, XnUInt32 nFrame, const void *pData, XnUInt32 nSize)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleRecorder* pNode = dynamic_cast<ModuleRecorder*>(pProdNode);
+ return pNode->OnNodeNewData(strNodeName, nTimeStamp, nFrame, pData, nSize);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleOnNodeStateReady(XnModuleNodeHandle hGenerator, const XnChar *strNodeName)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleRecorder* pNode = dynamic_cast<ModuleRecorder*>(pProdNode);
+ return pNode->OnNodeStateReady(strNodeName);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleGetDeviceName(XnModuleNodeHandle hInstance, XnChar* strBuffer, XnUInt32* pnBufferSize)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hInstance;
+ ModuleDevice* pNode = dynamic_cast<ModuleDevice*>(pProdNode);
+ ModuleDeviceIdentificationInterface* pInterface = pNode->GetIdentificationInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->GetDeviceName(strBuffer, *pnBufferSize);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleGetVendorSpecificData(XnModuleNodeHandle hInstance, XnChar* strBuffer, XnUInt32* pnBufferSize)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hInstance;
+ ModuleDevice* pNode = dynamic_cast<ModuleDevice*>(pProdNode);
+ ModuleDeviceIdentificationInterface* pInterface = pNode->GetIdentificationInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->GetVendorSpecificData(strBuffer, *pnBufferSize);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleGetSerialNumber(XnModuleNodeHandle hInstance, XnChar* strBuffer, XnUInt32* pnBufferSize)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hInstance;
+ ModuleDevice* pNode = dynamic_cast<ModuleDevice*>(pProdNode);
+ ModuleDeviceIdentificationInterface* pInterface = pNode->GetIdentificationInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->GetSerialNumber(strBuffer, *pnBufferSize);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleSetMirror(XnModuleNodeHandle hGenerator, XnBool bMirror)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGenerator* pNode = dynamic_cast<ModuleGenerator*>(pProdNode);
+ ModuleMirrorInterface* pInterface = pNode->GetMirrorInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->SetMirror(bMirror);
+}
+
+XnBool XN_CALLBACK_TYPE __ModuleIsMirrored(XnModuleNodeHandle hGenerator)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGenerator* pNode = dynamic_cast<ModuleGenerator*>(pProdNode);
+ ModuleMirrorInterface* pInterface = pNode->GetMirrorInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE_RET(pInterface, FALSE);
+ return pInterface->IsMirrored();
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleRegisterToMirrorChange(XnModuleNodeHandle hGenerator, XnModuleStateChangedHandler handler, void* pCookie, XnCallbackHandle* phCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGenerator* pNode = dynamic_cast<ModuleGenerator*>(pProdNode);
+ ModuleMirrorInterface* pInterface = pNode->GetMirrorInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->RegisterToMirrorChange(handler, pCookie, *phCallback);
+}
+
+void XN_CALLBACK_TYPE __ModuleUnregisterFromMirrorChange(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGenerator* pNode = dynamic_cast<ModuleGenerator*>(pProdNode);
+ ModuleMirrorInterface* pInterface = pNode->GetMirrorInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE_RET(pInterface,);
+ pInterface->UnregisterFromMirrorChange(hCallback);
+}
+
+XnBool XN_CALLBACK_TYPE __ModuleIsViewPointSupported(XnModuleNodeHandle hGenerator, XnNodeHandle hNode)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGenerator* pNode = dynamic_cast<ModuleGenerator*>(pProdNode);
+ ProductionNode node(hNode);
+ ModuleAlternativeViewPointInterface* pInterface = pNode->GetAlternativeViewPointInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE_RET(pInterface, FALSE);
+ return pInterface->IsViewPointSupported(node);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleSetViewPoint(XnModuleNodeHandle hGenerator, XnNodeHandle hNode)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGenerator* pNode = dynamic_cast<ModuleGenerator*>(pProdNode);
+ ProductionNode node(hNode);
+ ModuleAlternativeViewPointInterface* pInterface = pNode->GetAlternativeViewPointInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->SetViewPoint(node);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleResetViewPoint(XnModuleNodeHandle hGenerator)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGenerator* pNode = dynamic_cast<ModuleGenerator*>(pProdNode);
+ ModuleAlternativeViewPointInterface* pInterface = pNode->GetAlternativeViewPointInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->ResetViewPoint();
+}
+
+XnBool XN_CALLBACK_TYPE __ModuleIsViewPointAs(XnModuleNodeHandle hGenerator, XnNodeHandle hNode)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGenerator* pNode = dynamic_cast<ModuleGenerator*>(pProdNode);
+ ModuleAlternativeViewPointInterface* pInterface = pNode->GetAlternativeViewPointInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE_RET(pInterface, FALSE);
+ ProductionNode node(hNode);
+ return pInterface->IsViewPointAs(node);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleRegisterToViewPointChange(XnModuleNodeHandle hGenerator, XnModuleStateChangedHandler handler, void* pCookie, XnCallbackHandle* phCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGenerator* pNode = dynamic_cast<ModuleGenerator*>(pProdNode);
+ ModuleAlternativeViewPointInterface* pInterface = pNode->GetAlternativeViewPointInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->RegisterToViewPointChange(handler, pCookie, *phCallback);
+}
+
+void XN_CALLBACK_TYPE __ModuleUnregisterFromViewPointChange(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGenerator* pNode = dynamic_cast<ModuleGenerator*>(pProdNode);
+ ModuleAlternativeViewPointInterface* pInterface = pNode->GetAlternativeViewPointInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE_RET(pInterface,);
+ pInterface->UnregisterFromViewPointChange(hCallback);
+}
+
+XnBool XN_CALLBACK_TYPE __ModuleCanFrameSyncWith(XnModuleNodeHandle hGenerator, XnNodeHandle hNode)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGenerator* pNode = dynamic_cast<ModuleGenerator*>(pProdNode);
+ ModuleFrameSyncInterface* pInterface = pNode->GetFrameSyncInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE_RET(pInterface, FALSE);
+ ProductionNode node(hNode);
+ return pInterface->CanFrameSyncWith(node);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleFrameSyncWith(XnModuleNodeHandle hGenerator, XnNodeHandle hNode)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGenerator* pNode = dynamic_cast<ModuleGenerator*>(pProdNode);
+ ModuleFrameSyncInterface* pInterface = pNode->GetFrameSyncInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ ProductionNode node(hNode);
+ return pInterface->FrameSyncWith(node);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleStopFrameSyncWith(XnModuleNodeHandle hGenerator, XnNodeHandle hNode)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGenerator* pNode = dynamic_cast<ModuleGenerator*>(pProdNode);
+ ModuleFrameSyncInterface* pInterface = pNode->GetFrameSyncInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ ProductionNode node(hNode);
+ return pInterface->StopFrameSyncWith(node);
+}
+
+XnBool XN_CALLBACK_TYPE __ModuleIsFrameSyncedWith(XnModuleNodeHandle hGenerator, XnNodeHandle hNode)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGenerator* pNode = dynamic_cast<ModuleGenerator*>(pProdNode);
+ ModuleFrameSyncInterface* pInterface = pNode->GetFrameSyncInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE_RET(pInterface, FALSE);
+ ProductionNode node(hNode);
+ return pInterface->IsFrameSyncedWith(node);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleRegisterToFrameSyncChange(XnModuleNodeHandle hGenerator, XnModuleStateChangedHandler handler, void* pCookie, XnCallbackHandle* phCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGenerator* pNode = dynamic_cast<ModuleGenerator*>(pProdNode);
+ ModuleFrameSyncInterface* pInterface = pNode->GetFrameSyncInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->RegisterToFrameSyncChange(handler, pCookie, *phCallback);
+}
+
+void XN_CALLBACK_TYPE __ModuleUnregisterFromFrameSyncChange(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGenerator* pNode = dynamic_cast<ModuleGenerator*>(pProdNode);
+ ModuleFrameSyncInterface* pInterface = pNode->GetFrameSyncInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE_RET(pInterface,);
+ pInterface->UnregisterFromFrameSyncChange(hCallback);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleStartGenerating(XnModuleNodeHandle hGenerator)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGenerator* pNode = dynamic_cast<ModuleGenerator*>(pProdNode);
+ return pNode->StartGenerating();
+}
+
+XnBool XN_CALLBACK_TYPE __ModuleIsGenerating(XnModuleNodeHandle hGenerator)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGenerator* pNode = dynamic_cast<ModuleGenerator*>(pProdNode);
+ return pNode->IsGenerating();
+}
+
+void XN_CALLBACK_TYPE __ModuleStopGenerating(XnModuleNodeHandle hGenerator)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGenerator* pNode = dynamic_cast<ModuleGenerator*>(pProdNode);
+ pNode->StopGenerating();
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleRegisterToGenerationRunningChange(XnModuleNodeHandle hGenerator, XnModuleStateChangedHandler handler, void* pCookie, XnCallbackHandle* phCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGenerator* pNode = dynamic_cast<ModuleGenerator*>(pProdNode);
+ return pNode->RegisterToGenerationRunningChange(handler, pCookie, *phCallback);
+}
+
+void XN_CALLBACK_TYPE __ModuleUnregisterFromGenerationRunningChange(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGenerator* pNode = dynamic_cast<ModuleGenerator*>(pProdNode);
+ pNode->UnregisterFromGenerationRunningChange(hCallback);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleRegisterToNewDataAvailable(XnModuleNodeHandle hGenerator, XnModuleStateChangedHandler handler, void* pCookie, XnCallbackHandle* phCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGenerator* pNode = dynamic_cast<ModuleGenerator*>(pProdNode);
+ return pNode->RegisterToNewDataAvailable(handler, pCookie, *phCallback);
+}
+
+void XN_CALLBACK_TYPE __ModuleUnregisterFromNewDataAvailable(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGenerator* pNode = dynamic_cast<ModuleGenerator*>(pProdNode);
+ pNode->UnregisterFromNewDataAvailable(hCallback);
+}
+
+XnBool XN_CALLBACK_TYPE __ModuleIsNewDataAvailable(XnModuleNodeHandle hGenerator, XnUInt64* pnTimestamp)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGenerator* pNode = dynamic_cast<ModuleGenerator*>(pProdNode);
+ return pNode->IsNewDataAvailable(*pnTimestamp);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleUpdateData(XnModuleNodeHandle hGenerator)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGenerator* pNode = dynamic_cast<ModuleGenerator*>(pProdNode);
+ return pNode->UpdateData();
+}
+
+const void* XN_CALLBACK_TYPE __ModuleGetData(XnModuleNodeHandle hGenerator)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGenerator* pNode = dynamic_cast<ModuleGenerator*>(pProdNode);
+ return pNode->GetData();
+}
+
+XnUInt32 XN_CALLBACK_TYPE __ModuleGetDataSize(XnModuleNodeHandle hGenerator)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGenerator* pNode = dynamic_cast<ModuleGenerator*>(pProdNode);
+ return pNode->GetDataSize();
+}
+
+XnUInt64 XN_CALLBACK_TYPE __ModuleGetTimestamp(XnModuleNodeHandle hGenerator)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGenerator* pNode = dynamic_cast<ModuleGenerator*>(pProdNode);
+ return pNode->GetTimestamp();
+}
+
+XnUInt32 XN_CALLBACK_TYPE __ModuleGetFrameID(XnModuleNodeHandle hGenerator)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGenerator* pNode = dynamic_cast<ModuleGenerator*>(pProdNode);
+ return pNode->GetFrameID();
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleSetCropping(XnModuleNodeHandle hGenerator, const XnCropping* pCropping)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleMapGenerator* pNode = dynamic_cast<ModuleMapGenerator*>(pProdNode);
+ ModuleCroppingInterface* pInterface = pNode->GetCroppingInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->SetCropping(*pCropping);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleGetCropping(XnModuleNodeHandle hGenerator, XnCropping* pCropping)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleMapGenerator* pNode = dynamic_cast<ModuleMapGenerator*>(pProdNode);
+ ModuleCroppingInterface* pInterface = pNode->GetCroppingInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->GetCropping(*pCropping);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleRegisterToCroppingChange(XnModuleNodeHandle hGenerator, XnModuleStateChangedHandler handler, void* pCookie, XnCallbackHandle* phCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleMapGenerator* pNode = dynamic_cast<ModuleMapGenerator*>(pProdNode);
+ ModuleCroppingInterface* pInterface = pNode->GetCroppingInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->RegisterToCroppingChange(handler, pCookie, *phCallback);
+}
+
+void XN_CALLBACK_TYPE __ModuleUnregisterFromCroppingChange(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleMapGenerator* pNode = dynamic_cast<ModuleMapGenerator*>(pProdNode);
+ ModuleCroppingInterface* pInterface = pNode->GetCroppingInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE_RET(pInterface,);
+ pInterface->UnregisterFromCroppingChange(hCallback);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleSetPowerLineFrequency(XnModuleNodeHandle hGenerator, XnPowerLineFrequency nFrequency)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleMapGenerator* pNode = dynamic_cast<ModuleMapGenerator*>(pProdNode);
+ ModuleAntiFlickerInterface* pInterface = pNode->GetAntiFlickerInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->SetPowerLineFrequency(nFrequency);
+}
+
+XnPowerLineFrequency XN_CALLBACK_TYPE __ModuleGetPowerLineFrequency(XnModuleNodeHandle hGenerator)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleMapGenerator* pNode = dynamic_cast<ModuleMapGenerator*>(pProdNode);
+ ModuleAntiFlickerInterface* pInterface = pNode->GetAntiFlickerInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE_RET(pInterface, XN_POWER_LINE_FREQUENCY_OFF);
+ return pInterface->GetPowerLineFrequency();
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleRegisterToPowerLineFrequencyChange(XnModuleNodeHandle hGenerator, XnModuleStateChangedHandler handler, void* pCookie, XnCallbackHandle* phCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleMapGenerator* pNode = dynamic_cast<ModuleMapGenerator*>(pProdNode);
+ ModuleAntiFlickerInterface* pInterface = pNode->GetAntiFlickerInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->RegisterToPowerLineFrequencyChange(handler, pCookie, *phCallback);
+}
+
+void XN_CALLBACK_TYPE __ModuleUnregisterFromPowerLineFrequencyChange(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleMapGenerator* pNode = dynamic_cast<ModuleMapGenerator*>(pProdNode);
+ ModuleAntiFlickerInterface* pInterface = pNode->GetAntiFlickerInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE_RET(pInterface,);
+ pInterface->UnregisterFromPowerLineFrequencyChange(hCallback);
+}
+
+XnUInt32 XN_CALLBACK_TYPE __ModuleGetSupportedMapOutputModesCount(XnModuleNodeHandle hGenerator)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleMapGenerator* pNode = dynamic_cast<ModuleMapGenerator*>(pProdNode);
+ return pNode->GetSupportedMapOutputModesCount();
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleGetSupportedMapOutputModes(XnModuleNodeHandle hGenerator, XnMapOutputMode* aModes, XnUInt32* pnCount)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleMapGenerator* pNode = dynamic_cast<ModuleMapGenerator*>(pProdNode);
+ return pNode->GetSupportedMapOutputModes(aModes, *pnCount);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleSetMapOutputMode(XnModuleNodeHandle hGenerator, const XnMapOutputMode* pOutputMode)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleMapGenerator* pNode = dynamic_cast<ModuleMapGenerator*>(pProdNode);
+ return pNode->SetMapOutputMode(*pOutputMode);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleGetMapOutputMode(XnModuleNodeHandle hGenerator, XnMapOutputMode* pOutputMode)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleMapGenerator* pNode = dynamic_cast<ModuleMapGenerator*>(pProdNode);
+ return pNode->GetMapOutputMode(*pOutputMode);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleRegisterToMapOutputModeChange(XnModuleNodeHandle hGenerator, XnModuleStateChangedHandler handler, void* pCookie, XnCallbackHandle* phCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleMapGenerator* pNode = dynamic_cast<ModuleMapGenerator*>(pProdNode);
+ return pNode->RegisterToMapOutputModeChange(handler, pCookie, *phCallback);
+}
+
+void XN_CALLBACK_TYPE __ModuleUnregisterFromMapOutputModeChange(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleMapGenerator* pNode = dynamic_cast<ModuleMapGenerator*>(pProdNode);
+ pNode->UnregisterFromMapOutputModeChange(hCallback);
+}
+
+XnUInt32 XN_CALLBACK_TYPE __ModuleGetBytesPerPixel(XnModuleNodeHandle hGenerator)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleMapGenerator* pNode = dynamic_cast<ModuleMapGenerator*>(pProdNode);
+ return pNode->GetBytesPerPixel();
+}
+
+XnUInt32 XN_CALLBACK_TYPE __ModuleGetSupportedUserPositionsCount(XnModuleNodeHandle hGenerator)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleDepthGenerator* pNode = dynamic_cast<ModuleDepthGenerator*>(pProdNode);
+ ModuleUserPositionInterface* pInterface = pNode->GetUserPositionInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE_RET(pInterface, 0);
+ return pInterface->GetSupportedUserPositionsCount();
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleSetUserPosition(XnModuleNodeHandle hGenerator, XnUInt32 nIndex, const XnBoundingBox3D* pPosition)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleDepthGenerator* pNode = dynamic_cast<ModuleDepthGenerator*>(pProdNode);
+ ModuleUserPositionInterface* pInterface = pNode->GetUserPositionInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->SetUserPosition(nIndex, *pPosition);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleGetUserPosition(XnModuleNodeHandle hGenerator, XnUInt32 nIndex, XnBoundingBox3D* pPosition)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleDepthGenerator* pNode = dynamic_cast<ModuleDepthGenerator*>(pProdNode);
+ ModuleUserPositionInterface* pInterface = pNode->GetUserPositionInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->GetUserPosition(nIndex, *pPosition);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleRegisterToUserPositionChange(XnModuleNodeHandle hGenerator, XnModuleStateChangedHandler handler, void* pCookie, XnCallbackHandle* phCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleDepthGenerator* pNode = dynamic_cast<ModuleDepthGenerator*>(pProdNode);
+ ModuleUserPositionInterface* pInterface = pNode->GetUserPositionInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->RegisterToUserPositionChange(handler, pCookie, *phCallback);
+}
+
+void XN_CALLBACK_TYPE __ModuleUnregisterFromUserPositionChange(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleDepthGenerator* pNode = dynamic_cast<ModuleDepthGenerator*>(pProdNode);
+ ModuleUserPositionInterface* pInterface = pNode->GetUserPositionInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE_RET(pInterface,);
+ pInterface->UnregisterFromUserPositionChange(hCallback);
+}
+
+XnDepthPixel XN_CALLBACK_TYPE __ModuleGetDeviceMaxDepth(XnModuleNodeHandle hGenerator)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleDepthGenerator* pNode = dynamic_cast<ModuleDepthGenerator*>(pProdNode);
+ return pNode->GetDeviceMaxDepth();
+}
+
+void XN_CALLBACK_TYPE __ModuleGetFieldOfView(XnModuleNodeHandle hGenerator, XnFieldOfView* pFOV)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleDepthGenerator* pNode = dynamic_cast<ModuleDepthGenerator*>(pProdNode);
+ pNode->GetFieldOfView(*pFOV);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleRegisterToFieldOfViewChange(XnModuleNodeHandle hGenerator, XnModuleStateChangedHandler handler, void* pCookie, XnCallbackHandle* phCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleDepthGenerator* pNode = dynamic_cast<ModuleDepthGenerator*>(pProdNode);
+ return pNode->RegisterToFieldOfViewChange(handler, pCookie, *phCallback);
+}
+
+void XN_CALLBACK_TYPE __ModuleUnregisterFromFieldOfViewChange(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleDepthGenerator* pNode = dynamic_cast<ModuleDepthGenerator*>(pProdNode);
+ pNode->UnregisterFromFieldOfViewChange(hCallback);
+}
+
+XnDepthPixel* XN_CALLBACK_TYPE __ModuleGetDepthMap(XnModuleNodeHandle hGenerator)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleDepthGenerator* pNode = dynamic_cast<ModuleDepthGenerator*>(pProdNode);
+ return pNode->GetDepthMap();
+}
+
+XnUInt8* XN_CALLBACK_TYPE __ModuleGetImageMap(XnModuleNodeHandle hGenerator)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleImageGenerator* pNode = dynamic_cast<ModuleImageGenerator*>(pProdNode);
+ return pNode->GetImageMap();
+}
+
+XnBool XN_CALLBACK_TYPE __ModuleIsPixelFormatSupported(XnModuleNodeHandle hGenerator, XnPixelFormat Format)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleImageGenerator* pNode = dynamic_cast<ModuleImageGenerator*>(pProdNode);
+ return pNode->IsPixelFormatSupported(Format);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleSetPixelFormat(XnModuleNodeHandle hGenerator, XnPixelFormat Format)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleImageGenerator* pNode = dynamic_cast<ModuleImageGenerator*>(pProdNode);
+ return pNode->SetPixelFormat(Format);
+}
+
+XnPixelFormat XN_CALLBACK_TYPE __ModuleGetPixelFormat(XnModuleNodeHandle hGenerator)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleImageGenerator* pNode = dynamic_cast<ModuleImageGenerator*>(pProdNode);
+ return pNode->GetPixelFormat();
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleRegisterToPixelFormatChange(XnModuleNodeHandle hGenerator, XnModuleStateChangedHandler handler, void* pCookie, XnCallbackHandle* phCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleImageGenerator* pNode = dynamic_cast<ModuleImageGenerator*>(pProdNode);
+ return pNode->RegisterToPixelFormatChange(handler, pCookie, *phCallback);
+}
+
+void XN_CALLBACK_TYPE __ModuleUnregisterFromPixelFormatChange(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleImageGenerator* pNode = dynamic_cast<ModuleImageGenerator*>(pProdNode);
+ pNode->UnregisterFromPixelFormatChange(hCallback);
+}
+
+XnIRPixel* XN_CALLBACK_TYPE __ModuleGetIRMap(XnModuleNodeHandle hGenerator)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleIRGenerator* pNode = dynamic_cast<ModuleIRGenerator*>(pProdNode);
+ return pNode->GetIRMap();
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleAddGesture(XnModuleNodeHandle hGenerator, const XnChar* strGesture, XnBoundingBox3D* pArea)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGestureGenerator* pNode = dynamic_cast<ModuleGestureGenerator*>(pProdNode);
+ return pNode->AddGesture(strGesture, pArea);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleRemoveGesture(XnModuleNodeHandle hGenerator, const XnChar* strGesture)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGestureGenerator* pNode = dynamic_cast<ModuleGestureGenerator*>(pProdNode);
+ return pNode->RemoveGesture(strGesture);
+}
+XnStatus XN_CALLBACK_TYPE __ModuleGetActiveGestures(XnModuleNodeHandle hGenerator, XnChar** pstrGestures, XnUInt16* pnGestures)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGestureGenerator* pNode = dynamic_cast<ModuleGestureGenerator*>(pProdNode);
+ return pNode->GetActiveGestures(pstrGestures, *pnGestures);
+}
+XnStatus XN_CALLBACK_TYPE __ModuleGetAllActiveGestures(XnModuleNodeHandle hGenerator, XnChar** pstrGestures, XnUInt32 nNameLength, XnUInt16* pnGestures)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGestureGenerator* pNode = dynamic_cast<ModuleGestureGenerator*>(pProdNode);
+ return pNode->GetAllActiveGestures(pstrGestures, nNameLength, *pnGestures);
+}
+XnStatus XN_CALLBACK_TYPE __ModuleEnumerateGestures(XnModuleNodeHandle hGenerator, XnChar** pstrGestures, XnUInt16* pnGestures)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGestureGenerator* pNode = dynamic_cast<ModuleGestureGenerator*>(pProdNode);
+ return pNode->EnumerateGestures(pstrGestures, *pnGestures);
+}
+XnStatus XN_CALLBACK_TYPE __ModuleEnumerateAllGestures(XnModuleNodeHandle hGenerator, XnChar** pstrGestures, XnUInt32 nNameLength, XnUInt16* pnGestures)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGestureGenerator* pNode = dynamic_cast<ModuleGestureGenerator*>(pProdNode);
+ return pNode->EnumerateAllGestures(pstrGestures, nNameLength, *pnGestures);
+}
+XnBool XN_CALLBACK_TYPE __ModuleIsGestureAvailable(XnModuleNodeHandle hGenerator, const XnChar* strGesture)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGestureGenerator* pNode = dynamic_cast<ModuleGestureGenerator*>(pProdNode);
+ return pNode->IsGestureAvailable(strGesture);
+}
+XnBool XN_CALLBACK_TYPE __ModuleIsGestureProgressSupported(XnModuleNodeHandle hGenerator, const XnChar* strGesture)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGestureGenerator* pNode = dynamic_cast<ModuleGestureGenerator*>(pProdNode);
+ return pNode->IsGestureProgressSupported(strGesture);
+}
+XnStatus XN_CALLBACK_TYPE __ModuleRegisterGestureCallbacks(XnModuleNodeHandle hGenerator, XnModuleGestureRecognized RecognizedCB, XnModuleGestureProgress ProgressCB, void* pCookie, XnCallbackHandle* phCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGestureGenerator* pNode = dynamic_cast<ModuleGestureGenerator*>(pProdNode);
+ return pNode->RegisterGestureCallbacks(RecognizedCB, ProgressCB, pCookie, *phCallback);
+}
+void XN_CALLBACK_TYPE __ModuleUnregisterGestureCallbacks(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGestureGenerator* pNode = dynamic_cast<ModuleGestureGenerator*>(pProdNode);
+ pNode->UnregisterGestureCallbacks(hCallback);
+}
+XnStatus XN_CALLBACK_TYPE __ModuleRegisterToGestureChange(XnModuleNodeHandle hGenerator, XnModuleStateChangedHandler handler, void* pCookie, XnCallbackHandle* phCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGestureGenerator* pNode = dynamic_cast<ModuleGestureGenerator*>(pProdNode);
+ return pNode->RegisterToGestureChange(handler, pCookie, *phCallback);
+}
+void XN_CALLBACK_TYPE __ModuleUnregisterFromGestureChange(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGestureGenerator* pNode = dynamic_cast<ModuleGestureGenerator*>(pProdNode);
+ pNode->UnregisterFromGestureChange(hCallback);
+}
+XnStatus XN_CALLBACK_TYPE __ModuleRegisterToGestureIntermediateStageCompleted(XnModuleNodeHandle hGenerator, XnModuleGestureIntermediateStageCompleted handler, void* pCookie, XnCallbackHandle* phCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGestureGenerator* pNode = dynamic_cast<ModuleGestureGenerator*>(pProdNode);
+ return pNode->RegisterToGestureIntermediateStageCompleted(handler, pCookie, *phCallback);
+}
+void XN_CALLBACK_TYPE __ModuleUnregisterFromGestureIntermediateStageCompleted(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGestureGenerator* pNode = dynamic_cast<ModuleGestureGenerator*>(pProdNode);
+ pNode->UnregisterFromGestureIntermediateStageCompleted(hCallback);
+}
+XnStatus XN_CALLBACK_TYPE __ModuleRegisterToGestureReadyForNextIntermediateStage(XnModuleNodeHandle hGenerator, XnModuleGestureReadyForNextIntermediateStage handler, void* pCookie, XnCallbackHandle* phCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGestureGenerator* pNode = dynamic_cast<ModuleGestureGenerator*>(pProdNode);
+ return pNode->RegisterToGestureReadyForNextIntermediateStage(handler, pCookie, *phCallback);
+}
+void XN_CALLBACK_TYPE __ModuleUnregisterFromGestureReadyForNextIntermediateStage(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleGestureGenerator* pNode = dynamic_cast<ModuleGestureGenerator*>(pProdNode);
+ pNode->UnregisterFromGestureReadyForNextIntermediateStage(hCallback);
+}
+
+const XnLabel* XN_CALLBACK_TYPE __ModuleGetLabelMap(XnModuleNodeHandle hGenerator)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleSceneAnalyzer* pNode = dynamic_cast<ModuleSceneAnalyzer*>(pProdNode);
+ return pNode->GetLabelMap();
+}
+XnStatus XN_CALLBACK_TYPE __ModuleGetFloor(XnModuleNodeHandle hGenerator, XnPlane3D* pPlane)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleSceneAnalyzer* pNode = dynamic_cast<ModuleSceneAnalyzer*>(pProdNode);
+ return pNode->GetFloor(*pPlane);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleRegisterHandCallbacks(XnModuleNodeHandle hGenerator, XnModuleHandCreate CreateCB, XnModuleHandUpdate UpdateCB, XnModuleHandDestroy DestroyCB, void* pCookie, XnCallbackHandle* phCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleHandsGenerator* pNode = dynamic_cast<ModuleHandsGenerator*>(pProdNode);
+ return pNode->RegisterHandCallbacks(CreateCB, UpdateCB, DestroyCB, pCookie, *phCallback);
+}
+void XN_CALLBACK_TYPE __ModuleUnregisterHandCallbacks(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleHandsGenerator* pNode = dynamic_cast<ModuleHandsGenerator*>(pProdNode);
+ pNode->UnregisterHandCallbacks(hCallback);
+}
+XnStatus XN_CALLBACK_TYPE __ModuleStopTracking(XnModuleNodeHandle hGenerator, XnUserID user)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleHandsGenerator* pNode = dynamic_cast<ModuleHandsGenerator*>(pProdNode);
+ return pNode->StopTracking(user);
+}
+XnStatus XN_CALLBACK_TYPE __ModuleStopTrackingAll(XnModuleNodeHandle hGenerator)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleHandsGenerator* pNode = dynamic_cast<ModuleHandsGenerator*>(pProdNode);
+ return pNode->StopTrackingAll();
+}
+XnStatus XN_CALLBACK_TYPE __ModuleStartTracking(XnModuleNodeHandle hGenerator, const XnPoint3D* pPosition)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleHandsGenerator* pNode = dynamic_cast<ModuleHandsGenerator*>(pProdNode);
+ return pNode->StartTracking(*pPosition);
+}
+XnStatus XN_CALLBACK_TYPE __ModuleSetTrackingSmoothing(XnModuleNodeHandle hGenerator, XnFloat fSmoothingFactor)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleHandsGenerator* pNode = dynamic_cast<ModuleHandsGenerator*>(pProdNode);
+ return pNode->SetSmoothing(fSmoothingFactor);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleRegisterToHandTouchingFOVEdgeCallback(XnModuleNodeHandle hGenerator, XnModuleHandTouchingFOVEdge handler, void* pCookie, XnCallbackHandle* phCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleHandsGenerator* pNode = dynamic_cast<ModuleHandsGenerator*>(pProdNode);
+ ModuleHandTouchingFOVEdgeInterface* pInterface = pNode->GetHandTouchingFOVEdgeInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->RegisterToHandTouchingFOVEdge(handler, pCookie, *phCallback);
+}
+void XN_CALLBACK_TYPE __ModuleUnregisterFromHandTouchingFOVEdgeCallback(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleHandsGenerator* pNode = dynamic_cast<ModuleHandsGenerator*>(pProdNode);
+ ModuleHandTouchingFOVEdgeInterface* pInterface = pNode->GetHandTouchingFOVEdgeInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE_RET(pInterface, );
+ pInterface->UnregisterFromHandTouchingFOVEdge(hCallback);
+}
+
+XnBool XN_CALLBACK_TYPE __ModuleIsJointAvailable(XnModuleNodeHandle hGenerator, XnSkeletonJoint eJoint)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModuleSkeletonInterface* pInterface = pNode->GetSkeletonInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE_RET(pInterface, FALSE);
+ return pInterface->IsJointAvailable(eJoint);
+}
+XnBool XN_CALLBACK_TYPE __ModuleIsProfileAvailable(XnModuleNodeHandle hGenerator, XnSkeletonProfile eProfile)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModuleSkeletonInterface* pInterface = pNode->GetSkeletonInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE_RET(pInterface, FALSE);
+ return pInterface->IsProfileAvailable(eProfile);
+}
+XnStatus XN_CALLBACK_TYPE __ModuleSetSkeletonProfile(XnModuleNodeHandle hGenerator, XnSkeletonProfile eProfile)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModuleSkeletonInterface* pInterface = pNode->GetSkeletonInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->SetSkeletonProfile(eProfile);
+}
+XnStatus XN_CALLBACK_TYPE __ModuleSetJointActive(XnModuleNodeHandle hGenerator, XnSkeletonJoint eJoint, XnBool bState)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModuleSkeletonInterface* pInterface = pNode->GetSkeletonInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->SetJointActive(eJoint, bState);
+}
+XnBool XN_CALLBACK_TYPE __ModuleIsJointActive(XnModuleNodeHandle hGenerator, XnSkeletonJoint eJoint)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModuleSkeletonInterface* pInterface = pNode->GetSkeletonInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE_RET(pInterface, FALSE);
+ return pInterface->IsJointActive(eJoint);
+}
+XnStatus XN_CALLBACK_TYPE __ModuleRegisterToJointConfigurationChange(XnModuleNodeHandle hGenerator, XnModuleStateChangedHandler handler, void* pCookie, XnCallbackHandle* phCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModuleSkeletonInterface* pInterface = pNode->GetSkeletonInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->RegisterToJointConfigurationChange(handler, pCookie, *phCallback);
+}
+void XN_CALLBACK_TYPE __ModuleUnregisterFromJointConfigurationChange(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModuleSkeletonInterface* pInterface = pNode->GetSkeletonInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE_RET(pInterface,);
+ pInterface->UnregisterFromJointConfigurationChange(hCallback);
+}
+XnStatus XN_CALLBACK_TYPE __ModuleEnumerateActiveJoints(XnModuleNodeHandle hGenerator, XnSkeletonJoint* pJoints, XnUInt16* pnJoints)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModuleSkeletonInterface* pInterface = pNode->GetSkeletonInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->EnumerateActiveJoints(pJoints, *pnJoints);
+}
+XnStatus XN_CALLBACK_TYPE __ModuleGetSkeletonJoint(XnModuleNodeHandle hGenerator, XnUserID user, XnSkeletonJoint eJoint, XnSkeletonJointTransformation* pJoint)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModuleSkeletonInterface* pInterface = pNode->GetSkeletonInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->GetSkeletonJoint(user, eJoint, *pJoint);
+}
+XnStatus XN_CALLBACK_TYPE __ModuleGetSkeletonJointPosition(XnModuleNodeHandle hGenerator, XnUserID user, XnSkeletonJoint eJoint, XnSkeletonJointPosition* pJoint)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModuleSkeletonInterface* pInterface = pNode->GetSkeletonInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->GetSkeletonJointPosition(user, eJoint, *pJoint);
+}
+XnStatus XN_CALLBACK_TYPE __ModuleGetSkeletonJointOrientation(XnModuleNodeHandle hGenerator, XnUserID user, XnSkeletonJoint eJoint, XnSkeletonJointOrientation* pJoint)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModuleSkeletonInterface* pInterface = pNode->GetSkeletonInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->GetSkeletonJointOrientation(user, eJoint, *pJoint);
+}
+XnBool XN_CALLBACK_TYPE __ModuleIsSkeletonTracking(XnModuleNodeHandle hGenerator, XnUserID user)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModuleSkeletonInterface* pInterface = pNode->GetSkeletonInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE_RET(pInterface, FALSE);
+ return pInterface->IsTracking(user);
+}
+XnBool XN_CALLBACK_TYPE __ModuleIsSkeletonCalibrated(XnModuleNodeHandle hGenerator, XnUserID user)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModuleSkeletonInterface* pInterface = pNode->GetSkeletonInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE_RET(pInterface, FALSE);
+ return pInterface->IsCalibrated(user);
+}
+XnBool XN_CALLBACK_TYPE __ModuleIsSkeletonCalibrating(XnModuleNodeHandle hGenerator, XnUserID user)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModuleSkeletonInterface* pInterface = pNode->GetSkeletonInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE_RET(pInterface, FALSE);
+ return pInterface->IsCalibrating(user);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleRequestSkeletonCalibration(XnModuleNodeHandle hGenerator, XnUserID user, XnBool bForce)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModuleSkeletonInterface* pInterface = pNode->GetSkeletonInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->RequestCalibration(user, bForce);
+}
+XnStatus XN_CALLBACK_TYPE __ModuleAbortSkeletonCalibration(XnModuleNodeHandle hGenerator, XnUserID user)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModuleSkeletonInterface* pInterface = pNode->GetSkeletonInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->AbortCalibration(user);
+}
+XnStatus XN_CALLBACK_TYPE __ModuleSaveCalibrationDataToFile(XnModuleNodeHandle hGenerator, XnUserID user, const XnChar* strFileName)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModuleSkeletonInterface* pInterface = pNode->GetSkeletonInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->SaveCalibrationDataToFile(user, strFileName);
+}
+XnStatus XN_CALLBACK_TYPE __ModuleLoadCalibrationDataFromFile(XnModuleNodeHandle hGenerator, XnUserID user, const XnChar* strFileName)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModuleSkeletonInterface* pInterface = pNode->GetSkeletonInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->LoadCalibrationDataFromFile(user, strFileName);
+}
+XnStatus XN_CALLBACK_TYPE __ModuleSaveCalibrationData(XnModuleNodeHandle hGenerator, XnUserID user, XnUInt32 nSlot)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModuleSkeletonInterface* pInterface = pNode->GetSkeletonInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->SaveCalibrationData(user, nSlot);
+}
+XnStatus XN_CALLBACK_TYPE __ModuleLoadCalibrationData(XnModuleNodeHandle hGenerator, XnUserID user, XnUInt32 nSlot)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModuleSkeletonInterface* pInterface = pNode->GetSkeletonInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->LoadCalibrationData(user, nSlot);
+}
+XnStatus XN_CALLBACK_TYPE __ModuleClearCalibrationData(XnModuleNodeHandle hGenerator, XnUInt32 nSlot)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModuleSkeletonInterface* pInterface = pNode->GetSkeletonInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->ClearCalibrationData(nSlot);
+}
+XnBool XN_CALLBACK_TYPE __ModuleIsCalibrationData(XnModuleNodeHandle hGenerator, XnUInt32 nSlot)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModuleSkeletonInterface* pInterface = pNode->GetSkeletonInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE_RET(pInterface, FALSE);
+ return pInterface->IsCalibrationData(nSlot);
+}
+XnStatus XN_CALLBACK_TYPE __ModuleStartSkeletonTracking(XnModuleNodeHandle hGenerator, XnUserID user)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModuleSkeletonInterface* pInterface = pNode->GetSkeletonInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->StartTracking(user);
+}
+XnStatus XN_CALLBACK_TYPE __ModuleStopSkeletonTracking(XnModuleNodeHandle hGenerator, XnUserID user)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModuleSkeletonInterface* pInterface = pNode->GetSkeletonInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->StopTracking(user);
+}
+XnStatus XN_CALLBACK_TYPE __ModuleResetSkeleton(XnModuleNodeHandle hGenerator, XnUserID user)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModuleSkeletonInterface* pInterface = pNode->GetSkeletonInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->Reset(user);
+}
+XnBool XN_CALLBACK_TYPE __ModuleNeedPoseForSkeletonCalibration(XnModuleNodeHandle hGenerator)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModuleSkeletonInterface* pInterface = pNode->GetSkeletonInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE_RET(pInterface, FALSE);
+ return pInterface->NeedPoseForCalibration();
+}
+XnStatus XN_CALLBACK_TYPE __ModuleGetSkeletonCalibrationPose(XnModuleNodeHandle hGenerator, XnChar* strPose)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModuleSkeletonInterface* pInterface = pNode->GetSkeletonInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->GetCalibrationPose(strPose);
+}
+XnStatus XN_CALLBACK_TYPE __ModuleSetSkeletonSmoothing(XnModuleNodeHandle hGenerator, XnFloat fSmoothingFactor)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModuleSkeletonInterface* pInterface = pNode->GetSkeletonInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->SetSmoothing(fSmoothingFactor);
+}
+XnStatus XN_CALLBACK_TYPE __ModuleRegisterCalibrationCallbacks(XnModuleNodeHandle hGenerator, XnModuleCalibrationStart CalibrationStartCB, XnModuleCalibrationEnd CalibrationEndCB, void* pCookie, XnCallbackHandle* phCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModuleSkeletonInterface* pInterface = pNode->GetSkeletonInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->RegisterCalibrationCallbacks(CalibrationStartCB, CalibrationEndCB, pCookie, *phCallback);
+}
+void XN_CALLBACK_TYPE __ModuleUnregisterCalibrationCallbacks(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModuleSkeletonInterface* pInterface = pNode->GetSkeletonInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE_RET(pInterface,);
+ pInterface->UnregisterCalibrationCallbacks(hCallback);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleRegisterToCalibrationStartCallback(XnModuleNodeHandle hGenerator, XnModuleCalibrationStart handler, void* pCookie, XnCallbackHandle* phCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModuleSkeletonInterface* pInterface = pNode->GetSkeletonInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->RegisterToCalibrationStart(handler, pCookie, *phCallback);
+}
+void XN_CALLBACK_TYPE __ModuleUnregisterFromCalibrationStartCallback(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModuleSkeletonInterface* pInterface = pNode->GetSkeletonInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE_RET(pInterface,);
+ pInterface->UnregisterFromCalibrationStart(hCallback);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleRegisterToCalibrationInProgressCallback(XnModuleNodeHandle hGenerator, XnModuleCalibrationInProgress handler, void* pCookie, XnCallbackHandle* phCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModuleSkeletonInterface* pInterface = pNode->GetSkeletonInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->RegisterToCalibrationInProgress(handler, pCookie, *phCallback);
+}
+void XN_CALLBACK_TYPE __ModuleUnregisterFromCalibrationInProgressCallback(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModuleSkeletonInterface* pInterface = pNode->GetSkeletonInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE_RET(pInterface,);
+ pInterface->UnregisterFromCalibrationInProgress(hCallback);
+}
+XnStatus XN_CALLBACK_TYPE __ModuleRegisterToCalibrationCompleteCallback(XnModuleNodeHandle hGenerator, XnModuleCalibrationComplete handler, void* pCookie, XnCallbackHandle* phCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModuleSkeletonInterface* pInterface = pNode->GetSkeletonInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->RegisterToCalibrationComplete(handler, pCookie, *phCallback);
+}
+void XN_CALLBACK_TYPE __ModuleUnregisterFromCalibrationCompleteCallback(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModuleSkeletonInterface* pInterface = pNode->GetSkeletonInterface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE_RET(pInterface,);
+ pInterface->UnregisterFromCalibrationComplete(hCallback);
+}
+///
+XnUInt32 XN_CALLBACK_TYPE __ModuleGetNumberOfPoses(XnModuleNodeHandle hGenerator)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModulePoseDetectionInteface* pInterface = pNode->GetPoseDetectionInteface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE_RET(pInterface, 0);
+ return pInterface->GetNumberOfPoses();
+}
+XnStatus XN_CALLBACK_TYPE __ModuleGetAvailablePoses(XnModuleNodeHandle hGenerator, XnChar** pstrPoses, XnUInt32* pnPoses)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModulePoseDetectionInteface* pInterface = pNode->GetPoseDetectionInteface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->GetAvailablePoses(pstrPoses, *pnPoses);
+}
+XnStatus XN_CALLBACK_TYPE __ModuleGetAllAvailablePoses(XnModuleNodeHandle hGenerator, XnChar** pstrPoses, XnUInt32 nNameLength, XnUInt32* pnPoses)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModulePoseDetectionInteface* pInterface = pNode->GetPoseDetectionInteface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->GetAllAvailablePoses(pstrPoses, nNameLength, *pnPoses);
+}
+
+
+XnStatus XN_CALLBACK_TYPE __ModuleStartPoseDetection(XnModuleNodeHandle hGenerator, const XnChar* strPose, XnUserID user)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModulePoseDetectionInteface* pInterface = pNode->GetPoseDetectionInteface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->StartPoseDetection(strPose, user);
+}
+XnStatus XN_CALLBACK_TYPE __ModuleStopPoseDetection(XnModuleNodeHandle hGenerator, XnUserID user)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModulePoseDetectionInteface* pInterface = pNode->GetPoseDetectionInteface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->StopPoseDetection(user);
+}
+XnStatus XN_CALLBACK_TYPE __ModuleStopSinglePoseDetection(XnModuleNodeHandle hGenerator, XnUserID user, const XnChar* strPose)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModulePoseDetectionInteface* pInterface = pNode->GetPoseDetectionInteface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->StopSinglePoseDetection(user, strPose);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleRegisterToPoseCallbacks(XnModuleNodeHandle hGenerator, XnModulePoseDetectionCallback PoseDetectionStartCB, XnModulePoseDetectionCallback PoseDetectionEndCB, void* pCookie, XnCallbackHandle* phCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModulePoseDetectionInteface* pInterface = pNode->GetPoseDetectionInteface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->RegisterToPoseDetectionCallbacks(PoseDetectionStartCB, PoseDetectionEndCB, pCookie, *phCallback);
+}
+void XN_CALLBACK_TYPE __ModuleUnregisterFromPoseCallbacks(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModulePoseDetectionInteface* pInterface = pNode->GetPoseDetectionInteface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE_RET(pInterface,);
+ pInterface->UnregisterFromPoseDetectionCallbacks(hCallback);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleRegisterToPoseDetected(XnModuleNodeHandle hGenerator, XnModulePoseDetectionCallback handler, void* pCookie, XnCallbackHandle* phCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModulePoseDetectionInteface* pInterface = pNode->GetPoseDetectionInteface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->RegisterToPoseDetected(handler, pCookie, *phCallback);
+}
+void XN_CALLBACK_TYPE __ModuleUnregisterFromPoseDetected(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModulePoseDetectionInteface* pInterface = pNode->GetPoseDetectionInteface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE_RET(pInterface,);
+ pInterface->UnregisterFromPoseDetected(hCallback);
+}
+XnStatus XN_CALLBACK_TYPE __ModuleRegisterToOutOfPose(XnModuleNodeHandle hGenerator, XnModulePoseDetectionCallback handler, void* pCookie, XnCallbackHandle* phCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModulePoseDetectionInteface* pInterface = pNode->GetPoseDetectionInteface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->RegisterToOutOfPose(handler, pCookie, *phCallback);
+}
+void XN_CALLBACK_TYPE __ModuleUnregisterFromOutOfPose(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModulePoseDetectionInteface* pInterface = pNode->GetPoseDetectionInteface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE_RET(pInterface,);
+ pInterface->UnregisterFromOutOfPose(hCallback);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleRegisterToPoseInProgressCallback(XnModuleNodeHandle hGenerator, XnModulePoseDetectionInProgressCallback handler, void* pCookie, XnCallbackHandle* phCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModulePoseDetectionInteface* pInterface = pNode->GetPoseDetectionInteface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE(pInterface);
+ return pInterface->RegisterToPoseDetectionInProgress(handler, pCookie, *phCallback);
+}
+void XN_CALLBACK_TYPE __ModuleUnregisterFromPoseInProgressCallback(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ ModulePoseDetectionInteface* pInterface = pNode->GetPoseDetectionInteface();
+ _XN_VALIDATE_CAPABILITY_INTERFACE_RET(pInterface,);
+ pInterface->UnregisterFromPoseDetectionInProgress(hCallback);
+}
+
+
+XnUInt16 XN_CALLBACK_TYPE __ModuleGetNumberOfUsers(XnModuleNodeHandle hGenerator)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ return pNode->GetNumberOfUsers();
+}
+XnStatus XN_CALLBACK_TYPE __ModuleGetUsers(XnModuleNodeHandle hGenerator, XnUserID* pUsers, XnUInt16* pnUsers)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ return pNode->GetUsers(pUsers, *pnUsers);
+}
+XnStatus XN_CALLBACK_TYPE __ModuleGetUserCoM(XnModuleNodeHandle hGenerator, XnUserID user, XnPoint3D* pCoM)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ return pNode->GetCoM(user, *pCoM);
+}
+XnStatus XN_CALLBACK_TYPE __ModuleGetUserPixels(XnModuleNodeHandle hGenerator, XnUserID user, XnSceneMetaData* pScene)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ return pNode->GetUserPixels(user, pScene);
+}
+XnStatus XN_CALLBACK_TYPE __ModuleRegisterUserCallbacks(XnModuleNodeHandle hGenerator, XnModuleUserHandler NewUserCB, XnModuleUserHandler LostUserCB, void* pCookie, XnCallbackHandle* phCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ return pNode->RegisterUserCallbacks(NewUserCB, LostUserCB, pCookie, *phCallback);
+}
+void XN_CALLBACK_TYPE __ModuleUnregisterUserCallbacks(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ pNode->UnregisterUserCallbacks(hCallback);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleRegisterToUserExitCallback(XnModuleNodeHandle hGenerator, XnModuleUserHandler handler, void* pCookie, XnCallbackHandle* phCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ return pNode->RegisterToUserExit(handler, pCookie, *phCallback);
+}
+void XN_CALLBACK_TYPE __ModuleUnregisterFromUserExitCallback(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ pNode->UnregisterFromUserExit(hCallback);
+}
+XnStatus XN_CALLBACK_TYPE __ModuleRegisterToUserReEnterCallback(XnModuleNodeHandle hGenerator, XnModuleUserHandler handler, void* pCookie, XnCallbackHandle* phCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ return pNode->RegisterToUserReEnter(handler, pCookie, *phCallback);
+}
+void XN_CALLBACK_TYPE __ModuleUnregisterFromUserReEnterCallback(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleUserGenerator* pNode = dynamic_cast<ModuleUserGenerator*>(pProdNode);
+ pNode->UnregisterFromUserReEnter(hCallback);
+}
+
+
+XnUChar* XN_CALLBACK_TYPE __ModuleGetAudioBuffer(XnModuleNodeHandle hGenerator)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleAudioGenerator* pNode = dynamic_cast<ModuleAudioGenerator*>(pProdNode);
+ return pNode->GetAudioBuffer();
+}
+XnUInt32 XN_CALLBACK_TYPE __ModuleGetSupportedWaveOutputModesCount(XnModuleNodeHandle hGenerator)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleAudioGenerator* pNode = dynamic_cast<ModuleAudioGenerator*>(pProdNode);
+ return pNode->GetSupportedWaveOutputModesCount();
+}
+XnStatus XN_CALLBACK_TYPE __ModuleGetSupportedWaveOutputModes(XnModuleNodeHandle hGenerator, XnWaveOutputMode* aSupportedModes, XnUInt32* pnCount)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleAudioGenerator* pNode = dynamic_cast<ModuleAudioGenerator*>(pProdNode);
+ return pNode->GetSupportedWaveOutputModes(aSupportedModes, *pnCount);
+}
+XnStatus XN_CALLBACK_TYPE __ModuleSetWaveOutputMode(XnModuleNodeHandle hGenerator, const XnWaveOutputMode* pOutputMode)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleAudioGenerator* pNode = dynamic_cast<ModuleAudioGenerator*>(pProdNode);
+ return pNode->SetWaveOutputMode(*pOutputMode);
+}
+XnStatus XN_CALLBACK_TYPE __ModuleGetWaveOutputMode(XnModuleNodeHandle hGenerator, XnWaveOutputMode* pOutputMode)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleAudioGenerator* pNode = dynamic_cast<ModuleAudioGenerator*>(pProdNode);
+ return pNode->GetWaveOutputMode(*pOutputMode);
+}
+XnStatus XN_CALLBACK_TYPE __ModuleRegisterToWaveOutputModeChanges(XnModuleNodeHandle hGenerator, XnModuleStateChangedHandler handler, void* pCookie, XnCallbackHandle* phCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleAudioGenerator* pNode = dynamic_cast<ModuleAudioGenerator*>(pProdNode);
+ return pNode->RegisterToWaveOutputModeChanges(handler, pCookie, *phCallback);
+}
+void XN_CALLBACK_TYPE __ModuleUnregisterFromWaveOutputModeChanges(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hGenerator;
+ ModuleAudioGenerator* pNode = dynamic_cast<ModuleAudioGenerator*>(pProdNode);
+ pNode->UnregisterFromWaveOutputModeChanges(hCallback);
+}
+
+XnCodecID XN_CALLBACK_TYPE __ModuleGetCodecID(XnModuleNodeHandle hCodec)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hCodec;
+ ModuleCodec* pCodec = dynamic_cast<ModuleCodec*>(pProdNode);
+ return pCodec->GetCodecID();
+}
+XnStatus XN_CALLBACK_TYPE __ModuleCodecInit(XnModuleNodeHandle hCodec, XnNodeHandle hNode)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hCodec;
+ ModuleCodec* pCodec = dynamic_cast<ModuleCodec*>(pProdNode);
+ return pCodec->Init(ProductionNode(hNode));
+}
+XnStatus XN_CALLBACK_TYPE __ModuleCompressData(XnModuleNodeHandle hCodec, const void* pSrc, XnUInt32 nSrcSize, void* pDst, XnUInt32 nDstSize, XnUInt* pnBytesWritten)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hCodec;
+ ModuleCodec* pCodec = dynamic_cast<ModuleCodec*>(pProdNode);
+ return pCodec->CompressData(pSrc, nSrcSize, pDst, nDstSize, pnBytesWritten);
+}
+XnStatus XN_CALLBACK_TYPE __ModuleDecompressData(XnModuleNodeHandle hCodec, const void* pSrc, XnUInt32 nSrcSize, void* pDst, XnUInt32 nDstSize, XnUInt* pnBytesWritten)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hCodec;
+ ModuleCodec* pCodec = dynamic_cast<ModuleCodec*>(pProdNode);
+ return pCodec->DecompressData(pSrc, nSrcSize, pDst, nDstSize, pnBytesWritten);
+}
+
+const XnChar* XN_CALLBACK_TYPE __ModuleScriptGetSupportedFormat(XnModuleNodeHandle hScript)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hScript;
+ ModuleScriptNode* pScript = dynamic_cast<ModuleScriptNode*>(pProdNode);
+ return pScript->GetSupportedFormat();
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleLoadScriptFromFile(XnModuleNodeHandle hScript, const XnChar* strFileName)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hScript;
+ ModuleScriptNode* pScript = dynamic_cast<ModuleScriptNode*>(pProdNode);
+ return pScript->LoadScriptFromFile(strFileName);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleLoadScriptFromString(XnModuleNodeHandle hScript, const XnChar* strScript)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hScript;
+ ModuleScriptNode* pScript = dynamic_cast<ModuleScriptNode*>(pProdNode);
+ return pScript->LoadScriptFromString(strScript);
+}
+
+XnStatus XN_CALLBACK_TYPE __ModuleScriptRun(XnModuleNodeHandle hScript, XnNodeInfoList* pCreatedNodes, XnEnumerationErrors* pErrors)
+{
+ ModuleProductionNode* pProdNode = (ModuleProductionNode*)hScript;
+ ModuleScriptNode* pScript = dynamic_cast<ModuleScriptNode*>(pProdNode);
+ NodeInfoList createdNodes(pCreatedNodes);
+ EnumerationErrors errors(pErrors);
+ return pScript->Run(createdNodes, errors);
+}
+
+void XN_CALLBACK_TYPE __ModuleGetExtendedSerializationInterface(XnModuleExtendedSerializationInterface* pInterface)
+{
+ pInterface->InitNotifications = __ModuleInitNotifications;
+ pInterface->StopNotifications = __ModuleStopNotifications;
+}
+
+void XN_CALLBACK_TYPE __ModuleGetLockAwareInterface(XnModuleLockAwareInterface* pInterface)
+{
+ pInterface->SetLockState = __ModuleSetLockState;
+ pInterface->GetLockState = __ModuleGetLockState;
+ pInterface->RegisterToLockChange = __ModuleRegisterToLockChange;
+ pInterface->UnregisterFromLockChange = __ModuleUnregisterFromLockChange;
+}
+
+void XN_CALLBACK_TYPE __ModuleGetErrorStateInterface(XnModuleErrorStateInterface* pInterface)
+{
+ pInterface->GetErrorState = __ModuleGetErrorState;
+ pInterface->RegisterToErrorStateChange = __ModuleRegisterToErrorStateChange;
+ pInterface->UnregisterFromErrorStateChange = __ModuleUnregisterFromErrorStateChange;
+}
+
+void XN_CALLBACK_TYPE __ModuleGetGeneralIntInterface(XnModuleGeneralIntInterface* pInterface)
+{
+ pInterface->GetRange = __ModuleGeneralIntGetRange;
+ pInterface->Get = __ModuleGeneralIntGet;
+ pInterface->Set = __ModuleGeneralIntSet;
+ pInterface->RegisterToValueChange = __ModuleGeneralIntRegisterToValueChange;
+ pInterface->UnregisterFromValueChange = __ModuleGeneralIntUnregisterFromValueChange;
+}
+
+void XN_CALLBACK_TYPE __ModuleGetProductionNodeInterface(XnModuleProductionNodeInterface* pInterface)
+{
+ pInterface->IsCapabilitySupported = __ModuleIsCapabilitySupported;
+ pInterface->SetIntProperty = __ModuleSetIntProperty;
+ pInterface->SetRealProperty = __ModuleSetRealProperty;
+ pInterface->SetStringProperty = __ModuleSetStringProperty;
+ pInterface->SetGeneralProperty = __ModuleSetGeneralProperty;
+ pInterface->GetIntProperty = __ModuleGetIntProperty;
+ pInterface->GetRealProperty = __ModuleGetRealProperty;
+ pInterface->GetStringProperty = __ModuleGetStringProperty;
+ pInterface->GetGeneralProperty = __ModuleGetGeneralProperty;
+
+ __ModuleGetExtendedSerializationInterface(pInterface->pExtendedSerializationInterface);
+ __ModuleGetLockAwareInterface(pInterface->pLockAwareInterface);
+ __ModuleGetErrorStateInterface(pInterface->pErrorStateInterface);
+ __ModuleGetGeneralIntInterface(pInterface->pGeneralIntInterface);
+}
+
+void XN_CALLBACK_TYPE __ModuleGetDeviceIdentificationInterface(XnModuleDeviceIdentificationInterface* pInterface)
+{
+ pInterface->GetDeviceName = __ModuleGetDeviceName;
+ pInterface->GetVendorSpecificData = __ModuleGetVendorSpecificData;
+ pInterface->GetSerialNumber = __ModuleGetSerialNumber;
+}
+
+void XN_CALLBACK_TYPE __ModuleGetDeviceInterface(XnModuleDeviceInterface* pInterface)
+{
+ __ModuleGetProductionNodeInterface(pInterface->pProductionNode);
+ __ModuleGetDeviceIdentificationInterface(pInterface->pDeviceIdentificationInterface);
+}
+
+void XN_CALLBACK_TYPE __ModuleGetMirrorInterface(XnModuleMirrorInterface* pInterface)
+{
+ pInterface->SetMirror = __ModuleSetMirror;
+ pInterface->IsMirrored = __ModuleIsMirrored;
+ pInterface->RegisterToMirrorChange = __ModuleRegisterToMirrorChange;
+ pInterface->UnregisterFromMirrorChange = __ModuleUnregisterFromMirrorChange;
+}
+
+void XN_CALLBACK_TYPE __ModuleGetAlternativeViewPointInterface(XnModuleAlternativeViewPointInterface* pInterface)
+{
+ pInterface->IsViewPointSupported = __ModuleIsViewPointSupported;
+ pInterface->SetViewPoint = __ModuleSetViewPoint;
+ pInterface->ResetViewPoint = __ModuleResetViewPoint;
+ pInterface->IsViewPointAs = __ModuleIsViewPointAs;
+ pInterface->RegisterToViewPointChange = __ModuleRegisterToViewPointChange;
+ pInterface->UnregisterFromViewPointChange = __ModuleUnregisterFromViewPointChange;
+}
+
+void XN_CALLBACK_TYPE __ModuleGetFrameSyncInterface(XnModuleFrameSyncInterface* pInterface)
+{
+ pInterface->CanFrameSyncWith = __ModuleCanFrameSyncWith;
+ pInterface->FrameSyncWith = __ModuleFrameSyncWith;
+ pInterface->StopFrameSyncWith = __ModuleStopFrameSyncWith;
+ pInterface->IsFrameSyncedWith = __ModuleIsFrameSyncedWith;
+ pInterface->RegisterToFrameSyncChange = __ModuleRegisterToFrameSyncChange;
+ pInterface->UnregisterFromFrameSyncChange = __ModuleUnregisterFromFrameSyncChange;
+}
+
+void XN_CALLBACK_TYPE __ModuleGetGeneratorInterface(XnModuleGeneratorInterface* pInterface)
+{
+ __ModuleGetProductionNodeInterface(pInterface->pProductionNodeInterface);
+ pInterface->StartGenerating = __ModuleStartGenerating;
+ pInterface->IsGenerating = __ModuleIsGenerating;
+ pInterface->StopGenerating = __ModuleStopGenerating;
+ pInterface->RegisterToGenerationRunningChange = __ModuleRegisterToGenerationRunningChange;
+ pInterface->UnregisterFromGenerationRunningChange = __ModuleUnregisterFromGenerationRunningChange;
+ pInterface->RegisterToNewDataAvailable = __ModuleRegisterToNewDataAvailable;
+ pInterface->UnregisterFromNewDataAvailable = __ModuleUnregisterFromNewDataAvailable;
+ pInterface->IsNewDataAvailable = __ModuleIsNewDataAvailable;
+ pInterface->UpdateData = __ModuleUpdateData;
+ pInterface->GetData = __ModuleGetData;
+ pInterface->GetDataSize = __ModuleGetDataSize;
+ pInterface->GetTimestamp = __ModuleGetTimestamp;
+ pInterface->GetFrameID = __ModuleGetFrameID;
+ __ModuleGetMirrorInterface(pInterface->pMirrorInterface);
+ __ModuleGetAlternativeViewPointInterface(pInterface->pAlternativeViewPointInterface);
+ __ModuleGetFrameSyncInterface(pInterface->pFrameSyncInterface);
+}
+
+void XN_CALLBACK_TYPE __ModuleGetNodeNotificationsInterface(XnNodeNotifications *pInterface)
+{
+ pInterface->OnNodeAdded = __ModuleOnNodeAdded;
+ pInterface->OnNodeRemoved = __ModuleOnNodeRemoved;
+ pInterface->OnNodeIntPropChanged = __ModuleOnNodeIntPropChanged;
+ pInterface->OnNodeRealPropChanged = __ModuleOnNodeRealPropChanged;
+ pInterface->OnNodeStringPropChanged = __ModuleOnNodeStringPropChanged;
+ pInterface->OnNodeGeneralPropChanged = __ModuleOnNodeGeneralPropChanged;
+ pInterface->OnNodeStateReady = __ModuleOnNodeStateReady;
+ pInterface->OnNodeNewData = __ModuleOnNodeNewData;
+}
+
+void XN_CALLBACK_TYPE __ModuleGetRecorderInterface(XnModuleRecorderInterface* pInterface)
+{
+ pInterface->SetOutputStream = __ModuleSetOutputStream;
+ __ModuleGetProductionNodeInterface(pInterface->pProductionNode);
+ __ModuleGetNodeNotificationsInterface(pInterface->pNodeNotifications);
+}
+
+void XN_CALLBACK_TYPE __ModuleGetPlayerInterface(XnModulePlayerInterface* pInterface)
+{
+ __ModuleGetProductionNodeInterface(pInterface->pProductionNode);
+ pInterface->SetInputStream = __ModuleSetInputStream;
+ pInterface->ReadNext = __ModuleReadNext;
+ pInterface->SetNodeNotifications = __ModuleSetNodeNotifications;
+ pInterface->SetRepeat = __ModuleSetRepeat;
+ pInterface->SeekToTimeStamp = __ModuleSeekToTimeStamp;
+ pInterface->SeekToFrame = __ModuleSeekToFrame;
+ pInterface->TellTimestamp = __ModuleTellTimestamp;
+ pInterface->TellFrame = __ModuleTellFrame;
+ pInterface->GetNumFrames = __ModuleGetNumFrames;
+ pInterface->GetSupportedFormat = __ModuleGetSupportedFormat;
+ pInterface->IsEOF = __ModuleIsEOF;
+ pInterface->RegisterToEndOfFileReached = __ModuleRegisterToEndOfFileReached;
+ pInterface->UnregisterFromEndOfFileReached = __ModuleUnregisterFromEndOfFileReached;
+}
+
+void XN_CALLBACK_TYPE __ModuleGetCroppingInterface(XnModuleCroppingInterface* pInterface)
+{
+ pInterface->SetCropping = __ModuleSetCropping;
+ pInterface->GetCropping = __ModuleGetCropping;
+ pInterface->RegisterToCroppingChange = __ModuleRegisterToCroppingChange;
+ pInterface->UnregisterFromCroppingChange = __ModuleUnregisterFromCroppingChange;
+}
+
+void XN_CALLBACK_TYPE __ModuleGetAntiFlickerInterface(XnModuleAntiFlickerInterface* pInterface)
+{
+ pInterface->SetPowerLineFrequency = __ModuleSetPowerLineFrequency;
+ pInterface->GetPowerLineFrequency = __ModuleGetPowerLineFrequency;
+ pInterface->RegisterToPowerLineFrequencyChange = __ModuleRegisterToPowerLineFrequencyChange;
+ pInterface->UnregisterFromPowerLineFrequencyChange = __ModuleUnregisterFromPowerLineFrequencyChange;
+}
+
+void XN_CALLBACK_TYPE __ModuleGetMapGeneratorInterface(XnModuleMapGeneratorInterface* pInterface)
+{
+ __ModuleGetGeneratorInterface(pInterface->pGeneratorInterface);
+ pInterface->GetSupportedMapOutputModesCount = __ModuleGetSupportedMapOutputModesCount;
+ pInterface->GetSupportedMapOutputModes = __ModuleGetSupportedMapOutputModes;
+ pInterface->SetMapOutputMode = __ModuleSetMapOutputMode;
+ pInterface->GetMapOutputMode = __ModuleGetMapOutputMode;
+ pInterface->RegisterToMapOutputModeChange = __ModuleRegisterToMapOutputModeChange;
+ pInterface->UnregisterFromMapOutputModeChange = __ModuleUnregisterFromMapOutputModeChange;
+ pInterface->GetBytesPerPixel = __ModuleGetBytesPerPixel;
+ __ModuleGetCroppingInterface(pInterface->pCroppingInterface);
+ __ModuleGetAntiFlickerInterface(pInterface->pAntiFlickerInterface);
+}
+
+void XN_CALLBACK_TYPE __ModuleGetUserPositionInterface(XnModuleUserPositionCapabilityInterface* pInterface)
+{
+ pInterface->GetSupportedUserPositionsCount = __ModuleGetSupportedUserPositionsCount;
+ pInterface->SetUserPosition = __ModuleSetUserPosition;
+ pInterface->GetUserPosition = __ModuleGetUserPosition;
+ pInterface->RegisterToUserPositionChange = __ModuleRegisterToUserPositionChange;
+ pInterface->UnregisterFromUserPositionChange = __ModuleUnregisterFromUserPositionChange;
+}
+
+void XN_CALLBACK_TYPE __ModuleGetDepthGeneratorInterface(XnModuleDepthGeneratorInterface* pInterface)
+{
+ __ModuleGetMapGeneratorInterface(pInterface->pMapInterface);
+ pInterface->GetDeviceMaxDepth = __ModuleGetDeviceMaxDepth;
+ pInterface->GetFieldOfView = __ModuleGetFieldOfView;
+ pInterface->RegisterToFieldOfViewChange = __ModuleRegisterToFieldOfViewChange;
+ pInterface->UnregisterFromFieldOfViewChange = __ModuleUnregisterFromFieldOfViewChange;
+ pInterface->GetDepthMap = __ModuleGetDepthMap;
+ __ModuleGetUserPositionInterface(pInterface->pUserPositionInterface);
+}
+
+void XN_CALLBACK_TYPE __ModuleGetImageGeneratorInterface(XnModuleImageGeneratorInterface* pInterface)
+{
+ __ModuleGetMapGeneratorInterface(pInterface->pMapInterface);
+ pInterface->GetImageMap = __ModuleGetImageMap;
+ pInterface->IsPixelFormatSupported = __ModuleIsPixelFormatSupported;
+ pInterface->SetPixelFormat = __ModuleSetPixelFormat;
+ pInterface->GetPixelFormat = __ModuleGetPixelFormat;
+ pInterface->RegisterToPixelFormatChange = __ModuleRegisterToPixelFormatChange;
+ pInterface->UnregisterFromPixelFormatChange = __ModuleUnregisterFromPixelFormatChange;
+}
+
+void XN_CALLBACK_TYPE __ModuleGetIRGeneratorInterface(XnModuleIRGeneratorInterface* pInterface)
+{
+ __ModuleGetMapGeneratorInterface(pInterface->pMapInterface);
+ pInterface->GetIRMap = __ModuleGetIRMap;
+}
+
+void XN_CALLBACK_TYPE __ModuleGetGestureGeneratorInterface(XnModuleGestureGeneratorInterface* pInterface)
+{
+ __ModuleGetGeneratorInterface(pInterface->pGeneratorInterface);
+ pInterface->AddGesture = __ModuleAddGesture;
+ pInterface->RemoveGesture = __ModuleRemoveGesture;
+ pInterface->GetActiveGestures = __ModuleGetActiveGestures;
+ pInterface->GetAllActiveGestures = __ModuleGetAllActiveGestures;
+ pInterface->EnumerateGestures = __ModuleEnumerateGestures;
+ pInterface->EnumerateAllGestures = __ModuleEnumerateAllGestures;
+ pInterface->IsGestureAvailable = __ModuleIsGestureAvailable;
+ pInterface->IsGestureProgressSupported = __ModuleIsGestureProgressSupported;
+ pInterface->RegisterGestureCallbacks = __ModuleRegisterGestureCallbacks;
+ pInterface->UnregisterGestureCallbacks = __ModuleUnregisterGestureCallbacks;
+ pInterface->RegisterToGestureChange = __ModuleRegisterToGestureChange;
+ pInterface->UnregisterFromGestureChange = __ModuleUnregisterFromGestureChange;
+
+ pInterface->RegisterToGestureIntermediateStageCompleted = __ModuleRegisterToGestureIntermediateStageCompleted;
+ pInterface->UnregisterFromGestureIntermediateStageCompleted = __ModuleUnregisterFromGestureIntermediateStageCompleted;
+ pInterface->RegisterToGestureReadyForNextIntermediateStage = __ModuleRegisterToGestureReadyForNextIntermediateStage;
+ pInterface->UnregisterFromGestureReadyForNextIntermediateStage = __ModuleUnregisterFromGestureReadyForNextIntermediateStage;
+}
+
+void XN_CALLBACK_TYPE __ModuleGetSceneAnalyzerInterface(XnModuleSceneAnalyzerInterface* pInterface)
+{
+ __ModuleGetMapGeneratorInterface(pInterface->pMapInterface);
+ pInterface->GetLabelMap = __ModuleGetLabelMap;
+ pInterface->GetFloor = __ModuleGetFloor;
+}
+
+void XN_CALLBACK_TYPE __ModuleGetSkeletonInterface(XnModuleSkeletonCapabilityInterface* pInterface)
+{
+ pInterface->IsJointAvailable = __ModuleIsJointAvailable;
+ pInterface->IsProfileAvailable = __ModuleIsProfileAvailable;
+ pInterface->SetSkeletonProfile = __ModuleSetSkeletonProfile;
+ pInterface->SetJointActive = __ModuleSetJointActive;
+ pInterface->IsJointActive = __ModuleIsJointActive;
+ pInterface->RegisterToJointConfigurationChange = __ModuleRegisterToJointConfigurationChange;
+ pInterface->UnregisterFromJointConfigurationChange = __ModuleUnregisterFromJointConfigurationChange;
+ pInterface->EnumerateActiveJoints = __ModuleEnumerateActiveJoints;
+ pInterface->GetSkeletonJoint = __ModuleGetSkeletonJoint;
+ pInterface->GetSkeletonJointPosition = __ModuleGetSkeletonJointPosition;
+ pInterface->GetSkeletonJointOrientation = __ModuleGetSkeletonJointOrientation;
+ pInterface->IsTracking = __ModuleIsSkeletonTracking;
+ pInterface->IsCalibrated = __ModuleIsSkeletonCalibrated;
+ pInterface->IsCalibrating = __ModuleIsSkeletonCalibrating;
+ pInterface->RequestCalibration = __ModuleRequestSkeletonCalibration;
+ pInterface->AbortCalibration = __ModuleAbortSkeletonCalibration;
+ pInterface->SaveCalibrationDataToFile = __ModuleSaveCalibrationDataToFile;
+ pInterface->LoadCalibrationDataFromFile = __ModuleLoadCalibrationDataFromFile;
+ pInterface->SaveCalibrationData = __ModuleSaveCalibrationData;
+ pInterface->LoadCalibrationData = __ModuleLoadCalibrationData;
+ pInterface->ClearCalibrationData = __ModuleClearCalibrationData;
+ pInterface->IsCalibrationData = __ModuleIsCalibrationData;
+ pInterface->StartTracking = __ModuleStartSkeletonTracking;
+ pInterface->StopTracking = __ModuleStopSkeletonTracking;
+ pInterface->Reset = __ModuleResetSkeleton;
+ pInterface->NeedPoseForCalibration = __ModuleNeedPoseForSkeletonCalibration;
+ pInterface->GetCalibrationPose = __ModuleGetSkeletonCalibrationPose;
+ pInterface->SetSmoothing = __ModuleSetSkeletonSmoothing;
+ pInterface->RegisterCalibrationCallbacks = __ModuleRegisterCalibrationCallbacks;
+ pInterface->UnregisterCalibrationCallbacks = __ModuleUnregisterCalibrationCallbacks;
+
+ pInterface->RegisterToCalibrationInProgress = __ModuleRegisterToCalibrationInProgressCallback;
+ pInterface->UnregisterFromCalibrationInProgress = __ModuleUnregisterFromCalibrationInProgressCallback;
+ pInterface->RegisterToCalibrationComplete = __ModuleRegisterToCalibrationCompleteCallback;
+ pInterface->UnregisterFromCalibrationComplete = __ModuleUnregisterFromCalibrationCompleteCallback;
+
+ pInterface->RegisterToCalibrationStart = __ModuleRegisterToCalibrationStartCallback;
+ pInterface->UnregisterFromCalibrationStart = __ModuleUnregisterFromCalibrationStartCallback;
+}
+
+void XN_CALLBACK_TYPE __ModuleGetPoseDetectionInterface(XnModulePoseDetectionCapabilityInterface* pInteface)
+{
+ pInteface->GetNumberOfPoses = __ModuleGetNumberOfPoses;
+ pInteface->GetAvailablePoses = __ModuleGetAvailablePoses;
+ pInteface->GetAllAvailablePoses = __ModuleGetAllAvailablePoses;
+ pInteface->StartPoseDetection = __ModuleStartPoseDetection;
+ pInteface->StopPoseDetection = __ModuleStopPoseDetection;
+ pInteface->StopSinglePoseDetection = __ModuleStopSinglePoseDetection;
+ pInteface->RegisterToPoseCallbacks = __ModuleRegisterToPoseCallbacks;
+ pInteface->UnregisterFromPoseCallbacks = __ModuleUnregisterFromPoseCallbacks;
+
+ pInteface->RegisterToPoseDetectionInProgress = __ModuleRegisterToPoseInProgressCallback;
+ pInteface->UnregisterFromPoseDetectionInProgress = __ModuleUnregisterFromPoseInProgressCallback;
+
+ pInteface->RegisterToPoseDetected = __ModuleRegisterToPoseDetected;
+ pInteface->UnregisterFromPoseDetected = __ModuleUnregisterFromPoseDetected;
+ pInteface->RegisterToOutOfPose = __ModuleRegisterToOutOfPose;
+ pInteface->UnregisterFromOutOfPose = __ModuleUnregisterFromOutOfPose;
+}
+
+void XN_CALLBACK_TYPE __ModuleGetUserGeneratorInterface(XnModuleUserGeneratorInterface* pInterface)
+{
+ __ModuleGetGeneratorInterface(pInterface->pGeneratorInterface);
+
+ pInterface->GetNumberOfUsers = __ModuleGetNumberOfUsers;
+ pInterface->GetUsers = __ModuleGetUsers;
+ pInterface->GetCoM = __ModuleGetUserCoM;
+ pInterface->GetUserPixels = __ModuleGetUserPixels;
+ pInterface->RegisterUserCallbacks = __ModuleRegisterUserCallbacks;
+ pInterface->UnregisterUserCallbacks = __ModuleUnregisterUserCallbacks;
+
+ __ModuleGetSkeletonInterface(pInterface->pSkeletonInterface);
+ __ModuleGetPoseDetectionInterface(pInterface->pPoseDetectionInterface);
+
+ pInterface->RegisterToUserExit = __ModuleRegisterToUserExitCallback;
+ pInterface->UnregisterFromUserExit = __ModuleUnregisterFromUserExitCallback;
+ pInterface->RegisterToUserReEnter = __ModuleRegisterToUserReEnterCallback;
+ pInterface->UnregisterFromUserReEnter = __ModuleUnregisterFromUserReEnterCallback;
+}
+
+void XN_CALLBACK_TYPE __ModuleGetHandTouchingFOVEdgeInterface(XnModuleHandTouchingFOVEdgeCapabilityInterface* pInterface)
+{
+ pInterface->RegisterToHandTouchingFOVEdge = __ModuleRegisterToHandTouchingFOVEdgeCallback;
+ pInterface->UnregisterFromHandTouchingFOVEdge = __ModuleUnregisterFromHandTouchingFOVEdgeCallback;
+}
+void XN_CALLBACK_TYPE __ModuleGetHandsGeneratorInterface(XnModuleHandsGeneratorInterface* pInterface)
+{
+ __ModuleGetGeneratorInterface(pInterface->pGeneratorInterface);
+
+ pInterface->StartTracking = __ModuleStartTracking;
+ pInterface->StopTracking = __ModuleStopTracking;
+ pInterface->StopTrackingAll = __ModuleStopTrackingAll;
+ pInterface->RegisterHandCallbacks = __ModuleRegisterHandCallbacks;
+ pInterface->UnregisterHandCallbacks = __ModuleUnregisterHandCallbacks;
+ pInterface->SetSmoothing = __ModuleSetTrackingSmoothing;
+
+ __ModuleGetHandTouchingFOVEdgeInterface(pInterface->pHandTouchingFOVEdgeInterface);
+}
+
+void XN_CALLBACK_TYPE __ModuleGetAudioGeneratorInterface(XnModuleAudioGeneratorInterface* pInterface)
+{
+ __ModuleGetGeneratorInterface(pInterface->pGeneratorInterface);
+
+ pInterface->GetAudioBuffer = __ModuleGetAudioBuffer;
+ pInterface->GetSupportedWaveOutputModesCount = __ModuleGetSupportedWaveOutputModesCount;
+ pInterface->GetSupportedWaveOutputModes = __ModuleGetSupportedWaveOutputModes;
+ pInterface->SetWaveOutputMode = __ModuleSetWaveOutputMode;
+ pInterface->GetWaveOutputMode = __ModuleGetWaveOutputMode;
+ pInterface->RegisterToWaveOutputModeChanges = __ModuleRegisterToWaveOutputModeChanges;
+ pInterface->UnregisterFromWaveOutputModeChanges = __ModuleUnregisterFromWaveOutputModeChanges;
+}
+
+void XN_CALLBACK_TYPE __ModuleGetCodecInterface(XnModuleCodecInterface* pInterface)
+{
+ __ModuleGetProductionNodeInterface(pInterface->pProductionNode);
+
+ pInterface->GetCodecID = __ModuleGetCodecID;
+ pInterface->Init = __ModuleCodecInit;
+ pInterface->CompressData = __ModuleCompressData;
+ pInterface->DecompressData = __ModuleDecompressData;
+}
+
+void XN_CALLBACK_TYPE __ModuleGetScriptNodeInterface(XnModuleScriptNodeInterface* pInterface)
+{
+ __ModuleGetProductionNodeInterface(pInterface->pProductionNode);
+
+ pInterface->GetSupportedFormat = __ModuleScriptGetSupportedFormat;
+ pInterface->LoadScriptFromFile = __ModuleLoadScriptFromFile;
+ pInterface->LoadScriptFromString = __ModuleLoadScriptFromString;
+ pInterface->Run = __ModuleScriptRun;
+}
+
+#endif /* XN_MODULE_C_FUNCTIONS_H_ */
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnModuleCppInterface.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnModuleCppInterface.h
new file mode 100644
index 00000000..beb555e5
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnModuleCppInterface.h
@@ -0,0 +1,605 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef __XN_MODULE_CPP_INTERFACE_H__
+#define __XN_MODULE_CPP_INTERFACE_H__
+
+/**
+ * NOTE: this file should never be compiled into OpenNI. It must always remain
+ * in this h-file only (to make sure nothing breaks when installing new OpenNI DLL).
+ * It is only provided as a syntactic sugar for exporting interfaces.
+ */
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include "XnModuleInterface.h"
+#include "XnListT.h"
+#include "XnCppWrapper.h"
+
+//---------------------------------------------------------------------------
+// Types
+//---------------------------------------------------------------------------
+namespace xn
+{
+ typedef XnListT<XnModuleGetExportedInterfacePtr> ExportedNodesList;
+
+ class ModuleProductionNode;
+
+ class Module
+ {
+ public:
+ Module() {}
+ virtual ~Module() {}
+
+ virtual XnStatus Load() { return XN_STATUS_OK; }
+ virtual void Unload() {}
+
+ inline XnStatus AddExportedNode(XnModuleGetExportedInterfacePtr pEntryPoint) { return m_ExportedNodes.AddLast(pEntryPoint); }
+
+ XnUInt32 GetExportedNodesCount() { return m_ExportedNodes.Size(); }
+
+ XnStatus GetExportedNodes(XnModuleGetExportedInterfacePtr* aEntryPoints, XnUInt32 nCount)
+ {
+ if (nCount < m_ExportedNodes.Size())
+ {
+ return XN_STATUS_OUTPUT_BUFFER_OVERFLOW;
+ }
+
+ XnUInt32 i = 0;
+ for (ExportedNodesList::ConstIterator it = m_ExportedNodes.Begin();
+ it != m_ExportedNodes.End();
+ ++it, ++i)
+ {
+ aEntryPoints[i] = *it;
+ }
+
+ return (XN_STATUS_OK);
+ }
+
+ private:
+ ExportedNodesList m_ExportedNodes;
+ };
+
+ class ExtensionModule : public Module
+ {
+ public:
+ virtual XnStatus Load()
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ nRetVal = Module::Load();
+ XN_IS_STATUS_OK(nRetVal);
+
+ nRetVal = RegisterNewTypes();
+ XN_IS_STATUS_OK(nRetVal);
+
+ return (XN_STATUS_OK);
+ }
+
+ protected:
+ virtual XnStatus RegisterNewTypes() = 0;
+ };
+
+ class ModuleExportedProductionNode
+ {
+ public:
+ ModuleExportedProductionNode() {}
+ virtual ~ModuleExportedProductionNode() {}
+
+ virtual void GetDescription(XnProductionNodeDescription* pDescription) = 0;
+ virtual XnStatus EnumerateProductionTrees(Context& context, NodeInfoList& TreesList, EnumerationErrors* pErrors) = 0;
+ virtual XnStatus Create(Context& context, const XnChar* strInstanceName, const XnChar* strCreationInfo, NodeInfoList* pNeededTrees, const XnChar* strConfigurationDir, ModuleProductionNode** ppInstance) = 0;
+ virtual void Destroy(ModuleProductionNode* pInstance) = 0;
+ };
+
+ class ModuleExtendedSerializationInterface
+ {
+ public:
+ virtual ~ModuleExtendedSerializationInterface() {}
+ virtual XnStatus NotifyExState(XnNodeNotifications* pNotifications, void* pCookie) = 0;
+ virtual void UnregisterExNotifications() = 0;
+ };
+
+ class ModuleLockAwareInterface
+ {
+ public:
+ virtual ~ModuleLockAwareInterface() {}
+ virtual XnStatus SetLockState(XnBool bLocked) = 0;
+ virtual XnBool GetLockState() = 0;
+ virtual XnStatus RegisterToLockChange(XnModuleStateChangedHandler handler, void* pCookie, XnCallbackHandle& hCallback) = 0;
+ virtual void UnregisterFromLockChange(XnCallbackHandle hCallback) = 0;
+ };
+
+ class ModuleErrorStateInterface
+ {
+ public:
+ virtual ~ModuleErrorStateInterface() {}
+ virtual XnStatus GetErrorState() = 0;
+ virtual XnStatus RegisterToErrorStateChange(XnModuleStateChangedHandler handler, void* pCookie, XnCallbackHandle& hCallback) = 0;
+ virtual void UnregisterFromErrorStateChange(XnCallbackHandle hCallback) = 0;
+ };
+
+ class ModuleGeneralIntInterface
+ {
+ public:
+ virtual XnStatus GetRange(const XnChar* strCap, XnInt32& nMin, XnInt32& nMax, XnInt32& nStep, XnInt32& nDefault, XnBool& bIsAutoSupported) = 0;
+ virtual XnStatus Get(const XnChar* strCap, XnInt32& nValue) = 0;
+ virtual XnInt32 Set(const XnChar* strCap, XnInt32 nValue) = 0;
+ virtual XnStatus RegisterToValueChange(const XnChar* strCap, XnModuleStateChangedHandler handler, void* pCookie, XnCallbackHandle& hCallback) = 0;
+ virtual void UnregisterFromValueChange(const XnChar* strCap, XnCallbackHandle hCallback) = 0;
+ };
+
+ class ModuleProductionNode
+ {
+ public:
+#ifdef XN_NO_DYNAMIC_CAST
+ ModuleProductionNode()
+ {
+ xnOSMemSet(m_aInterfaces, 0, sizeof(m_aInterfaces));
+ m_aInterfaces[XN_NODE_TYPE_PRODUCTION_NODE] = this;
+ }
+#endif
+ virtual ~ModuleProductionNode() {}
+ virtual XnBool IsCapabilitySupported(const XnChar* /*strCapabilityName*/) { return FALSE; }
+ virtual XnStatus SetIntProperty(const XnChar* /*strName*/, XnUInt64 /*nValue*/) { return XN_STATUS_ERROR; }
+ virtual XnStatus SetRealProperty(const XnChar* /*strName*/, XnDouble /*dValue*/) { return XN_STATUS_ERROR; }
+ virtual XnStatus SetStringProperty(const XnChar* /*strName*/, const XnChar* /*strValue*/) { return XN_STATUS_ERROR; }
+ virtual XnStatus SetGeneralProperty(const XnChar* /*strName*/, XnUInt32 /*nBufferSize*/, const void* /*pBuffer*/) { return XN_STATUS_ERROR; }
+ virtual XnStatus GetIntProperty(const XnChar* /*strName*/, XnUInt64& /*nValue*/) const { return XN_STATUS_ERROR; }
+ virtual XnStatus GetRealProperty(const XnChar* /*strName*/, XnDouble& /*dValue*/) const { return XN_STATUS_ERROR; }
+ virtual XnStatus GetStringProperty(const XnChar* /*strName*/, XnChar* /*csValue*/, XnUInt32 /*nBufSize*/) const { return XN_STATUS_ERROR; }
+ virtual XnStatus GetGeneralProperty(const XnChar* /*strName*/, XnUInt32 /*nBufferSize*/, void* /*pBuffer*/) const { return XN_STATUS_ERROR; }
+ virtual ModuleExtendedSerializationInterface* GetExtendedSerializationInterface() { return NULL; }
+ virtual ModuleLockAwareInterface* GetLockAwareInterface() { return NULL; }
+ virtual ModuleErrorStateInterface* GetErrorStateInterface() { return NULL; }
+ virtual ModuleGeneralIntInterface* GetGeneralIntInterface(const XnChar* /*strCap*/) { return NULL; }
+
+ public:
+#ifdef XN_NO_DYNAMIC_CAST
+ void* m_aInterfaces[XN_NODE_TYPE_FIRST_EXTENSION];
+#endif
+ };
+
+ class ModuleDeviceIdentificationInterface
+ {
+ public:
+ virtual ~ModuleDeviceIdentificationInterface() {}
+ virtual XnStatus GetDeviceName(XnChar* strBuffer, XnUInt32& nBufferSize) = 0;
+ virtual XnStatus GetVendorSpecificData(XnChar* strBuffer, XnUInt32& nBufferSize) = 0;
+ virtual XnStatus GetSerialNumber(XnChar* strBuffer, XnUInt32& nBufferSize) = 0;
+ };
+
+ class ModuleDevice : virtual public ModuleProductionNode
+ {
+ public:
+#ifdef XN_NO_DYNAMIC_CAST
+ ModuleDevice() { m_aInterfaces[XN_NODE_TYPE_DEVICE] = this; }
+#endif
+ virtual ~ModuleDevice() {}
+ virtual ModuleDeviceIdentificationInterface* GetIdentificationInterface() { return NULL; }
+ };
+
+ class ModuleMirrorInterface
+ {
+ public:
+ virtual ~ModuleMirrorInterface() {}
+ virtual XnStatus SetMirror(XnBool bMirror) = 0;
+ virtual XnBool IsMirrored() = 0;
+ virtual XnStatus RegisterToMirrorChange(XnModuleStateChangedHandler handler, void* pCookie, XnCallbackHandle& hCallback) = 0;
+ virtual void UnregisterFromMirrorChange(XnCallbackHandle hCallback) = 0;
+ };
+
+ class ModuleAlternativeViewPointInterface
+ {
+ public:
+ virtual ~ModuleAlternativeViewPointInterface() {}
+ virtual XnBool IsViewPointSupported(ProductionNode& other) = 0;
+ virtual XnStatus SetViewPoint(ProductionNode& other) = 0;
+ virtual XnBool IsViewPointAs(ProductionNode& other) = 0;
+ virtual XnStatus ResetViewPoint() = 0;
+ virtual XnStatus RegisterToViewPointChange(XnModuleStateChangedHandler handler, void* pCookie, XnCallbackHandle& hCallback) = 0;
+ virtual void UnregisterFromViewPointChange(XnCallbackHandle hCallback) = 0;
+ };
+
+ class ModuleFrameSyncInterface
+ {
+ public:
+ virtual XnBool CanFrameSyncWith(ProductionNode& other) = 0;
+ virtual XnStatus FrameSyncWith(ProductionNode& other) = 0;
+ virtual XnStatus StopFrameSyncWith(ProductionNode& other) = 0;
+ virtual XnBool IsFrameSyncedWith(ProductionNode& other) = 0;
+ virtual XnStatus RegisterToFrameSyncChange(XnModuleStateChangedHandler handler, void* pCookie, XnCallbackHandle& hCallback) = 0;
+ virtual void UnregisterFromFrameSyncChange(XnCallbackHandle hCallback) = 0;
+ };
+
+ class ModuleGenerator : virtual public ModuleProductionNode
+ {
+ public:
+#ifdef XN_NO_DYNAMIC_CAST
+ ModuleGenerator() { m_aInterfaces[XN_NODE_TYPE_GENERATOR] = this;}
+#endif
+ virtual ~ModuleGenerator() {}
+ virtual XnStatus StartGenerating() = 0;
+ virtual XnBool IsGenerating() = 0;
+ virtual void StopGenerating() = 0;
+ virtual XnStatus RegisterToGenerationRunningChange(XnModuleStateChangedHandler handler, void* pCookie, XnCallbackHandle& hCallback) = 0;
+ virtual void UnregisterFromGenerationRunningChange(XnCallbackHandle hCallback) = 0;
+ virtual XnStatus RegisterToNewDataAvailable(XnModuleStateChangedHandler handler, void* pCookie, XnCallbackHandle& hCallback) = 0;
+ virtual void UnregisterFromNewDataAvailable(XnCallbackHandle hCallback) = 0;
+ virtual XnBool IsNewDataAvailable(XnUInt64& nTimestamp) = 0;
+ virtual XnStatus UpdateData() = 0;
+ virtual const void* GetData() = 0;
+ virtual XnUInt32 GetDataSize() = 0;
+ virtual XnUInt64 GetTimestamp() = 0;
+ virtual XnUInt32 GetFrameID() = 0;
+ virtual ModuleMirrorInterface* GetMirrorInterface() { return NULL; }
+ virtual ModuleAlternativeViewPointInterface* GetAlternativeViewPointInterface() { return NULL; }
+ virtual ModuleFrameSyncInterface* GetFrameSyncInterface() { return NULL; }
+ };
+
+ class ModuleNodeNotifications
+ {
+ public:
+ virtual ~ModuleNodeNotifications() {}
+ virtual XnStatus OnNodeAdded(const XnChar* strNodeName, XnProductionNodeType type, XnCodecID compression) = 0;
+ virtual XnStatus OnNodeRemoved(const XnChar* strNodeName) = 0;
+ virtual XnStatus OnNodeIntPropChanged(const XnChar* strNodeName, const XnChar* strPropName, XnUInt64 nValue) = 0;
+ virtual XnStatus OnNodeRealPropChanged(const XnChar* strNodeName, const XnChar* strPropName, XnDouble dValue) = 0;
+ virtual XnStatus OnNodeStringPropChanged(const XnChar* strNodeName, const XnChar* strPropName, const XnChar* strValue) = 0;
+ virtual XnStatus OnNodeStateReady(const XnChar* strNodeName) = 0;
+ virtual XnStatus OnNodeGeneralPropChanged(const XnChar* strNodeName, const XnChar* strPropName, XnUInt32 nBufferSize, const void* pBuffer) = 0;
+ virtual XnStatus OnNodeNewData(const XnChar* strNodeName, XnUInt64 nTimeStamp, XnUInt32 nFrame, const void* pData, XnUInt32 nSize) = 0;
+ };
+
+ class ModuleRecorder :
+ virtual public ModuleProductionNode,
+ virtual public ModuleNodeNotifications
+ {
+ public:
+#ifdef XN_NO_DYNAMIC_CAST
+ ModuleRecorder() { m_aInterfaces[XN_NODE_TYPE_RECORDER] = this; }
+#endif
+ virtual ~ModuleRecorder() {}
+ virtual XnStatus SetOutputStream(void* pCookie, XnRecorderOutputStreamInterface* pStream) = 0;
+ };
+
+ class ModulePlayer : virtual public ModuleProductionNode
+ {
+ public:
+#ifdef XN_NO_DYNAMIC_CAST
+ ModulePlayer() { m_aInterfaces[XN_NODE_TYPE_PLAYER] = this; }
+#endif
+ virtual ~ModulePlayer() {}
+ virtual XnStatus SetInputStream(void* pStreamCookie, XnPlayerInputStreamInterface* pStream) = 0;
+ virtual XnStatus ReadNext() = 0;
+ virtual XnStatus SetNodeNotifications(void* pNodeNotificationsCookie, XnNodeNotifications* pNodeNotifications) = 0;
+
+ virtual XnStatus SetRepeat(XnBool bRepeat) = 0;
+ virtual XnStatus SeekToTimeStamp(XnInt64 nTimeOffset, XnPlayerSeekOrigin origin) = 0;
+ virtual XnStatus SeekToFrame(const XnChar* strNodeName, XnInt32 nFrameOffset, XnPlayerSeekOrigin origin) = 0;
+ virtual XnStatus TellTimestamp(XnUInt64& nTimestamp) = 0;
+ virtual XnStatus TellFrame(const XnChar* strNodeName, XnUInt32& nFrame) = 0;
+ virtual XnUInt32 GetNumFrames(const XnChar* strNodeName, XnUInt32& nFrames) = 0;
+ virtual const XnChar* GetSupportedFormat() = 0;
+ virtual XnBool IsEOF() = 0;
+ virtual XnStatus RegisterToEndOfFileReached(XnModuleStateChangedHandler handler, void* pCookie, XnCallbackHandle& hCallback) = 0;
+ virtual void UnregisterFromEndOfFileReached(XnCallbackHandle hCallback) = 0;
+ };
+
+ class ModuleCroppingInterface
+ {
+ public:
+ virtual ~ModuleCroppingInterface() {}
+ virtual XnStatus SetCropping(const XnCropping &Cropping) = 0;
+ virtual XnStatus GetCropping(XnCropping &Cropping) = 0;
+ virtual XnStatus RegisterToCroppingChange(XnModuleStateChangedHandler handler, void* pCookie, XnCallbackHandle& hCallback) = 0;
+ virtual void UnregisterFromCroppingChange(XnCallbackHandle hCallback) = 0;
+ };
+
+ class ModuleAntiFlickerInterface
+ {
+ public:
+ virtual ~ModuleAntiFlickerInterface() {}
+ virtual XnStatus SetPowerLineFrequency(XnPowerLineFrequency nFrequency) = 0;
+ virtual XnPowerLineFrequency GetPowerLineFrequency() = 0;
+ virtual XnStatus RegisterToPowerLineFrequencyChange(XnModuleStateChangedHandler handler, void* pCookie, XnCallbackHandle& hCallback) = 0;
+ virtual void UnregisterFromPowerLineFrequencyChange(XnCallbackHandle hCallback) = 0;
+ };
+
+ class ModuleMapGenerator : virtual public ModuleGenerator
+ {
+ public:
+#ifdef XN_NO_DYNAMIC_CAST
+ ModuleMapGenerator() { m_aInterfaces[XN_NODE_TYPE_MAP_GENERATOR] = this; }
+#endif
+ virtual ~ModuleMapGenerator() {}
+ virtual XnUInt32 GetSupportedMapOutputModesCount() = 0;
+ virtual XnStatus GetSupportedMapOutputModes(XnMapOutputMode aModes[], XnUInt32& nCount) = 0;
+ virtual XnStatus SetMapOutputMode(const XnMapOutputMode& Mode) = 0;
+ virtual XnStatus GetMapOutputMode(XnMapOutputMode& Mode) = 0;
+ virtual XnStatus RegisterToMapOutputModeChange(XnModuleStateChangedHandler handler, void* pCookie, XnCallbackHandle& hCallback) = 0;
+ virtual void UnregisterFromMapOutputModeChange(XnCallbackHandle hCallback) = 0;
+ virtual XnUInt32 GetBytesPerPixel() = 0;
+ virtual ModuleCroppingInterface* GetCroppingInterface() { return NULL; }
+ virtual ModuleAntiFlickerInterface* GetAntiFlickerInterface() { return NULL; }
+ };
+
+ class ModuleUserPositionInterface
+ {
+ public:
+ virtual ~ModuleUserPositionInterface() {}
+ virtual XnUInt32 GetSupportedUserPositionsCount() = 0;
+ virtual XnStatus SetUserPosition(XnUInt32 nIndex, const XnBoundingBox3D& Position) = 0;
+ virtual XnStatus GetUserPosition(XnUInt32 nIndex, XnBoundingBox3D& Position) = 0;
+ virtual XnStatus RegisterToUserPositionChange(XnModuleStateChangedHandler handler, void* pCookie, XnCallbackHandle& hCallback) = 0;
+ virtual void UnregisterFromUserPositionChange(XnCallbackHandle hCallback) = 0;
+ };
+
+ class ModuleDepthGenerator : virtual public ModuleMapGenerator
+ {
+ public:
+#ifdef XN_NO_DYNAMIC_CAST
+ ModuleDepthGenerator() { m_aInterfaces[XN_NODE_TYPE_DEPTH] = this; }
+#endif
+ virtual ~ModuleDepthGenerator() {}
+ virtual const void* GetData() { return GetDepthMap(); }
+ virtual XnUInt32 GetBytesPerPixel() { return sizeof(XnDepthPixel); }
+ virtual XnDepthPixel* GetDepthMap() = 0;
+ virtual XnDepthPixel GetDeviceMaxDepth() = 0;
+ virtual void GetFieldOfView(XnFieldOfView& FOV) = 0;
+ virtual XnStatus RegisterToFieldOfViewChange(XnModuleStateChangedHandler handler, void* pCookie, XnCallbackHandle& hCallback) = 0;
+ virtual void UnregisterFromFieldOfViewChange(XnCallbackHandle hCallback) = 0;
+ virtual ModuleUserPositionInterface* GetUserPositionInterface() { return NULL; }
+ };
+
+ class ModuleImageGenerator : virtual public ModuleMapGenerator
+ {
+ public:
+#ifdef XN_NO_DYNAMIC_CAST
+ ModuleImageGenerator() { m_aInterfaces[XN_NODE_TYPE_IMAGE] = this; }
+#endif
+ virtual ~ModuleImageGenerator() {}
+ virtual const void* GetData() { return GetImageMap(); }
+ virtual XnUInt32 GetBytesPerPixel() { return xnGetBytesPerPixelForPixelFormat(GetPixelFormat()); }
+ virtual XnUInt8* GetImageMap() = 0;
+ virtual XnBool IsPixelFormatSupported(XnPixelFormat Format) = 0;
+ virtual XnStatus SetPixelFormat(XnPixelFormat Format) = 0;
+ virtual XnPixelFormat GetPixelFormat() = 0;
+ virtual XnStatus RegisterToPixelFormatChange(XnModuleStateChangedHandler handler, void* pCookie, XnCallbackHandle& hCallback) = 0;
+ virtual void UnregisterFromPixelFormatChange(XnCallbackHandle hCallback) = 0;
+ };
+
+ class ModuleIRGenerator : virtual public ModuleMapGenerator
+ {
+ public:
+#ifdef XN_NO_DYNAMIC_CAST
+ ModuleIRGenerator() { m_aInterfaces[XN_NODE_TYPE_IR] = this; }
+#endif
+ virtual ~ModuleIRGenerator() {}
+ virtual const void* GetData() { return GetIRMap(); }
+ virtual XnUInt32 GetBytesPerPixel() { return sizeof(XnIRPixel); }
+ virtual XnIRPixel* GetIRMap() = 0;
+ };
+
+ class ModuleGestureGenerator : virtual public ModuleGenerator
+ {
+ public:
+#ifdef XN_NO_DYNAMIC_CAST
+ ModuleGestureGenerator() { m_aInterfaces[XN_NODE_TYPE_GESTURE] = this; }
+#endif
+ virtual ~ModuleGestureGenerator() {}
+ virtual const void* GetData() { return NULL; }
+ virtual XnStatus AddGesture(const XnChar* strGesture, XnBoundingBox3D* pArea) = 0;
+ virtual XnStatus RemoveGesture(const XnChar* strGesture) = 0;
+ virtual XnStatus GetActiveGestures(XnChar** pstrGestures, XnUInt16& nGestures) = 0;
+ virtual XnStatus GetAllActiveGestures(XnChar** pstrGestures, XnUInt32 nNameLength, XnUInt16& nGestures) = 0;
+ virtual XnStatus EnumerateGestures(XnChar** pstrGestures, XnUInt16& nGestures) = 0;
+ virtual XnStatus EnumerateAllGestures(XnChar** pstrGestures, XnUInt32 nNameLength, XnUInt16& nGestures) = 0;
+ virtual XnBool IsGestureAvailable(const XnChar* strGesture) = 0;
+ virtual XnBool IsGestureProgressSupported(const XnChar* strGesture) = 0;
+ virtual XnStatus RegisterGestureCallbacks(XnModuleGestureRecognized RecognizedCB, XnModuleGestureProgress ProgressCB, void* pCookie, XnCallbackHandle& hCallback) = 0;
+ virtual void UnregisterGestureCallbacks(XnCallbackHandle hCallback) = 0;
+ virtual XnStatus RegisterToGestureChange(XnModuleStateChangedHandler handler, void* pCookie, XnCallbackHandle& hCallback) = 0;
+ virtual void UnregisterFromGestureChange(XnCallbackHandle hCallback) = 0;
+
+ virtual XnStatus RegisterToGestureIntermediateStageCompleted(XnModuleGestureIntermediateStageCompleted GestureIntermediateStageCompletedCB, void* pCookie, XnCallbackHandle& hCallback) = 0;
+ virtual void UnregisterFromGestureIntermediateStageCompleted(XnCallbackHandle hCallback) = 0;
+ virtual XnStatus RegisterToGestureReadyForNextIntermediateStage(XnModuleGestureReadyForNextIntermediateStage ReadyForNextIntermediateStageCB, void* pCookie, XnCallbackHandle& hCallback) = 0;
+ virtual void UnregisterFromGestureReadyForNextIntermediateStage(XnCallbackHandle hCallback) = 0;
+ };
+
+ class ModuleSceneAnalyzer : virtual public ModuleMapGenerator
+ {
+ public:
+#ifdef XN_NO_DYNAMIC_CAST
+ ModuleSceneAnalyzer() { m_aInterfaces[XN_NODE_TYPE_SCENE] = this; }
+#endif
+ virtual ~ModuleSceneAnalyzer() {}
+ virtual const void* GetData() { return GetLabelMap(); }
+ virtual XnUInt32 GetBytesPerPixel() { return sizeof(XnLabel); }
+ virtual const XnLabel* GetLabelMap() = 0;
+ virtual XnStatus GetFloor(XnPlane3D& pPlane) = 0;
+ };
+
+ class ModuleHandTouchingFOVEdgeInterface
+ {
+ public:
+ virtual ~ModuleHandTouchingFOVEdgeInterface() {}
+ virtual XnStatus RegisterToHandTouchingFOVEdge(XnModuleHandTouchingFOVEdge TouchingFOVEdgeCB, void* pCookie, XnCallbackHandle& hCallback) = 0;
+ virtual void UnregisterFromHandTouchingFOVEdge(XnCallbackHandle hCallback) = 0;
+ };
+
+ class ModuleHandsGenerator : virtual public ModuleGenerator
+ {
+ public:
+#ifdef XN_NO_DYNAMIC_CAST
+ ModuleHandsGenerator() { m_aInterfaces[XN_NODE_TYPE_HANDS] = this; }
+#endif
+ virtual ~ModuleHandsGenerator() {}
+ virtual const void* GetData() { return NULL; }
+ virtual XnStatus RegisterHandCallbacks(XnModuleHandCreate CreateCB, XnModuleHandUpdate UpdateCB, XnModuleHandDestroy DestroyCB, void* pCookie, XnCallbackHandle& hCallback) = 0;
+ virtual void UnregisterHandCallbacks(XnCallbackHandle hCallback) = 0;
+ virtual XnStatus StopTracking(XnUserID user) = 0;
+ virtual XnStatus StopTrackingAll() = 0;
+ virtual XnStatus StartTracking(const XnPoint3D& ptPosition) = 0;
+ virtual XnStatus SetSmoothing(XnFloat fSmoothingFactor) = 0;
+
+ virtual ModuleHandTouchingFOVEdgeInterface* GetHandTouchingFOVEdgeInterface() { return NULL; }
+ };
+
+ class ModuleSkeletonInterface
+ {
+ public:
+ virtual ~ModuleSkeletonInterface() {}
+ virtual XnBool IsJointAvailable(XnSkeletonJoint eJoint) = 0;
+ virtual XnBool IsProfileAvailable(XnSkeletonProfile eProfile) = 0;
+ virtual XnStatus SetSkeletonProfile(XnSkeletonProfile eProfile) = 0;
+ virtual XnStatus SetJointActive(XnSkeletonJoint eJoint, XnBool bState) = 0;
+ virtual XnBool IsJointActive(XnSkeletonJoint eJoint) = 0;
+ virtual XnStatus RegisterToJointConfigurationChange(XnModuleStateChangedHandler handler, void* pCookie, XnCallbackHandle& hCallback) = 0;
+ virtual void UnregisterFromJointConfigurationChange(XnCallbackHandle hCallback) = 0;
+ virtual XnStatus EnumerateActiveJoints(XnSkeletonJoint* pJoints, XnUInt16& nJoints) = 0;
+ virtual XnStatus GetSkeletonJoint(XnUserID user, XnSkeletonJoint eJoint, XnSkeletonJointTransformation& jointTransformation) = 0;
+ virtual XnStatus GetSkeletonJointPosition(XnUserID user, XnSkeletonJoint eJoint, XnSkeletonJointPosition& pJointPosition) = 0;
+ virtual XnStatus GetSkeletonJointOrientation(XnUserID user, XnSkeletonJoint eJoint, XnSkeletonJointOrientation& pJointOrientation) = 0;
+ virtual XnBool IsTracking(XnUserID user) = 0;
+ virtual XnBool IsCalibrated(XnUserID user) = 0;
+ virtual XnBool IsCalibrating(XnUserID user) = 0;
+ virtual XnStatus RequestCalibration(XnUserID user, XnBool bForce) = 0;
+ virtual XnStatus AbortCalibration(XnUserID user) = 0;
+ virtual XnStatus SaveCalibrationDataToFile(XnUserID user, const XnChar* strFileName) = 0;
+ virtual XnStatus LoadCalibrationDataFromFile(XnUserID user, const XnChar* strFileName) = 0;
+ virtual XnStatus SaveCalibrationData(XnUserID user, XnUInt32 nSlot) = 0;
+ virtual XnStatus LoadCalibrationData(XnUserID user, XnUInt32 nSlot) = 0;
+ virtual XnStatus ClearCalibrationData(XnUInt32 nSlot) = 0;
+ virtual XnBool IsCalibrationData(XnUInt32 nSlot) = 0;
+ virtual XnStatus StartTracking(XnUserID user) = 0;
+ virtual XnStatus StopTracking(XnUserID user) = 0;
+ virtual XnStatus Reset(XnUserID user) = 0;
+ virtual XnBool NeedPoseForCalibration() = 0;
+ virtual XnStatus GetCalibrationPose(XnChar* strPose) = 0;
+ virtual XnStatus SetSmoothing(XnFloat fSmoothingFactor) = 0;
+ virtual XnStatus RegisterCalibrationCallbacks(XnModuleCalibrationStart CalibrationStartCB, XnModuleCalibrationEnd CalibrationEndCB, void* pCookie, XnCallbackHandle& hCallback) = 0;
+ virtual void UnregisterCalibrationCallbacks(XnCallbackHandle hCallback) = 0;
+
+ virtual XnStatus RegisterToCalibrationInProgress(XnModuleCalibrationInProgress CalibrationInProgressCB, void* pCookie, XnCallbackHandle& hCallback) = 0;
+ virtual void UnregisterFromCalibrationInProgress(XnCallbackHandle hCallback) = 0;
+ virtual XnStatus RegisterToCalibrationComplete(XnModuleCalibrationComplete CalibrationCompleteCB, void* pCookie, XnCallbackHandle& hCallback) = 0;
+ virtual void UnregisterFromCalibrationComplete(XnCallbackHandle hCallback) = 0;
+
+ virtual XnStatus RegisterToCalibrationStart(XnModuleCalibrationStart handler, void* pCookie, XnCallbackHandle& hCallback) = 0;
+ virtual void UnregisterFromCalibrationStart(XnCallbackHandle hCallback) = 0;
+ };
+
+ class ModulePoseDetectionInteface
+ {
+ public:
+ virtual ~ModulePoseDetectionInteface() {}
+
+ virtual XnUInt32 GetNumberOfPoses() = 0;
+ virtual XnStatus GetAvailablePoses(XnChar** pstrPoses, XnUInt32& nPoses) = 0;
+ virtual XnStatus GetAllAvailablePoses(XnChar** pstrPoses, XnUInt32 nNameLength, XnUInt32& nPoses) = 0;
+
+ virtual XnStatus StartPoseDetection(const XnChar* strPose, XnUserID user) = 0;
+ virtual XnStatus StopPoseDetection(XnUserID user) = 0;
+ virtual XnStatus StopSinglePoseDetection(XnUserID user, const XnChar* strPose) = 0;
+
+ virtual XnStatus RegisterToPoseDetectionCallbacks(XnModulePoseDetectionCallback StartPoseCB, XnModulePoseDetectionCallback EndPoseCB, void* pCookie, XnCallbackHandle& hCallback) = 0;
+ virtual void UnregisterFromPoseDetectionCallbacks(XnCallbackHandle hCallback) = 0;
+
+ virtual XnStatus RegisterToPoseDetectionInProgress(XnModulePoseDetectionInProgressCallback InProgressCB, void* pCookie, XnCallbackHandle& hCallback) = 0;
+ virtual void UnregisterFromPoseDetectionInProgress(XnCallbackHandle hCallback) = 0;
+
+ virtual XnStatus RegisterToPoseDetected(XnModulePoseDetectionCallback handler, void* pCookie, XnCallbackHandle& hCallback) = 0;
+ virtual XnStatus RegisterToOutOfPose(XnModulePoseDetectionCallback handler, void* pCookie, XnCallbackHandle& hCallback) = 0;
+ virtual void UnregisterFromPoseDetected(XnCallbackHandle hCallback) = 0;
+ virtual void UnregisterFromOutOfPose(XnCallbackHandle hCallback) = 0;
+ };
+
+ class ModuleUserGenerator : virtual public ModuleGenerator
+ {
+ public:
+#ifdef XN_NO_DYNAMIC_CAST
+ ModuleUserGenerator() { m_aInterfaces[XN_NODE_TYPE_USER] = this;}
+#endif
+ virtual ~ModuleUserGenerator() {}
+ virtual const void* GetData() { return NULL; }
+ virtual XnUInt16 GetNumberOfUsers() = 0;
+ virtual XnStatus GetUsers(XnUserID* pUsers, XnUInt16& nUsers) = 0;
+ virtual XnStatus GetCoM(XnUserID user, XnPoint3D& com) = 0;
+ virtual XnStatus GetUserPixels(XnUserID user, XnSceneMetaData *pScene) = 0;
+ virtual XnStatus RegisterUserCallbacks(XnModuleUserHandler NewUserCB, XnModuleUserHandler LostUserCB, void* pCookie, XnCallbackHandle& hCallback) = 0;
+ virtual void UnregisterUserCallbacks(XnCallbackHandle hCallback) = 0;
+ virtual ModuleSkeletonInterface* GetSkeletonInterface() { return NULL; }
+ virtual ModulePoseDetectionInteface* GetPoseDetectionInteface() {return NULL;}
+
+ virtual XnStatus RegisterToUserExit(XnModuleUserHandler UserExitCB, void* pCookie, XnCallbackHandle& hCallback) = 0;
+ virtual void UnregisterFromUserExit(XnCallbackHandle hCallback) = 0;
+ virtual XnStatus RegisterToUserReEnter(XnModuleUserHandler UserReEnterCB, void* pCookie, XnCallbackHandle& hCallback) = 0;
+ virtual void UnregisterFromUserReEnter(XnCallbackHandle hCallback) = 0;
+ };
+
+ class ModuleAudioGenerator : virtual public ModuleGenerator
+ {
+ public:
+#ifdef XN_NO_DYNAMIC_CAST
+ ModuleAudioGenerator() { m_aInterfaces[XN_NODE_TYPE_AUDIO] = this; }
+#endif
+ virtual ~ModuleAudioGenerator() {}
+ virtual const void* GetData() { return GetAudioBuffer(); }
+ virtual XnUChar* GetAudioBuffer() = 0;
+ virtual XnUInt32 GetSupportedWaveOutputModesCount() = 0;
+ virtual XnStatus GetSupportedWaveOutputModes(XnWaveOutputMode aSupportedModes[], XnUInt32& nCount) = 0;
+ virtual XnStatus SetWaveOutputMode(const XnWaveOutputMode& OutputMode) = 0;
+ virtual XnStatus GetWaveOutputMode(XnWaveOutputMode& OutputMode) = 0;
+ virtual XnStatus RegisterToWaveOutputModeChanges(XnModuleStateChangedHandler handler, void* pCookie, XnCallbackHandle& hCallback) = 0;
+ virtual void UnregisterFromWaveOutputModeChanges(XnCallbackHandle hCallback) = 0;
+ };
+
+ class ModuleCodec : virtual public ModuleProductionNode
+ {
+ public:
+#ifdef XN_NO_DYNAMIC_CAST
+ ModuleCodec() { m_aInterfaces[XN_NODE_TYPE_CODEC] = this; }
+#endif
+ virtual ~ModuleCodec() {}
+ virtual XnCodecID GetCodecID() const = 0;
+ virtual XnStatus Init(const ProductionNode& node) = 0;
+ virtual XnStatus CompressData(const void* pSrc, XnUInt32 nSrcSize, void* pDst, XnUInt32 nDstSize, XnUInt* pnBytesWritten) const = 0;
+ virtual XnStatus DecompressData(const void* pSrc, XnUInt32 nSrcSize, void* pDst, XnUInt32 nDstSize, XnUInt* pnBytesWritten) const = 0;
+ };
+
+ class ModuleScriptNode : virtual public ModuleProductionNode
+ {
+ public:
+#ifdef XN_NO_DYNAMIC_CAST
+ ModuleScriptNode() { m_aInterfaces[XN_NODE_TYPE_SCRIPT] = this; }
+#endif
+ virtual ~ModuleScriptNode() {}
+ virtual const XnChar* GetSupportedFormat() = 0;
+ virtual XnStatus LoadScriptFromFile(const XnChar* strFileName) = 0;
+ virtual XnStatus LoadScriptFromString(const XnChar* strScript) = 0;
+ virtual XnStatus Run(NodeInfoList& createdNodes, EnumerationErrors& errors) = 0;
+ };
+}
+
+#endif // __XN_MODULE_CPP_INTERFACE_H__
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnModuleCppRegistratration.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnModuleCppRegistratration.h
new file mode 100644
index 00000000..207edb9c
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnModuleCppRegistratration.h
@@ -0,0 +1,303 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef __XN_MODULE_CPP_REGISTRATION_H__
+#define __XN_MODULE_CPP_REGISTRATION_H__
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include "XnModuleCppInterface.h"
+#include <XnUtils.h>
+
+using namespace xn;
+
+//---------------------------------------------------------------------------
+// Internal Macros
+//---------------------------------------------------------------------------
+/** Defines module instance name. */
+#define _XN_MODULE_INST g_pTheModule
+
+#define _CONCAT(a,b) a##b
+
+inline XnModuleNodeHandle __ModuleNodeToHandle(xn::ModuleProductionNode* pNode)
+{
+ return ((XnModuleNodeHandle)pNode);
+}
+
+#define __XN_EXPORT_NODE_COMMON(ExportedClass, ExportedName, Type) \
+ /** Create a static global instance. */ \
+ static ExportedClass* ExportedName = new ExportedClass(); \
+ \
+ void XN_CALLBACK_TYPE _CONCAT(ExportedClass,GetDescription)(XnProductionNodeDescription* pDescription) \
+ { \
+ ExportedName->GetDescription(pDescription); \
+ } \
+ \
+ XnStatus XN_CALLBACK_TYPE _CONCAT(ExportedClass,EnumerateProductionTrees) \
+ (XnContext* pContext, XnNodeInfoList* pTreesList, XnEnumerationErrors* pErrors) \
+ { \
+ Context context(pContext); \
+ NodeInfoList list(pTreesList); \
+ EnumerationErrors errors(pErrors); \
+ return ExportedName->EnumerateProductionTrees(context, list, pErrors == NULL ? NULL : &errors); \
+ } \
+ \
+ XnStatus XN_CALLBACK_TYPE _CONCAT(ExportedClass,Create)(XnContext* pContext, \
+ const XnChar* strInstanceName, \
+ const XnChar* strCreationInfo, \
+ XnNodeInfoList* pNeededTrees, \
+ const XnChar* strConfigurationDir, \
+ XnModuleNodeHandle* phInstance) \
+ { \
+ xn::NodeInfoList* pNeeded = NULL; \
+ if (pNeededTrees != NULL) \
+ { \
+ pNeeded = XN_NEW(xn::NodeInfoList, pNeededTrees); \
+ } \
+ ModuleProductionNode* pNode; \
+ Context context(pContext); \
+ XnStatus nRetVal = ExportedName->Create(context, strInstanceName, strCreationInfo, \
+ pNeeded, strConfigurationDir, &pNode); \
+ if (nRetVal != XN_STATUS_OK) \
+ { \
+ XN_DELETE(pNeeded); \
+ return (nRetVal); \
+ } \
+ *phInstance = __ModuleNodeToHandle(pNode); \
+ XN_DELETE(pNeeded); \
+ return (XN_STATUS_OK); \
+ } \
+ \
+ void XN_CALLBACK_TYPE _CONCAT(ExportedClass,Destroy)(XnModuleNodeHandle hInstance) \
+ { \
+ ModuleProductionNode* pNode = (ModuleProductionNode*)hInstance; \
+ ExportedName->Destroy(pNode); \
+ } \
+ \
+ void XN_CALLBACK_TYPE _CONCAT(ExportedClass,GetExportedInterface)( \
+ XnModuleExportedProductionNodeInterface* pInterface) \
+ { \
+ pInterface->GetDescription = _CONCAT(ExportedClass,GetDescription); \
+ pInterface->EnumerateProductionTrees = _CONCAT(ExportedClass,EnumerateProductionTrees); \
+ pInterface->Create = _CONCAT(ExportedClass,Create); \
+ pInterface->Destroy = _CONCAT(ExportedClass,Destroy); \
+ pInterface->GetInterface.General = __ModuleGetGetInterfaceFunc(Type); \
+ } \
+ \
+ static XnStatus _CONCAT(ExportedClass,RegisterResult) = \
+ _XN_MODULE_INST->AddExportedNode(_CONCAT(ExportedClass,GetExportedInterface));
+
+#define _XN_EXPORT_NODE_COMMON(ExportedClass, Type) \
+ __XN_EXPORT_NODE_COMMON(ExportedClass, _g_##ExportedClass, Type)
+
+//---------------------------------------------------------------------------
+// Forward Declarations
+//---------------------------------------------------------------------------
+
+void XN_CALLBACK_TYPE __ModuleGetProductionNodeInterface(XnModuleProductionNodeInterface* pInterface);
+void XN_CALLBACK_TYPE __ModuleGetDeviceInterface(XnModuleDeviceInterface* pInterface);
+void XN_CALLBACK_TYPE __ModuleGetGeneratorInterface(XnModuleGeneratorInterface* pInterface);
+void XN_CALLBACK_TYPE __ModuleGetMapGeneratorInterface(XnModuleMapGeneratorInterface* pInterface);
+void XN_CALLBACK_TYPE __ModuleGetDepthGeneratorInterface(XnModuleDepthGeneratorInterface* pInterface);
+void XN_CALLBACK_TYPE __ModuleGetImageGeneratorInterface(XnModuleImageGeneratorInterface* pInterface);
+void XN_CALLBACK_TYPE __ModuleGetIRGeneratorInterface(XnModuleIRGeneratorInterface* pInterface);
+void XN_CALLBACK_TYPE __ModuleGetUserGeneratorInterface(XnModuleUserGeneratorInterface* pInterface);
+void XN_CALLBACK_TYPE __ModuleGetHandsGeneratorInterface(XnModuleHandsGeneratorInterface* pInterface);
+void XN_CALLBACK_TYPE __ModuleGetGestureGeneratorInterface(XnModuleGestureGeneratorInterface* pInterface);
+void XN_CALLBACK_TYPE __ModuleGetSceneAnalyzerInterface(XnModuleSceneAnalyzerInterface* pInterface);
+void XN_CALLBACK_TYPE __ModuleGetAudioGeneratorInterface(XnModuleAudioGeneratorInterface* pInterface);
+void XN_CALLBACK_TYPE __ModuleGetRecorderInterface(XnModuleRecorderInterface* pInterface);
+void XN_CALLBACK_TYPE __ModuleGetPlayerInterface(XnModulePlayerInterface* pInterface);
+void XN_CALLBACK_TYPE __ModuleGetCodecInterface(XnModuleCodecInterface* pInterface);
+void XN_CALLBACK_TYPE __ModuleGetScriptNodeInterface(XnModuleScriptNodeInterface* pInterface);
+
+//---------------------------------------------------------------------------
+// Utility Macros
+//---------------------------------------------------------------------------
+
+typedef void (XN_CALLBACK_TYPE *GetInterfaceFuncPtr)(void* pInterface);
+
+static GetInterfaceFuncPtr __ModuleGetGetInterfaceFunc(XnProductionNodeType type)
+{
+ // start with concrete type
+ if (xnIsTypeDerivedFrom(type, XN_NODE_TYPE_DEVICE))
+ return (GetInterfaceFuncPtr)__ModuleGetDeviceInterface;
+ else if (xnIsTypeDerivedFrom(type, XN_NODE_TYPE_DEPTH))
+ return (GetInterfaceFuncPtr)__ModuleGetDepthGeneratorInterface;
+ else if (xnIsTypeDerivedFrom(type, XN_NODE_TYPE_IMAGE))
+ return (GetInterfaceFuncPtr)__ModuleGetImageGeneratorInterface;
+ else if (xnIsTypeDerivedFrom(type, XN_NODE_TYPE_IR))
+ return (GetInterfaceFuncPtr)__ModuleGetIRGeneratorInterface;
+ else if (xnIsTypeDerivedFrom(type, XN_NODE_TYPE_USER))
+ return (GetInterfaceFuncPtr)__ModuleGetUserGeneratorInterface;
+ else if (xnIsTypeDerivedFrom(type, XN_NODE_TYPE_GESTURE))
+ return (GetInterfaceFuncPtr)__ModuleGetGestureGeneratorInterface;
+ else if (xnIsTypeDerivedFrom(type, XN_NODE_TYPE_SCENE))
+ return (GetInterfaceFuncPtr)__ModuleGetSceneAnalyzerInterface;
+ else if (xnIsTypeDerivedFrom(type, XN_NODE_TYPE_AUDIO))
+ return (GetInterfaceFuncPtr)__ModuleGetAudioGeneratorInterface;
+ else if (xnIsTypeDerivedFrom(type, XN_NODE_TYPE_RECORDER))
+ return (GetInterfaceFuncPtr)__ModuleGetRecorderInterface;
+ else if (xnIsTypeDerivedFrom(type, XN_NODE_TYPE_PLAYER))
+ return (GetInterfaceFuncPtr)__ModuleGetPlayerInterface;
+ else if (xnIsTypeDerivedFrom(type, XN_NODE_TYPE_HANDS))
+ return (GetInterfaceFuncPtr)__ModuleGetHandsGeneratorInterface;
+ else if (xnIsTypeDerivedFrom(type, XN_NODE_TYPE_CODEC))
+ return (GetInterfaceFuncPtr)__ModuleGetCodecInterface;
+ else if (xnIsTypeDerivedFrom(type, XN_NODE_TYPE_SCRIPT))
+ return (GetInterfaceFuncPtr)__ModuleGetScriptNodeInterface;
+ // and continue with abstract ones
+ else if (xnIsTypeDerivedFrom(type, XN_NODE_TYPE_MAP_GENERATOR))
+ return (GetInterfaceFuncPtr)__ModuleGetMapGeneratorInterface;
+ else if (xnIsTypeDerivedFrom(type, XN_NODE_TYPE_GENERATOR))
+ return (GetInterfaceFuncPtr)__ModuleGetGeneratorInterface;
+ else if (xnIsTypeDerivedFrom(type, XN_NODE_TYPE_PRODUCTION_NODE))
+ return (GetInterfaceFuncPtr)__ModuleGetProductionNodeInterface;
+
+ // unknown
+ XN_ASSERT(FALSE);
+ return NULL;
+}
+
+/** Exports an OpenNI module from the DLL. */
+#if XN_PLATFORM_SUPPORTS_DYNAMIC_LIBS
+ #define XN_EXPORT_MODULE(ModuleClass) \
+ /** Declare the static variable */ \
+ ModuleClass __moduleInstance; \
+ Module* _XN_MODULE_INST = &__moduleInstance;
+#else
+ #define XN_EXPORT_MODULE(ModuleClass) \
+ /** Declare the static variable */ \
+ static ModuleClass __moduleInstance; \
+ static Module* _XN_MODULE_INST = &__moduleInstance;
+#endif
+
+/** Exports a node from the DLL. */
+#define XN_EXPORT_NODE(ExportedClass, nodeType) \
+ _XN_EXPORT_NODE_COMMON(ExportedClass, nodeType)
+
+/** Exports a device node from the DLL. */
+#define XN_EXPORT_DEVICE(ExportedClass) \
+ _XN_EXPORT_NODE_COMMON(ExportedClass, XN_NODE_TYPE_DEVICE)
+
+/** Exports a depth generator from the DLL. */
+#define XN_EXPORT_DEPTH(ExportedClass) \
+ _XN_EXPORT_NODE_COMMON(ExportedClass, XN_NODE_TYPE_DEPTH)
+
+/** Exports an image generator from the DLL. */
+#define XN_EXPORT_IMAGE(ExportedClass) \
+ _XN_EXPORT_NODE_COMMON(ExportedClass, XN_NODE_TYPE_IMAGE)
+
+/** Exports an IR generator from the DLL. */
+#define XN_EXPORT_IR(ExportedClass) \
+ _XN_EXPORT_NODE_COMMON(ExportedClass, XN_NODE_TYPE_IR)
+
+#define XN_EXPORT_USER(ExportedClass) \
+ _XN_EXPORT_NODE_COMMON(ExportedClass, XN_NODE_TYPE_USER)
+
+#define XN_EXPORT_HANDS(ExportedClass) \
+ _XN_EXPORT_NODE_COMMON(ExportedClass, XN_NODE_TYPE_HANDS)
+
+#define XN_EXPORT_GESTURE(ExportedClass) \
+ _XN_EXPORT_NODE_COMMON(ExportedClass, XN_NODE_TYPE_GESTURE)
+
+#define XN_EXPORT_SCENE(ExportedClass) \
+ _XN_EXPORT_NODE_COMMON(ExportedClass, XN_NODE_TYPE_SCENE)
+
+/** Exports an Audio generator from the DLL. */
+#define XN_EXPORT_AUDIO(ExportedClass) \
+ _XN_EXPORT_NODE_COMMON(ExportedClass, XN_NODE_TYPE_AUDIO)
+
+/** Exports a Recorder from the DLL. */
+#define XN_EXPORT_RECORDER(ExportedClass) \
+ _XN_EXPORT_NODE_COMMON(ExportedClass, XN_NODE_TYPE_RECORDER)
+
+/** Exports a Player from the DLL. */
+#define XN_EXPORT_PLAYER(ExportedClass) \
+ _XN_EXPORT_NODE_COMMON(ExportedClass, XN_NODE_TYPE_PLAYER)
+
+#define XN_EXPORT_CODEC(ExportedClass) \
+ _XN_EXPORT_NODE_COMMON(ExportedClass, XN_NODE_TYPE_CODEC)
+
+#define XN_EXPORT_SCRIPT(ExportedClass) \
+ _XN_EXPORT_NODE_COMMON(ExportedClass, XN_NODE_TYPE_SCRIPT)
+
+//---------------------------------------------------------------------------
+// Exported C functions
+//---------------------------------------------------------------------------
+#if XN_PLATFORM_SUPPORTS_DYNAMIC_LIBS
+ #include <XnModuleCFunctions.h>
+ #define XN_MODULE_FUNC_TYPE XN_C_API_EXPORT
+ extern Module* _XN_MODULE_INST;
+#else
+ #define XN_MODULE_FUNC_TYPE static
+ static Module* _XN_MODULE_INST;
+#endif
+
+XN_MODULE_FUNC_TYPE XnStatus XN_C_DECL XN_MODULE_LOAD()
+{
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ nRetVal = _XN_MODULE_INST->Load();
+ XN_IS_STATUS_OK(nRetVal);
+
+ return (XN_STATUS_OK);
+}
+
+XN_MODULE_FUNC_TYPE void XN_C_DECL XN_MODULE_UNLOAD()
+{
+ _XN_MODULE_INST->Unload();
+}
+
+XN_MODULE_FUNC_TYPE XnUInt32 XN_C_DECL XN_MODULE_GET_EXPORTED_NODES_COUNT()
+{
+ return _XN_MODULE_INST->GetExportedNodesCount();
+}
+
+XN_MODULE_FUNC_TYPE XnStatus XN_C_DECL XN_MODULE_GET_EXPORTED_NODES_ENTRY_POINTS(XnModuleGetExportedInterfacePtr* aEntryPoints, XnUInt32 nCount)
+{
+ return _XN_MODULE_INST->GetExportedNodes(aEntryPoints, nCount);
+}
+
+XN_MODULE_FUNC_TYPE void XN_C_DECL XN_MODULE_GET_OPEN_NI_VERSION(XnVersion* pVersion)
+{
+ pVersion->nMajor = XN_MAJOR_VERSION;
+ pVersion->nMinor = XN_MINOR_VERSION;
+ pVersion->nMaintenance = XN_MAINTENANCE_VERSION;
+ pVersion->nBuild = XN_BUILD_VERSION;
+}
+
+#if !XN_PLATFORM_SUPPORTS_DYNAMIC_LIBS
+#include <XnUtils.h>
+
+static XnOpenNIModuleInterface moduleInterface =
+{
+ XN_MODULE_LOAD,
+ XN_MODULE_UNLOAD,
+ XN_MODULE_GET_EXPORTED_NODES_COUNT,
+ XN_MODULE_GET_EXPORTED_NODES_ENTRY_POINTS,
+ XN_MODULE_GET_OPEN_NI_VERSION
+};
+static XnStatus registerResult = xnRegisterModuleWithOpenNI(&moduleInterface, NULL, __FILE__);
+#endif
+
+#endif // __XN_MODULE_CPP_REGISTRATION_H__
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnModuleInterface.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnModuleInterface.h
new file mode 100644
index 00000000..a973d692
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnModuleInterface.h
@@ -0,0 +1,1351 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef __XN_MODULE_INTERFACE_H__
+#define __XN_MODULE_INTERFACE_H__
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include <XnTypes.h>
+
+//---------------------------------------------------------------------------
+// Defines
+//---------------------------------------------------------------------------
+#define XN_MODULE_LOAD xnModuleLoad
+#define XN_MODULE_UNLOAD xnModuleUnload
+#define XN_MODULE_GET_EXPORTED_NODES_COUNT xnModuleGetExportedNodesCount
+#define XN_MODULE_GET_EXPORTED_NODES_ENTRY_POINTS xnModuleGetExportedNodesEntryPoints
+#define XN_MODULE_GET_OPEN_NI_VERSION xnModuleGetOpenNIVersion
+
+//---------------------------------------------------------------------------
+// Forward Declarations
+//---------------------------------------------------------------------------
+struct XnModuleProductionNodeInterface;
+struct XnModuleDeviceInterface;
+struct XnModuleDepthGeneratorInterface;
+struct XnModuleImageGeneratorInterface;
+struct XnModuleIRGeneratorInterface;
+struct XnModuleGestureGeneratorInterface;
+struct XnModuleUserGeneratorInterface;
+struct XnModuleHandsGeneratorInterface;
+struct XnModuleSceneAnalyzerInterface;
+struct XnModuleAudioGeneratorInterface;
+struct XnModuleRecorderInterface;
+struct XnModulePlayerInterface;
+struct XnModuleGeneratorInterface;
+struct XnModuleCodecInterface;
+struct XnModuleScriptNodeInterface;
+struct XnModuleMapGeneratorInterface;
+
+//---------------------------------------------------------------------------
+// Types
+//---------------------------------------------------------------------------
+
+typedef void (XN_CALLBACK_TYPE* XnModuleGetExportedInterfacePtr)(XnModuleExportedProductionNodeInterface* pInterface);
+typedef XnStatus (XN_C_DECL* XnModuleLoadPtr)();
+typedef void (XN_C_DECL* XnModuleUnloadPtr)();
+typedef XnUInt32 (XN_C_DECL* XnModuleGetExportedNodesCountPtr)();
+typedef XnStatus (XN_C_DECL* XnModuleGetExportedNodesEntryPointsPtr)(XnModuleGetExportedInterfacePtr* aEntryPoints, XnUInt32 nCount);
+typedef void (XN_C_DECL* XnModuleGetOpenNIVersionPtr)(XnVersion* pVersion);
+
+typedef struct XnOpenNIModuleInterface
+{
+ XnModuleLoadPtr pLoadFunc;
+ XnModuleUnloadPtr pUnloadFunc;
+ XnModuleGetExportedNodesCountPtr pGetCountFunc;
+ XnModuleGetExportedNodesEntryPointsPtr pGetEntryPointsFunc;
+ XnModuleGetOpenNIVersionPtr pGetVersionFunc;
+} XnOpenNIModuleInterface;
+
+/** Prototype for state change callback function. **/
+typedef void (XN_CALLBACK_TYPE* XnModuleStateChangedHandler)(void* pCookie);
+
+// User
+typedef void (XN_CALLBACK_TYPE* XnModuleUserHandler)(XnUserID user, void* pCookie);
+
+// Hand touching FOV edge
+typedef void (XN_CALLBACK_TYPE* XnModuleHandTouchingFOVEdge)(XnUserID user, const XnPoint3D* pPosition, XnFloat fTime, XnDirection eDir, void* pCookie);
+
+// UI
+typedef void (XN_CALLBACK_TYPE* XnModuleHandCreate)(XnUserID user, const XnPoint3D* pPosition, XnFloat fTime, void* pCookie);
+typedef void (XN_CALLBACK_TYPE* XnModuleHandUpdate)(XnUserID user, const XnPoint3D* pPosition, XnFloat fTime, void* pCookie);
+typedef void (XN_CALLBACK_TYPE* XnModuleHandDestroy)(XnUserID user, XnFloat fTime, void* pCookie);
+
+// Gesture Module
+typedef void (XN_CALLBACK_TYPE* XnModuleGestureRecognized)(const XnChar* strGesture, const XnPoint3D* pIDPosition, const XnPoint3D* pEndPosition, void* pCookie);
+typedef void (XN_CALLBACK_TYPE* XnModuleGestureProgress)(const XnChar* strGesture, const XnPoint3D* pPosition, XnFloat fProgress, void* pCookie);
+typedef void (XN_CALLBACK_TYPE* XnModuleGestureIntermediateStageCompleted)(const XnChar* strGesture, const XnPoint3D* pPosition, void* pCookie);
+typedef void (XN_CALLBACK_TYPE* XnModuleGestureReadyForNextIntermediateStage)(const XnChar* strGesture, const XnPoint3D* pPosition, void* pCookie);
+
+// Skeleton
+typedef void (XN_CALLBACK_TYPE* XnModuleCalibrationStart)(XnUserID user, void* pCookie);
+typedef void (XN_CALLBACK_TYPE* XnModuleCalibrationEnd)(XnUserID user, XnBool bSuccess, void* pCookie);
+typedef void (XN_CALLBACK_TYPE* XnModuleCalibrationInProgress)(XnUserID user, XnCalibrationStatus calibrationError, void* pCookie);
+typedef void (XN_CALLBACK_TYPE* XnModuleCalibrationComplete)(XnUserID user, XnCalibrationStatus calibrationError, void* pCookie);
+
+// Pose Detection
+typedef void (XN_CALLBACK_TYPE* XnModulePoseDetectionCallback)(const XnChar* strPose, XnUserID user, void* pCookie);
+typedef void (XN_CALLBACK_TYPE* XnModulePoseDetectionInProgressCallback)(const XnChar* strPose, XnUserID user, XnPoseDetectionStatus poseError, void* pCookie);
+
+typedef struct XnModuleExportedProductionNodeInterface
+{
+ /**
+ * Gets a description of this generator.
+ *
+ * @param pDescription [in/out] A struct to be filled with the description.
+ */
+ void (XN_CALLBACK_TYPE* GetDescription)
+ (XnProductionNodeDescription* pDescription);
+
+ /**
+ * Find all tree possibilities for this production node.
+ *
+ * @param pContext [in] Current OpenNI context
+ * @param pNodesList [in] A list to be filled with production trees.
+ * @param pErrors [in] Optional. An enumeration errors object to be passed to enumeration functions.
+ */
+ XnStatus (XN_CALLBACK_TYPE* EnumerateProductionTrees)
+ (XnContext* pContext,
+ XnNodeInfoList* pNodesList,
+ XnEnumerationErrors* pErrors);
+
+ /**
+ * Creates an instance of this generator.
+ *
+ * @param pContext [in] Current OpenNI context
+ * @param strInstanceName [in] The name of this new instance.
+ * @param strCreationInfo [in] Optional creation info (returned from enumeration).
+ * @param pNeededNodes [in] A list of inputs for this generator.
+ * @param strConfigurationDir [in] The module configuration dir, or NULL if it doesn't have one.
+ * @param phInstance [out] A handle to the created instance.
+ */
+ XnStatus (XN_CALLBACK_TYPE* Create)
+ (XnContext* pContext,
+ const XnChar* strInstanceName,
+ const XnChar* strCreationInfo,
+ XnNodeInfoList* pNeededNodes,
+ const XnChar* strConfigurationDir,
+ XnModuleNodeHandle* phInstance);
+
+ /**
+ * Destroys an instance previously created using Create().
+ *
+ * @param hGenerator [in] A handle to the instance to be destroyed.
+ */
+ void (XN_CALLBACK_TYPE* Destroy)
+ (XnModuleNodeHandle hInstance);
+
+ /**
+ * Fills a struct with the entire interface exported. The type of the struct passed
+ * to this function is determined according to the type this production node declares itself.
+ * For example, a depth generator will be passed a pointer to a XnModuleDepthGeneratorInterface struct.
+ *
+ * @param pInterface [in/out] A pointer to a struct to be filled.
+ */
+ union
+ {
+ void (XN_CALLBACK_TYPE* ProductionNode)(struct XnModuleProductionNodeInterface* pInterface);
+ void (XN_CALLBACK_TYPE* Device)(struct XnModuleDeviceInterface* pInterface);
+ void (XN_CALLBACK_TYPE* Generator)(struct XnModuleGeneratorInterface* pInterface);
+ void (XN_CALLBACK_TYPE* MapGenerator)(struct XnModuleMapGeneratorInterface* pInterface);
+ void (XN_CALLBACK_TYPE* Depth)(struct XnModuleDepthGeneratorInterface* pInterface);
+ void (XN_CALLBACK_TYPE* Image)(struct XnModuleImageGeneratorInterface* pInterface);
+ void (XN_CALLBACK_TYPE* IR)(struct XnModuleIRGeneratorInterface* pInterface);
+ void (XN_CALLBACK_TYPE* User)(struct XnModuleUserGeneratorInterface* pInterface);
+ void (XN_CALLBACK_TYPE* Hands)(struct XnModuleHandsGeneratorInterface* pInterace);
+ void (XN_CALLBACK_TYPE* Gesture)(struct XnModuleGestureGeneratorInterface* pInterface);
+ void (XN_CALLBACK_TYPE* Scene)(struct XnModuleSceneAnalyzerInterface* pInterface);
+ void (XN_CALLBACK_TYPE* Audio)(struct XnModuleAudioGeneratorInterface* pInterface);
+ void (XN_CALLBACK_TYPE* Recorder)(struct XnModuleRecorderInterface* pInterface);
+ void (XN_CALLBACK_TYPE* Player)(struct XnModulePlayerInterface* pInterface);
+ void (XN_CALLBACK_TYPE* Codec)(struct XnModuleCodecInterface* pInterface);
+ void (XN_CALLBACK_TYPE* Script)(struct XnModuleScriptNodeInterface* pInterface);
+
+ void (XN_CALLBACK_TYPE* General)(void* pInterface);
+ } GetInterface;
+
+} XnModuleExportedProductionNodeInterface;
+
+typedef struct XnModuleExtendedSerializationInterface
+{
+ XnStatus (XN_CALLBACK_TYPE* InitNotifications)(XnModuleNodeHandle hInstance, XnNodeNotifications* pNotifications, void* pCookie);
+ void (XN_CALLBACK_TYPE* StopNotifications)(XnModuleNodeHandle hInstance);
+
+} XnModuleExtendedSerializationInterface;
+
+typedef struct XnModuleLockAwareInterface
+{
+ /**
+ * Notifies the node its lock state was changed.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param bLocked [in] Current lock state.
+ */
+ XnStatus (XN_CALLBACK_TYPE* SetLockState)(XnModuleNodeHandle hInstance, XnBool bLocked);
+
+ /**
+ * Gets current lock state.
+ *
+ * @param hInstance [in] A handle to the instance.
+ */
+ XnBool (XN_CALLBACK_TYPE* GetLockState)(XnModuleNodeHandle hInstance);
+
+ /**
+ * Registers a callback function to lock changes.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param handler [in] A pointer to a function that will be called when lock changes.
+ * @param pCookie [in] A user cookie that will be passed to the callback function.
+ * @param phCallback [out] Optional. Will be filled with a handle to be passed to @ref UnregisterFromLockChange().
+ */
+ XnStatus (XN_CALLBACK_TYPE* RegisterToLockChange)
+ (XnModuleNodeHandle hInstance, XnModuleStateChangedHandler handler,
+ void* pCookie, XnCallbackHandle* phCallback);
+
+ /**
+ * Unregisters a callback function which was registered using @ref RegisterToLockChange().
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param hCallback [in] The handle to the callback returned from @ref RegisterToLockChange().
+ */
+ void (XN_CALLBACK_TYPE* UnregisterFromLockChange)
+ (XnModuleNodeHandle hInstance, XnCallbackHandle hCallback);
+
+} XnModuleLockAwareInterface;
+
+typedef struct XnModuleErrorStateInterface
+{
+ /**
+ * Gets current error state of this node.
+ *
+ * @param hInstance [in] A handle to the instance.
+ */
+ XnStatus (XN_CALLBACK_TYPE* GetErrorState)(XnModuleNodeHandle hInstance);
+
+ /**
+ * Registers a callback function to error state changes.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param handler [in] A pointer to a function that will be called when lock changes.
+ * @param pCookie [in] A user cookie that will be passed to the callback function.
+ * @param phCallback [out] Optional. Will be filled with a handle to be passed to @ref UnregisterFromErrorStateChange().
+ */
+ XnStatus (XN_CALLBACK_TYPE* RegisterToErrorStateChange)
+ (XnModuleNodeHandle hInstance, XnModuleStateChangedHandler handler,
+ void* pCookie, XnCallbackHandle* phCallback);
+
+ /**
+ * Unregisters a callback function which was registered using @ref RegisterToErrorStateChange().
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param hCallback [in] The handle to the callback returned from @ref RegisterToErrorStateChange().
+ */
+ void (XN_CALLBACK_TYPE* UnregisterFromErrorStateChange)
+ (XnModuleNodeHandle hInstance, XnCallbackHandle hCallback);
+
+} XnModuleErrorStateInterface;
+
+typedef struct XnModuleGeneralIntInterface
+{
+ /**
+ * Gets the range of this capability values
+ *
+ * @param hGenerator [in] A handle to the instance
+ * @param strCap [in] Name of the capability
+ * @param pnMin [out] Minimum value
+ * @param pnMax [out] Maximum value
+ * @param pnStep [out] Step size
+ * @param pnDefault [out] Default value
+ * @param pbIsAutoSupported [out] TRUE if auto adjustment is supported, FALSE otherwise
+ */
+ XnStatus (XN_CALLBACK_TYPE* GetRange)(XnModuleNodeHandle hGenerator, const XnChar* strCap, XnInt32* pnMin, XnInt32* pnMax, XnInt32* pnStep, XnInt32* pnDefault, XnBool* pbIsAutoSupported);
+
+ /**
+ * Gets the current value of this capability
+ *
+ * @param hGenerator [in] A handle to the instance
+ * @param strCap [in] Name of the capability
+ * @param pnValue [out] Current value
+ */
+ XnStatus (XN_CALLBACK_TYPE* Get)(XnModuleNodeHandle hGenerator, const XnChar* strCap, XnInt32* pnValue);
+
+ /**
+ * Sets the current value of this capability
+ *
+ * @param hGenerator [in] A handle to the instance
+ * @param strCap [in] Name of the capability
+ * @param nValue [in] Value to set
+ */
+ XnStatus (XN_CALLBACK_TYPE* Set)(XnModuleNodeHandle hGenerator, const XnChar* strCap, XnInt32 nValue);
+
+ /**
+ * Registers a callback function to values changes.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param strCap [in] Name of the capability
+ * @param handler [in] A pointer to a function that will be called when value changes.
+ * @param pCookie [in] A user cookie that will be passed to the callback function.
+ * @param phCallback [out] Optional. Will be filled with a handle to be passed to @ref UnregisterFromValueChange().
+ */
+ XnStatus (XN_CALLBACK_TYPE* RegisterToValueChange)
+ (XnModuleNodeHandle hGenerator, const XnChar* strCap, XnModuleStateChangedHandler handler,
+ void* pCookie, XnCallbackHandle* phCallback);
+
+ /**
+ * Unregisters a callback function which was registered using @ref RegisterToValueChange().
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param strCap [in] Name of the capability
+ * @param hCallback [in] The handle to the callback returned from @ref RegisterToValueChange().
+ */
+ void (XN_CALLBACK_TYPE* UnregisterFromValueChange)
+ (XnModuleNodeHandle hGenerator, const XnChar* strCap, XnCallbackHandle hCallback);
+
+} XnModuleGeneralIntInterface;
+
+typedef struct XnModuleProductionNodeInterface
+{
+ /**
+ * Checks if the specified capability is supported.
+ *
+ * @param hInstance [in] A handle to the instance to be queried.
+ * @param strCapabilityName [in] The name of the capability to check.
+ */
+ XnBool (XN_CALLBACK_TYPE* IsCapabilitySupported)(
+ XnModuleNodeHandle hInstance,
+ const XnChar* strCapabilityName
+ );
+
+ /**
+ * [Optional] Sets a property.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param strName [in] Property name
+ * @param nValue [in] New value
+ */
+ XnStatus (XN_CALLBACK_TYPE* SetIntProperty)(XnModuleNodeHandle hInstance, const XnChar* strName, XnUInt64 nValue);
+ XnStatus (XN_CALLBACK_TYPE* SetRealProperty)(XnModuleNodeHandle hInstance, const XnChar* strName, XnDouble dValue);
+ XnStatus (XN_CALLBACK_TYPE* SetStringProperty)(XnModuleNodeHandle hInstance, const XnChar* strName, const XnChar* strValue);
+ XnStatus (XN_CALLBACK_TYPE* SetGeneralProperty)(XnModuleNodeHandle hInstance, const XnChar* strName, XnUInt32 nBufferSize, const void* pBuffer);
+
+ /**
+ * [Optional] Gets a property.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param strName [in] Property name
+ * @param pnValue [out] Current value
+ */
+ XnStatus (XN_CALLBACK_TYPE* GetIntProperty)(XnModuleNodeHandle hInstance, const XnChar* strName, XnUInt64* pnValue);
+ XnStatus (XN_CALLBACK_TYPE* GetRealProperty)(XnModuleNodeHandle hInstance, const XnChar* strName, XnDouble* pdValue);
+ XnStatus (XN_CALLBACK_TYPE* GetStringProperty)(XnModuleNodeHandle hInstance, const XnChar* strName, XnChar* csValue, XnUInt32 nBufSize);
+ XnStatus (XN_CALLBACK_TYPE* GetGeneralProperty)(XnModuleNodeHandle hInstance, const XnChar* strName, XnUInt32 nBufferSize, void* pBuffer);
+
+ XnModuleExtendedSerializationInterface* pExtendedSerializationInterface;
+ XnModuleLockAwareInterface* pLockAwareInterface;
+ XnModuleErrorStateInterface* pErrorStateInterface;
+ XnModuleGeneralIntInterface* pGeneralIntInterface;
+
+} XnModuleProductionNodeInterface;
+
+typedef struct XnModuleDeviceIdentificationInterface
+{
+ /**
+ * Gets the device name.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param strBuffer [in] A buffer to accept the device name.
+ * @param pnBufferSize [in/out] Size of the buffer.
+ *
+ * @returns XN_STATUS_OK if succeeded, or XN_STATUS_OUTPUT_BUFFER_OVERFLOW if buffer is not sufficient.
+ * in such a case, the device name should be truncated to fit in the buffer, and pnBufferSize should be
+ * updated to the required size.
+ */
+ XnStatus (XN_CALLBACK_TYPE* GetDeviceName)(XnModuleNodeHandle hInstance, XnChar* strBuffer, XnUInt32* pnBufferSize);
+
+ /**
+ * Gets a vendor-specific string.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param strBuffer [in] A buffer to accept the string.
+ * @param pnBufferSize [in/out] Size of the buffer.
+ *
+ * @returns XN_STATUS_OK if succeeded, or XN_STATUS_OUTPUT_BUFFER_OVERFLOW if buffer is not sufficient.
+ * in such a case, the string should be truncated to fit in the buffer, and pnBufferSize should be
+ * updated to the required size.
+ */
+ XnStatus (XN_CALLBACK_TYPE* GetVendorSpecificData)(XnModuleNodeHandle hInstance, XnChar* strBuffer, XnUInt32* pnBufferSize);
+
+ /**
+ * Gets the serial number of the device.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param strBuffer [in] A buffer to accept the string.
+ * @param pnBufferSize [in/out] Size of the buffer.
+ *
+ * @returns XN_STATUS_OK if succeeded, or XN_STATUS_OUTPUT_BUFFER_OVERFLOW if buffer is not sufficient.
+ * in such a case, the string should be truncated to fit in the buffer, and pnBufferSize should be
+ * updated to the required size.
+ */
+ XnStatus (XN_CALLBACK_TYPE* GetSerialNumber)(XnModuleNodeHandle hInstance, XnChar* strBuffer, XnUInt32* pnBufferSize);
+
+} XnModuleDeviceIdentificationInterface;
+
+typedef struct XnModuleDeviceInterface
+{
+ XnModuleProductionNodeInterface* pProductionNode;
+
+ XnModuleDeviceIdentificationInterface* pDeviceIdentificationInterface;
+
+} XnModuleDeviceInterface;
+
+typedef struct XnModuleMirrorInterface
+{
+ /**
+ * Sets current mirror configuration.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param bMirror [in] TRUE for mirroring output, FALSE otherwise.
+ */
+ XnStatus (XN_CALLBACK_TYPE* SetMirror)(XnModuleNodeHandle hInstance, XnBool bMirror);
+
+ /**
+ * Gets current mirroring configuration.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ */
+ XnBool (XN_CALLBACK_TYPE* IsMirrored)(XnModuleNodeHandle hInstance);
+
+ /**
+ * Registers a callback function to mirror changes.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param handler [in] A pointer to a function that will be called when mirror changes.
+ * @param pCookie [in] A user cookie that will be passed to the callback function.
+ * @param phCallback [out] Optional. Will be filled with a handle to be passed to @ref UnregisterFromMirrorChange().
+ */
+ XnStatus (XN_CALLBACK_TYPE* RegisterToMirrorChange)
+ (XnModuleNodeHandle hGenerator, XnModuleStateChangedHandler handler,
+ void* pCookie, XnCallbackHandle* phCallback);
+
+ /**
+ * Unregisters a callback function which was registered using @ref RegisterToMirrorChange().
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param hCallback [in] The handle to the callback returned from @ref RegisterToMirrorChange().
+ */
+ void (XN_CALLBACK_TYPE* UnregisterFromMirrorChange)
+ (XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback);
+
+} XnModuleMirrorInterface;
+
+typedef struct XnModuleAlternativeViewPointInterface
+{
+ /**
+ * Checks if this generator can change its output to look like as if it was taken from
+ * a different location, represented by another generator.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param hOther [in] The view point to be checked.
+ *
+ * @return TRUE if view point is supported, FALSE otherwise.
+ */
+ XnBool (XN_CALLBACK_TYPE* IsViewPointSupported)(XnModuleNodeHandle hGenerator, XnNodeHandle hOther);
+
+ /**
+ * Sets the view point of this generator to look like as if placed at another generator location.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param hOther [in] The view point to be set.
+ */
+ XnStatus (XN_CALLBACK_TYPE* SetViewPoint)(XnModuleNodeHandle hGenerator, XnNodeHandle hOther);
+
+ /**
+ * Checks if current view point is as if coming from the other node view point.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param hOther [in] The view point to be checked.
+ */
+ XnBool (XN_CALLBACK_TYPE* IsViewPointAs)(XnModuleNodeHandle hGenerator, XnNodeHandle hOther);
+
+ /**
+ * Sets the view point of this generator to its normal one.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ */
+ XnStatus (XN_CALLBACK_TYPE* ResetViewPoint)(XnModuleNodeHandle hGenerator);
+
+ /**
+ * Registers a callback function to view point changes.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param handler [in] A pointer to a function that will be called when view point changes.
+ * @param pCookie [in] A user cookie that will be passed to the callback function.
+ * @param phCallback [out] Optional. Will be filled with a handle to be passed to @ref UnregisterFromViewPointChange().
+ */
+ XnStatus (XN_CALLBACK_TYPE* RegisterToViewPointChange)(XnModuleNodeHandle hGenerator, XnModuleStateChangedHandler handler, void* pCookie, XnCallbackHandle* phCallback);
+
+ /**
+ * Unregisters a callback function which was registered using @ref RegisterToViewPointChange().
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param hCallback [in] The handle to the callback returned from @ref RegisterToViewPointChange().
+ */
+ void (XN_CALLBACK_TYPE* UnregisterFromViewPointChange)(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback);
+
+} XnModuleAlternativeViewPointInterface;
+
+typedef struct XnModuleFrameSyncInterface
+{
+ /**
+ * Checks if this generator can frame sync with another generator.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param hOther [in] The node to be checked.
+ *
+ * @returns TRUE if frame sync is supported, FALSE otherwise.
+ */
+ XnBool (XN_CALLBACK_TYPE* CanFrameSyncWith)(XnModuleNodeHandle hGenerator, XnNodeHandle hOther);
+
+ /**
+ * Activates frame sync with another node
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param hOther [in] The node to sync with.
+ */
+ XnStatus (XN_CALLBACK_TYPE* FrameSyncWith)(XnModuleNodeHandle hGenerator, XnNodeHandle hOther);
+
+ /**
+ * Stops frame sync with another node.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param hOther [in] The node to stop sync with.
+ */
+ XnStatus (XN_CALLBACK_TYPE* StopFrameSyncWith)(XnModuleNodeHandle hGenerator, XnNodeHandle hOther);
+
+ /**
+ * Checks if frame synced with other node.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param hOther [in] The node to be checked.
+ */
+ XnBool (XN_CALLBACK_TYPE* IsFrameSyncedWith)(XnModuleNodeHandle hGenerator, XnNodeHandle hOther);
+
+ /**
+ * Registers a callback function to frame sync changes.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param handler [in] A pointer to a function that will be called when frame sync changes.
+ * @param pCookie [in] A user cookie that will be passed to the callback function.
+ * @param phCallback [out] Optional. Will be filled with a handle to be passed to @ref UnregisterFromFrameSyncChange().
+ */
+ XnStatus (XN_CALLBACK_TYPE* RegisterToFrameSyncChange)(XnModuleNodeHandle hGenerator, XnModuleStateChangedHandler handler, void* pCookie, XnCallbackHandle* phCallback);
+
+ /**
+ * Unregisters a callback function which was registered using @ref RegisterToFrameSyncChange().
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param hCallback [in] The handle to the callback returned from @ref RegisterToFrameSyncChange().
+ */
+ void (XN_CALLBACK_TYPE* UnregisterFromFrameSyncChange)(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback);
+
+} XnModuleFrameSyncInterface;
+
+/** The interface of a generator. */
+typedef struct XnModuleGeneratorInterface
+{
+ /**
+ * Contains production node interface.
+ */
+ XnModuleProductionNodeInterface* pProductionNodeInterface;
+
+ /**
+ * Starts generation of the output.
+ *
+ * @param hGenerator [in] A handle to the instance to start generating.
+ */
+ XnStatus (XN_CALLBACK_TYPE* StartGenerating)
+ (XnModuleNodeHandle hGenerator);
+
+ /**
+ * Checks if the generator is currently generating.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ */
+ XnBool (XN_CALLBACK_TYPE* IsGenerating)
+ (XnModuleNodeHandle hGenerator);
+
+ /**
+ * Stops generation of the output.
+ *
+ * @param hGenerator [in] A handle to the instance to stop generating.
+ */
+ void (XN_CALLBACK_TYPE* StopGenerating)
+ (XnModuleNodeHandle hGenerator);
+
+ /**
+ * Registers a callback function to be called when generation starts or stops.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param handler [in] A pointer to a function that will be called when generation starts/stops.
+ * @param pCookie [in] A user cookie that will be passed to the callback function.
+ * @param phCallback [out] Optional. Will be filled with a handle to be passed to @ref UnregisterFromGenerationRunningChange().
+ */
+ XnStatus (XN_CALLBACK_TYPE* RegisterToGenerationRunningChange)
+ (XnModuleNodeHandle hGenerator, XnModuleStateChangedHandler handler,
+ void* pCookie, XnCallbackHandle* phCallback);
+
+ /**
+ * Unregisters a callback function which was registered using @ref RegisterToGenerationRunningChange().
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param hCallback [in] The handle to the callback returned from @ref RegisterToGenerationRunningChange().
+ */
+ void (XN_CALLBACK_TYPE* UnregisterFromGenerationRunningChange)
+ (XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback);
+
+ /**
+ * Registers a callback function to be called when new data is available.
+ *
+ * @param handler [in] A pointer to a function that will be called when new data is available.
+ * @param pCookie [in] A user cookie that will be passed to the callback function.
+ * @param phCallback [out] Optional. Will be filled with a handle to be passed to @ref UnregisterFromNewDataAvailable().
+ */
+ XnStatus (XN_CALLBACK_TYPE* RegisterToNewDataAvailable)
+ (XnModuleNodeHandle hGenerator, XnModuleStateChangedHandler handler,
+ void* pCookie, XnCallbackHandle* phCallback);
+
+ /**
+ * Unregisters a callback function which was registered using @ref RegisterToNewDataAvailable().
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param hCallback [in] The handle to the callback returned from @ref RegisterToNewDataAvailable().
+ */
+ void (XN_CALLBACK_TYPE* UnregisterFromNewDataAvailable)
+ (XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback);
+
+ /**
+ * Checks whether this node has new data (and so a call to @ref xn::Generator::WaitAndUpdateData() will not block).
+ *
+ * @param hGenerator [in] A handle to the instance to be updated.
+ * @param pnTimestamp [out] If new data is available, the timestamp of that data.
+ */
+ XnBool (XN_CALLBACK_TYPE* IsNewDataAvailable)
+ (XnModuleNodeHandle hGenerator, XnUInt64* pnTimestamp);
+
+ /**
+ * Updates the data to the latest available one. This function will only be called AFTER the node
+ * notified OpenNI it has new data available.
+ *
+ * @param hGenerator [in] A handle to the instance to be updated.
+ */
+ XnStatus (XN_CALLBACK_TYPE* UpdateData)
+ (XnModuleNodeHandle hGenerator);
+
+ /**
+ * Gets the size of current data, in bytes.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ */
+ XnUInt32 (XN_CALLBACK_TYPE* GetDataSize)(XnModuleNodeHandle hGenerator);
+
+ /**
+ * Gets the timestamp of current data, in microseconds.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ */
+ XnUInt64 (XN_CALLBACK_TYPE* GetTimestamp)(XnModuleNodeHandle hGenerator);
+
+ /**
+ * Gets the frame ID of current data.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ */
+ XnUInt32 (XN_CALLBACK_TYPE* GetFrameID)(XnModuleNodeHandle hGenerator);
+
+ XnModuleMirrorInterface* pMirrorInterface;
+ XnModuleAlternativeViewPointInterface* pAlternativeViewPointInterface;
+ void* pObsolete1; // used to be pSeekingInterface (removed in 1.0.0.28)
+ XnModuleFrameSyncInterface* pFrameSyncInterface;
+
+ //Note: The GetData() function was added in version 1.0.0.28
+ /**
+ * Gets pointer to current data.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ */
+ const void* (XN_CALLBACK_TYPE* GetData)(XnModuleNodeHandle hGenerator);
+
+} XnModuleGeneratorInterface;
+
+typedef struct XnModuleRecorderInterface
+{
+ /*
+ * Sets the output stream for the recorder module.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param pStreamToken [in] A token that the recorder module must save for passing to later stream calls.
+ * @param pStream [in] The stream interface the recorder module must save for later stream calls.
+ */
+ XnStatus (XN_CALLBACK_TYPE* SetOutputStream)
+ (XnModuleNodeHandle hInstance, void *pStreamToken, XnRecorderOutputStreamInterface *pStream);
+
+ XnModuleProductionNodeInterface* pProductionNode;
+ XnNodeNotifications* pNodeNotifications;
+} XnModuleRecorderInterface;
+
+typedef struct XnModulePlayerInterface
+{
+ /*
+ * Sets the input stream for the player module
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param pStreamCookie [in] A cookie that the player module must save for passing to later stream calls.
+ * @param pStream [in] The stream interface the player module must save for later stream calls.
+ */
+ XnStatus (XN_CALLBACK_TYPE* SetInputStream)
+ (XnModuleNodeHandle hInstance, void *pStreamCookie, XnPlayerInputStreamInterface *pStream);
+
+ /**
+ * Reads next data from the input stream.
+ *
+ * @param hInstance [in] A handle to the instance.
+ */
+ XnStatus (XN_CALLBACK_TYPE* ReadNext)(XnModuleNodeHandle hInstance);
+
+ /*
+ * Sets the node notifications object to be used by the player. The player will use this object to
+ * notify about events it encounters in the stream that was set with @ref SetInputStream().
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param pNodeNotificationsCookie [in] A cookie that the player module must save for passing to node notification calls.
+ * @param pNodeNotifications [in] The node notifications interface that the player module will use to raise node notifications it finds in the stream.
+ */
+ XnStatus (XN_CALLBACK_TYPE* SetNodeNotifications)
+ (XnModuleNodeHandle hInstance, void *pNodeNotificationsCookie, XnNodeNotifications *pNodeNotifications);
+
+ XnStatus (XN_CALLBACK_TYPE* SetRawNodeNotifications)
+ (XnModuleNodeHandle hInstance, void *pRawNodeNotificationsCookie, XnNodeNotifications *pRawNodeNotifications);
+
+
+ /*
+ * Determines whether the player repeats the played stream or not.
+ *
+ * @param bRepeat [in] If TRUE, repeat is set to be ON. If FALSE, repeat is set to be OFF.
+ */
+ XnStatus (XN_CALLBACK_TYPE* SetRepeat)
+ (XnModuleNodeHandle hInstance, XnBool bRepeat);
+
+ XnStatus (XN_CALLBACK_TYPE* SeekToTimeStamp)
+ (XnModuleNodeHandle hInstance, XnInt64 nTimeOffset, XnPlayerSeekOrigin origin);
+
+ XnStatus (XN_CALLBACK_TYPE* SeekToFrame)
+ (XnModuleNodeHandle hInstance, const XnChar* strNodeName, XnInt32 nFrameOffset, XnPlayerSeekOrigin origin);
+
+ XnStatus (XN_CALLBACK_TYPE* TellTimestamp)
+ (XnModuleNodeHandle hInstance, XnUInt64* pnTimestamp);
+
+ XnStatus (XN_CALLBACK_TYPE* TellFrame)
+ (XnModuleNodeHandle hInstance, const XnChar* strNodeName, XnUInt32* pnFrame);
+
+ XnStatus (XN_CALLBACK_TYPE* GetNumFrames)
+ (XnModuleNodeHandle hInstance, const XnChar* strNodeName, XnUInt32* pnFrames);
+
+ const XnChar* (XN_CALLBACK_TYPE* GetSupportedFormat)
+ (XnModuleNodeHandle hInstance);
+
+ XnBool (XN_CALLBACK_TYPE* IsEOF)
+ (XnModuleNodeHandle hInstance);
+
+ /**
+ * Registers a callback function to be called when end-of-file was reached.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param handler [in] A pointer to a function to be called.
+ * @param pCookie [in] A user cookie that will be passed to the callback function.
+ * @param phCallback [out] Optional. Will be filled with a handle to be passed to UnregisterFromEndOfFileReached().
+ */
+ XnStatus (XN_CALLBACK_TYPE* RegisterToEndOfFileReached)
+ (XnModuleNodeHandle hGenerator, XnModuleStateChangedHandler handler,
+ void* pCookie, XnCallbackHandle* phCallback);
+
+ /**
+ * Unregisters a callback function which was registered using RegisterToEndOfFileReached().
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param hCallback [in] The handle to the callback returned from RegisterToEndOfFileReached().
+ */
+ void (XN_CALLBACK_TYPE* UnregisterFromEndOfFileReached)
+ (XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback);
+
+ XnModuleProductionNodeInterface* pProductionNode;
+ void* pObsolete1; // used to be pSeekingInterface (removed in 1.0.0.28)
+
+} XnModulePlayerInterface;
+
+typedef struct XnModuleCroppingInterface
+{
+ /**
+ * Sets the cropping.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param pCropping [in] The cropping configuration to be set.
+ */
+ XnStatus (XN_CALLBACK_TYPE* SetCropping)(XnModuleNodeHandle hGenerator, const XnCropping* pCropping);
+
+ /**
+ * Gets current cropping configuration.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param pCropping [out] Current cropping configuration.
+ */
+ XnStatus (XN_CALLBACK_TYPE* GetCropping)(XnModuleNodeHandle hGenerator, XnCropping* pCropping);
+
+ /**
+ * Registers a callback function to cropping changes.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param handler [in] A pointer to a function that will be called when cropping changes.
+ * @param pCookie [in] A user cookie that will be passed to the callback function.
+ * @param phCallback [out] Optional. Will be filled with a handle to be passed to UnregisterFromCroppingChange().
+ */
+ XnStatus (XN_CALLBACK_TYPE* RegisterToCroppingChange)
+ (XnModuleNodeHandle hGenerator, XnModuleStateChangedHandler handler,
+ void* pCookie, XnCallbackHandle* phCallback);
+
+ /**
+ * Unregisters a callback function which was registered using RegisterToCroppingChange().
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param hCallback [in] The handle to the callback returned from RegisterToCroppingChange().
+ */
+ void (XN_CALLBACK_TYPE* UnregisterFromCroppingChange)
+ (XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback);
+
+} XnModuleCroppingInterface;
+
+typedef struct XnModuleAntiFlickerInterface
+{
+ /**
+ * Sets the power line frequency: 50 Hz, 60 Hz, or 0 to turn off anti-flicker.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param nFrequency [in] The frequency to be used.
+ */
+ XnStatus (XN_CALLBACK_TYPE* SetPowerLineFrequency)(XnModuleNodeHandle hGenerator, XnPowerLineFrequency nFrequency);
+
+ /**
+ * Gets the power line frequency.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ */
+ XnPowerLineFrequency (XN_CALLBACK_TYPE* GetPowerLineFrequency)(XnModuleNodeHandle hGenerator);
+
+ /**
+ * Registers a callback function to power line frequency changes.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param handler [in] A pointer to a function that will be called when power line frequency changes.
+ * @param pCookie [in] A user cookie that will be passed to the callback function.
+ * @param phCallback [out] Optional. Will be filled with a handle to be passed to @ref UnregisterFromPowerLineFrequencyChange().
+ */
+ XnStatus (XN_CALLBACK_TYPE* RegisterToPowerLineFrequencyChange)
+ (XnModuleNodeHandle hGenerator, XnModuleStateChangedHandler handler,
+ void* pCookie, XnCallbackHandle* phCallback);
+
+ /**
+ * Unregisters a callback function which was registered using @ref RegisterToPowerLineFrequencyChange().
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param hCallback [in] The handle to the callback returned from @ref RegisterToPowerLineFrequencyChange().
+ */
+ void (XN_CALLBACK_TYPE* UnregisterFromPowerLineFrequencyChange)
+ (XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback);
+
+} XnModuleAntiFlickerInterface;
+
+typedef struct XnModuleMapGeneratorInterface
+{
+ /**
+ * Contains the generator interface.
+ */
+ XnModuleGeneratorInterface* pGeneratorInterface;
+
+ /**
+ * Gets the number of supported modes. This is useful for allocating an array that will be passed to
+ * @ref GetSupportedMapOutputModes().
+ *
+ * @param hInstance [in] A handle to the instance.
+ */
+ XnUInt32 (XN_CALLBACK_TYPE* GetSupportedMapOutputModesCount)
+ (XnModuleNodeHandle hGenerator);
+
+ /**
+ * Gets a list of all supported modes. The size of the array that should be passed can be obtained by calling
+ * @ref GetSupportedMapOutputModesCount().
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param aModes [in/out] An array to be filled with supported modes.
+ * @param pnCount [in/out] In: number of elements allocated in the array. Out: number of elements
+ * actually written to the array.
+ */
+ XnStatus (XN_CALLBACK_TYPE* GetSupportedMapOutputModes)
+ (XnModuleNodeHandle hGenerator,
+ XnMapOutputMode* aModes, XnUInt32* pnCount);
+
+ /**
+ * Sets the output mode.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param pOutputMode [in] The output mode to be set.
+ */
+ XnStatus (XN_CALLBACK_TYPE* SetMapOutputMode)
+ (XnModuleNodeHandle hGenerator, const XnMapOutputMode* pOutputMode);
+
+ /**
+ * Gets the current output mode.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param pOutputMode [out] Current output mode.
+ */
+ XnStatus (XN_CALLBACK_TYPE* GetMapOutputMode)
+ (XnModuleNodeHandle hGenerator, XnMapOutputMode* pOutputMode);
+
+ /**
+ * Registers a callback function to mode changes.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param handler [in] A pointer to a function that will be called when mode changes.
+ * @param pCookie [in] A user cookie that will be passed to the callback function.
+ * @param phCallback [out] Optional. Will be filled with a handle to be passed to UnregisterFromMapOutputModeChange.
+ */
+ XnStatus (XN_CALLBACK_TYPE* RegisterToMapOutputModeChange)
+ (XnModuleNodeHandle hGenerator, XnModuleStateChangedHandler handler,
+ void* pCookie, XnCallbackHandle* phCallback);
+
+ /**
+ * Unregisters a callback function which was registered using RegisterToMapOutputModeChange.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param hCallback [in] The handle to the callback returned from RegisterToMapOutputModeChange.
+ */
+ void (XN_CALLBACK_TYPE* UnregisterFromMapOutputModeChange)
+ (XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback);
+
+ XnModuleCroppingInterface* pCroppingInterface;
+
+ // NOTE: GetBytesPerPixel() was added in OpenNI 1.0.0.30
+ /**
+ * Gets the number of bytes per pixel
+ *
+ * @param hGenerator [in] A handle to the instance.
+ */
+ XnUInt32 (XN_CALLBACK_TYPE* GetBytesPerPixel)
+ (XnModuleNodeHandle hGenerator);
+
+ XnModuleAntiFlickerInterface* pAntiFlickerInterface;
+
+} XnModuleMapGeneratorInterface;
+
+/**
+ * A set of functions supported by depth generators who supports the User Position capability.
+ */
+typedef struct XnModuleUserPositionCapabilityInterface
+{
+ /**
+ * Gets the number of user positions supported by this generator.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ */
+ XnUInt32 (XN_CALLBACK_TYPE* GetSupportedUserPositionsCount)
+ (XnModuleNodeHandle hGenerator);
+
+ /**
+ * Sets the current user position.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param nIndex [in] The user position to set.
+ * @param pPosition [in] The user position in the frame.
+ */
+ XnStatus (XN_CALLBACK_TYPE* SetUserPosition)(
+ XnModuleNodeHandle hGenerator,
+ XnUInt32 nIndex,
+ const XnBoundingBox3D* pPosition);
+
+ /**
+ * Gets the current user position.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param nIndex [in] The user position to get.
+ * @param pPosition [out] Current user position.
+ */
+ XnStatus (XN_CALLBACK_TYPE* GetUserPosition)
+ (XnModuleNodeHandle hGenerator, XnUInt32 nIndex, XnBoundingBox3D* pPosition);
+
+ /**
+ * Registers a callback function to user position changes.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param handler [in] A pointer to a function that will be called when user position changes.
+ * @param pCookie [in] A user cookie that will be passed to the callback function.
+ * @param phCallback [out] Optional. Will be filled with a handle to be passed to UnregisterFromUserPositionChange.
+ */
+ XnStatus (XN_CALLBACK_TYPE* RegisterToUserPositionChange)
+ (XnModuleNodeHandle hGenerator, XnModuleStateChangedHandler handler,
+ void* pCookie, XnCallbackHandle* phCallback);
+
+ /**
+ * Unregisters a callback function which was registered using RegisterToUserPositionChange.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param hCallback [in] The handle to the callback returned from RegisterToUserPositionChange.
+ */
+ void (XN_CALLBACK_TYPE* UnregisterFromUserPositionChange)
+ (XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback);
+
+} XnModuleUserPositionCapabilityInterface;
+
+/** Depth generator additional methods. */
+typedef struct XnModuleDepthGeneratorInterface
+{
+ /**
+ * Contains map generator interface.
+ */
+ XnModuleMapGeneratorInterface* pMapInterface;
+
+ /**
+ * Gets the current depth-map. This map is updated after a call to WaitAndUpdateData().
+ *
+ * @param hGenerator [in] A handle to the instance.
+ */
+ XnDepthPixel* (XN_CALLBACK_TYPE* GetDepthMap)
+ (XnModuleNodeHandle hGenerator);
+
+ /**
+ * Gets the maximum depth the device can produce.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ */
+ XnDepthPixel (XN_CALLBACK_TYPE* GetDeviceMaxDepth)
+ (XnModuleNodeHandle hGenerator);
+
+ /**
+ * Gets the field of view of the sensor, in radians.
+ * This value will be used for translation between projective and real-world coordinates.
+ * It is assumed that the sensor is a pinhole camera.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param pFOV [in] A struct to be filled with data.
+ */
+ void (XN_CALLBACK_TYPE* GetFieldOfView)(XnModuleNodeHandle hGenerator, XnFieldOfView* pFOV);
+
+ /**
+ * Registers a callback function to field of view changes.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param handler [in] A pointer to a function that will be called when field of view changes.
+ * @param pCookie [in] A user cookie that will be passed to the callback function.
+ * @param phCallback [out] Optional. Will be filled with a handle to be passed to @ref UnregisterFromFieldOfViewChange().
+ */
+ XnStatus (XN_CALLBACK_TYPE* RegisterToFieldOfViewChange)(XnModuleNodeHandle hGenerator, XnModuleStateChangedHandler handler,
+ void* pCookie, XnCallbackHandle* phCallback);
+
+ /**
+ * Unregisters a callback function which was registered using @ref RegisterToFieldOfViewChange.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param hCallback [in] The handle to the callback returned from @ref RegisterToFieldOfViewChange.
+ */
+ void (XN_CALLBACK_TYPE* UnregisterFromFieldOfViewChange)(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback);
+
+ /**
+ * Contains User Position Capability interface.
+ */
+ XnModuleUserPositionCapabilityInterface* pUserPositionInterface;
+
+} XnModuleDepthGeneratorInterface;
+
+/** Image generator Interface. */
+typedef struct XnModuleImageGeneratorInterface
+{
+ /**
+ * Contains map generator interface.
+ */
+ XnModuleMapGeneratorInterface* pMapInterface;
+
+ /** Gets the current image-map. This map is updated after a call to WaitAndUpdateData(). */
+ XnUInt8* (XN_CALLBACK_TYPE* GetImageMap)(
+ XnModuleNodeHandle hGenerator
+ );
+
+ /**
+ * Checks if a specific pixel format is supported.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param Format [in] The format to check for.
+ */
+ XnBool (XN_CALLBACK_TYPE* IsPixelFormatSupported)(XnModuleNodeHandle hGenerator, XnPixelFormat Format);
+
+ /**
+ * Sets the pixel format of the image map.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param Format [in] The format to set.
+ */
+ XnStatus (XN_CALLBACK_TYPE* SetPixelFormat)(XnModuleNodeHandle hGenerator, XnPixelFormat Format);
+
+ /**
+ * Gets current pixel format.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ */
+ XnPixelFormat (XN_CALLBACK_TYPE* GetPixelFormat)(XnModuleNodeHandle hGenerator);
+
+ /**
+ * Registers a callback function to pixel format changes.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param handler [in] A pointer to a function that will be called when pixel format changes.
+ * @param pCookie [in] A user cookie that will be passed to the callback function.
+ * @param phCallback [out] Optional. Will be filled with a handle to be passed to @ref xnUnregisterFromPixelFormatChange.
+ */
+ XnStatus (XN_CALLBACK_TYPE* RegisterToPixelFormatChange)(XnModuleNodeHandle hGenerator, XnModuleStateChangedHandler handler,
+ void* pCookie, XnCallbackHandle* phCallback);
+
+ /**
+ * Unregisters a callback function which was registered using @ref xnRegisterToPixelFormatChange.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param hCallback [in] The handle to the callback returned from @ref xnRegisterToPixelFormatChange.
+ */
+ void (XN_CALLBACK_TYPE* UnregisterFromPixelFormatChange)(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback);
+
+} XnModuleImageGeneratorInterface;
+
+/** IR generator Interface. */
+typedef struct XnModuleIRGeneratorInterface
+{
+ /**
+ * Contains map generator interface.
+ */
+ XnModuleMapGeneratorInterface* pMapInterface;
+
+ /** Gets the current IR-map. This map is updated after a call to WaitAndUpdateData(). */
+ XnIRPixel* (XN_CALLBACK_TYPE* GetIRMap)(
+ XnModuleNodeHandle hGenerator
+ );
+
+} XnModuleIRGeneratorInterface;
+
+/** Gesture generator Interface. */
+typedef struct XnModuleGestureGeneratorInterface
+{
+ XnModuleGeneratorInterface* pGeneratorInterface;
+
+ XnStatus (XN_CALLBACK_TYPE* AddGesture)(XnModuleNodeHandle hGenerator, const XnChar* strGesture, XnBoundingBox3D* pArea);
+ XnStatus (XN_CALLBACK_TYPE* RemoveGesture)(XnModuleNodeHandle hGenerator, const XnChar* strGesture);
+ XnStatus (XN_CALLBACK_TYPE* GetActiveGestures)(XnModuleNodeHandle hGenerator, XnChar** pstrGestures, XnUInt16* nGestures);
+ XnStatus (XN_CALLBACK_TYPE* EnumerateGestures)(XnModuleNodeHandle hGenerator, XnChar** pstrGestures, XnUInt16* nGestures);
+ XnBool (XN_CALLBACK_TYPE* IsGestureAvailable)(XnModuleNodeHandle hInstance, const XnChar* strGesture);
+ XnBool (XN_CALLBACK_TYPE* IsGestureProgressSupported)(XnModuleNodeHandle hGenerator, const XnChar* strGesture);
+ XnStatus (XN_CALLBACK_TYPE* RegisterGestureCallbacks)(XnModuleNodeHandle hGenerator, XnModuleGestureRecognized RecognizedCB, XnModuleGestureProgress ProgressCB, void* pCookie, XnCallbackHandle* phCallback);
+ void (XN_CALLBACK_TYPE* UnregisterGestureCallbacks)(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback);
+ XnStatus (XN_CALLBACK_TYPE* RegisterToGestureChange)(XnModuleNodeHandle hGenerator, XnModuleStateChangedHandler handler, void* pCookie, XnCallbackHandle* phCallback);
+ void (XN_CALLBACK_TYPE* UnregisterFromGestureChange)(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback);
+
+ XnStatus (XN_CALLBACK_TYPE* GetAllActiveGestures)(XnModuleNodeHandle hGenerator, XnChar** pstrGestures, XnUInt32 nNameLength, XnUInt16* nGestures);
+ XnStatus (XN_CALLBACK_TYPE* EnumerateAllGestures)(XnModuleNodeHandle hGenerator, XnChar** pstrGestures, XnUInt32 nNameLength, XnUInt16* nGestures);
+
+ XnStatus (XN_CALLBACK_TYPE* RegisterToGestureIntermediateStageCompleted)(XnModuleNodeHandle hGenerator, XnModuleGestureIntermediateStageCompleted GestureIntermediateStageCompletedCB, void* pCookie, XnCallbackHandle* phCallback);
+ void (XN_CALLBACK_TYPE* UnregisterFromGestureIntermediateStageCompleted)(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback);
+ XnStatus (XN_CALLBACK_TYPE* RegisterToGestureReadyForNextIntermediateStage)(XnModuleNodeHandle hGenerator, XnModuleGestureReadyForNextIntermediateStage ReadyForNextIntermediateStageCB, void* pCookie, XnCallbackHandle* phCallback);
+ void (XN_CALLBACK_TYPE* UnregisterFromGestureReadyForNextIntermediateStage)(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback);
+
+} XnModuleGestureGeneratorInterface;
+
+/** Scene Analyzer Interface. */
+typedef struct XnModuleSceneAnalyzerInterface
+{
+ XnModuleMapGeneratorInterface* pMapInterface;
+
+ const XnLabel* (XN_CALLBACK_TYPE* GetLabelMap)(XnModuleNodeHandle hGenerator);
+ XnStatus (XN_CALLBACK_TYPE* GetFloor)(XnModuleNodeHandle hGenerator, XnPlane3D* pPlane);
+} XnModuleSceneAnalyzerInterface;
+
+/**
+* A set of functions supported by user generators who supports the UI capability.
+*/
+typedef struct XnModuleHandTouchingFOVEdgeCapabilityInterface
+{
+ XnStatus (XN_CALLBACK_TYPE* RegisterToHandTouchingFOVEdge)(XnModuleNodeHandle hGenerator, XnModuleHandTouchingFOVEdge, void* pCookie, XnCallbackHandle* phCallback);
+ void (XN_CALLBACK_TYPE* UnregisterFromHandTouchingFOVEdge)(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback);
+} XnModuleHandTouchingFOVEdgeCapabilityInterface;
+
+typedef struct XnModuleHandsGeneratorInterface
+{
+ XnModuleGeneratorInterface* pGeneratorInterface;
+
+ XnStatus (XN_CALLBACK_TYPE* RegisterHandCallbacks)(XnModuleNodeHandle hGenerator, XnModuleHandCreate CreateCB, XnModuleHandUpdate UpdateCB, XnModuleHandDestroy DestroyCB, void* pCookie, XnCallbackHandle* phCallback);
+ void (XN_CALLBACK_TYPE* UnregisterHandCallbacks)(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback);
+ XnStatus (XN_CALLBACK_TYPE* StopTracking)(XnModuleNodeHandle hGenerator, XnUserID user);
+ XnStatus (XN_CALLBACK_TYPE* StopTrackingAll)(XnModuleNodeHandle hGenerator);
+ XnStatus (XN_CALLBACK_TYPE* StartTracking)(XnModuleNodeHandle hGenerator, const XnPoint3D* pPosition);
+ XnStatus (XN_CALLBACK_TYPE* SetSmoothing)(XnModuleNodeHandle hGenerator, XnFloat fSmoothingFactor);
+
+ XnModuleHandTouchingFOVEdgeCapabilityInterface* pHandTouchingFOVEdgeInterface;
+
+} XnModuleHandsGeneratorInterface;
+
+/**
+* A set of functions supported by user generators who supports the Skeleton capability.
+*/
+typedef struct XnModuleSkeletonCapabilityInterface
+{
+ XnBool (XN_CALLBACK_TYPE* IsJointAvailable)(XnModuleNodeHandle hGenerator, XnSkeletonJoint eJoint);
+ XnBool (XN_CALLBACK_TYPE* IsProfileAvailable)(XnModuleNodeHandle hGenerator, XnSkeletonProfile eProfile);
+ XnStatus (XN_CALLBACK_TYPE* SetSkeletonProfile)(XnModuleNodeHandle hGenerator, XnSkeletonProfile eProfile);
+ XnStatus (XN_CALLBACK_TYPE* SetJointActive)(XnModuleNodeHandle hGenerator, XnSkeletonJoint eJoint, XnBool bState);
+ XnBool (XN_CALLBACK_TYPE* IsJointActive)(XnModuleNodeHandle hGenerator, XnSkeletonJoint eJoint);
+ XnStatus (XN_CALLBACK_TYPE* RegisterToJointConfigurationChange)(XnModuleNodeHandle hGenerator, XnModuleStateChangedHandler handler, void* pCookie, XnCallbackHandle* phCallback);
+ void (XN_CALLBACK_TYPE* UnregisterFromJointConfigurationChange)(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback);
+ XnStatus (XN_CALLBACK_TYPE* EnumerateActiveJoints)(XnModuleNodeHandle hGenerator, XnSkeletonJoint* pJoints, XnUInt16* pnJoints);
+ XnStatus (XN_CALLBACK_TYPE* GetSkeletonJoint)(XnModuleNodeHandle hGenerator, XnUserID user, XnSkeletonJoint eJoint, XnSkeletonJointTransformation* pJoint);
+ XnStatus (XN_CALLBACK_TYPE* GetSkeletonJointPosition)(XnModuleNodeHandle hGenerator, XnUserID user, XnSkeletonJoint eJoint, XnSkeletonJointPosition* pJoint);
+ XnStatus (XN_CALLBACK_TYPE* GetSkeletonJointOrientation)(XnModuleNodeHandle hGenerator, XnUserID user, XnSkeletonJoint eJoint, XnSkeletonJointOrientation* pJoint);
+ XnBool (XN_CALLBACK_TYPE* IsTracking)(XnModuleNodeHandle hGenerator, XnUserID user);
+ XnBool (XN_CALLBACK_TYPE* IsCalibrated)(XnModuleNodeHandle hGenerator, XnUserID user);
+ XnBool (XN_CALLBACK_TYPE* IsCalibrating)(XnModuleNodeHandle hGenerator, XnUserID user);
+ XnStatus (XN_CALLBACK_TYPE* RequestCalibration)(XnModuleNodeHandle hGenerator, XnUserID user, XnBool bForce);
+ XnStatus (XN_CALLBACK_TYPE* AbortCalibration)(XnModuleNodeHandle hGenerator, XnUserID user);
+ XnStatus (XN_CALLBACK_TYPE* SaveCalibrationData)(XnModuleNodeHandle hGenerator, XnUserID user, XnUInt32 nSlot);
+ XnStatus (XN_CALLBACK_TYPE* LoadCalibrationData)(XnModuleNodeHandle hGenerator, XnUserID user, XnUInt32 nSlot);
+ XnStatus (XN_CALLBACK_TYPE* ClearCalibrationData)(XnModuleNodeHandle hGenerator, XnUInt32 nSlot);
+ XnBool (XN_CALLBACK_TYPE* IsCalibrationData)(XnModuleNodeHandle hGenerator, XnUInt32 nSlot);
+ XnStatus (XN_CALLBACK_TYPE* StartTracking)(XnModuleNodeHandle hGenerator, XnUserID user);
+ XnStatus (XN_CALLBACK_TYPE* StopTracking)(XnModuleNodeHandle hGenerator, XnUserID user);
+ XnStatus (XN_CALLBACK_TYPE* Reset)(XnModuleNodeHandle hGenerator, XnUserID user);
+ XnBool (XN_CALLBACK_TYPE* NeedPoseForCalibration)(XnModuleNodeHandle hGenerator);
+ XnStatus (XN_CALLBACK_TYPE* GetCalibrationPose)(XnModuleNodeHandle hGenerator, XnChar* strPose);
+ XnStatus (XN_CALLBACK_TYPE* SetSmoothing)(XnModuleNodeHandle hGenerator, XnFloat fSmoothingFactor);
+ XnStatus (XN_CALLBACK_TYPE* RegisterCalibrationCallbacks)(XnModuleNodeHandle hGenerator, XnModuleCalibrationStart CalibrationStartCB, XnModuleCalibrationEnd CalibrationEndCB, void* pCookie, XnCallbackHandle* phCallback);
+ void (XN_CALLBACK_TYPE* UnregisterCalibrationCallbacks)(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback);
+
+ XnStatus (XN_CALLBACK_TYPE* SaveCalibrationDataToFile)(XnModuleNodeHandle hGenerator, XnUserID user, const XnChar* strFileName);
+ XnStatus (XN_CALLBACK_TYPE* LoadCalibrationDataFromFile)(XnModuleNodeHandle hGenerator, XnUserID user, const XnChar* strFileName);
+
+ XnStatus (XN_CALLBACK_TYPE* RegisterToCalibrationInProgress)(XnModuleNodeHandle hGenerator, XnModuleCalibrationInProgress CalibrationInProgressCB, void* pCookie, XnCallbackHandle* phCallback);
+ void (XN_CALLBACK_TYPE* UnregisterFromCalibrationInProgress)(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback);
+ XnStatus (XN_CALLBACK_TYPE* RegisterToCalibrationComplete)(XnModuleNodeHandle hGenerator, XnModuleCalibrationComplete CalibrationCompleteCB, void* pCookie, XnCallbackHandle* phCallback);
+ void (XN_CALLBACK_TYPE* UnregisterFromCalibrationComplete)(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback);
+
+ XnStatus (XN_CALLBACK_TYPE* RegisterToCalibrationStart)(XnModuleNodeHandle hGenerator, XnModuleCalibrationStart handler, void* pCookie, XnCallbackHandle* phCallback);
+ void (XN_CALLBACK_TYPE* UnregisterFromCalibrationStart)(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback);
+} XnModuleSkeletonCapabilityInterface;
+
+typedef struct XnModulePoseDetectionCapabilityInterface
+{
+ XnUInt32 (XN_CALLBACK_TYPE* GetNumberOfPoses)(XnModuleNodeHandle hGenerator);
+ XnStatus (XN_CALLBACK_TYPE* GetAvailablePoses)(XnModuleNodeHandle hGenerator, XnChar** pstrPoses, XnUInt32* pnPoses);
+ XnStatus (XN_CALLBACK_TYPE* StartPoseDetection)(XnModuleNodeHandle hGenerator, const XnChar* strPose, XnUserID user);
+ XnStatus (XN_CALLBACK_TYPE* StopPoseDetection)(XnModuleNodeHandle hGenerator, XnUserID user);
+ XnStatus (XN_CALLBACK_TYPE* RegisterToPoseCallbacks)(XnModuleNodeHandle hGenerator, XnModulePoseDetectionCallback StartPoseCB, XnModulePoseDetectionCallback EndCB, void* pCookie, XnCallbackHandle* phCallback);
+ void (XN_CALLBACK_TYPE* UnregisterFromPoseCallbacks)(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback);
+
+ XnStatus (XN_CALLBACK_TYPE* GetAllAvailablePoses)(XnModuleNodeHandle hGenerator, XnChar** pstrPoses, XnUInt32 nNameLength, XnUInt32* pnPoses);
+
+ XnStatus (XN_CALLBACK_TYPE* RegisterToPoseDetectionInProgress)(XnModuleNodeHandle hGenerator, XnModulePoseDetectionInProgressCallback PoseProgressCB, void* pCookie, XnCallbackHandle* phCallback);
+ void (XN_CALLBACK_TYPE* UnregisterFromPoseDetectionInProgress)(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback);
+
+ XnStatus (XN_CALLBACK_TYPE* RegisterToPoseDetected)(XnModuleNodeHandle hGenerator, XnModulePoseDetectionCallback handler, void* pCookie, XnCallbackHandle* phCallback);
+ void (XN_CALLBACK_TYPE* UnregisterFromPoseDetected)(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback);
+ XnStatus (XN_CALLBACK_TYPE* RegisterToOutOfPose)(XnModuleNodeHandle hGenerator, XnModulePoseDetectionCallback handler, void* pCookie, XnCallbackHandle* phCallback);
+ void (XN_CALLBACK_TYPE* UnregisterFromOutOfPose)(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback);
+
+ XnStatus (XN_CALLBACK_TYPE* StopSinglePoseDetection)(XnModuleNodeHandle hGenerator, XnUserID user, const XnChar* strPose);
+} XnModulePoseDetectionCapabilityInterface;
+
+/** User generator Interface. */
+typedef struct XnModuleUserGeneratorInterface
+{
+ XnModuleGeneratorInterface* pGeneratorInterface;
+
+ XnUInt16 (XN_CALLBACK_TYPE* GetNumberOfUsers)(XnModuleNodeHandle hGenerator);
+ XnStatus (XN_CALLBACK_TYPE* GetUsers)(XnModuleNodeHandle hGenerator, XnUserID* pUsers, XnUInt16* pnUsers);
+ XnStatus (XN_CALLBACK_TYPE* GetCoM)(XnModuleNodeHandle hGenerator, XnUserID user, XnPoint3D* pCoM);
+ XnStatus (XN_CALLBACK_TYPE* GetUserPixels)(XnModuleNodeHandle hGenerator, XnUserID user, XnSceneMetaData* pScene);
+ XnStatus (XN_CALLBACK_TYPE* RegisterUserCallbacks)(XnModuleNodeHandle hGenerator, XnModuleUserHandler NewUserCB, XnModuleUserHandler LostUserCB, void* pCookie, XnCallbackHandle* phCallback);
+ void (XN_CALLBACK_TYPE* UnregisterUserCallbacks)(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback);
+
+ /**
+ * Contains Skeleton Capability interface.
+ */
+ XnModuleSkeletonCapabilityInterface* pSkeletonInterface;
+ /**
+ * Contains Pose Detection Capability interface
+ */
+ XnModulePoseDetectionCapabilityInterface* pPoseDetectionInterface;
+
+ XnStatus (XN_CALLBACK_TYPE* RegisterToUserExit)(XnModuleNodeHandle hGenerator, XnModuleUserHandler UserExitCB, void* pCookie, XnCallbackHandle* phCallback);
+ void (XN_CALLBACK_TYPE* UnregisterFromUserExit)(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback);
+ XnStatus (XN_CALLBACK_TYPE* RegisterToUserReEnter)(XnModuleNodeHandle hGenerator, XnModuleUserHandler UserReEnterCB, void* pCookie, XnCallbackHandle* phCallback);
+ void (XN_CALLBACK_TYPE* UnregisterFromUserReEnter)(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback);
+
+} XnModuleUserGeneratorInterface;
+
+/** Audio Generator Interface. */
+typedef struct XnModuleAudioGeneratorInterface
+{
+ XnModuleGeneratorInterface* pGeneratorInterface;
+
+ XnUChar* (XN_CALLBACK_TYPE* GetAudioBuffer)(XnModuleNodeHandle hGenerator);
+ XnUInt32 (XN_CALLBACK_TYPE* GetSupportedWaveOutputModesCount)(XnModuleNodeHandle hGenerator);
+ XnStatus (XN_CALLBACK_TYPE* GetSupportedWaveOutputModes)(XnModuleNodeHandle hGenerator, XnWaveOutputMode* aSupportedModes, XnUInt32* pnCount);
+ XnStatus (XN_CALLBACK_TYPE* SetWaveOutputMode)(XnModuleNodeHandle hGenerator, const XnWaveOutputMode* OutputMode);
+ XnStatus (XN_CALLBACK_TYPE* GetWaveOutputMode)(XnModuleNodeHandle hGenerator, XnWaveOutputMode* OutputMode);
+ XnStatus (XN_CALLBACK_TYPE* RegisterToWaveOutputModeChanges)(XnModuleNodeHandle hGenerator, XnModuleStateChangedHandler handler,
+ void* pCookie, XnCallbackHandle* phCallback);
+ void (XN_CALLBACK_TYPE* UnregisterFromWaveOutputModeChanges)(XnModuleNodeHandle hGenerator, XnCallbackHandle hCallback);
+
+} XnModuleAudioGeneratorInterface;
+
+typedef struct XnModuleCodecInterface
+{
+ XnModuleProductionNodeInterface* pProductionNode;
+
+ XnCodecID (XN_CALLBACK_TYPE* GetCodecID)(XnModuleNodeHandle hCodec);
+ XnStatus (XN_CALLBACK_TYPE* Init)(XnModuleNodeHandle hCodec, XnNodeHandle hNode);
+ XnStatus (XN_CALLBACK_TYPE* CompressData)(XnModuleNodeHandle hCodec, const void* pSrc, XnUInt32 nSrcSize, void* pDst, XnUInt32 nDstSize, XnUInt* pnBytesWritten);
+ XnStatus (XN_CALLBACK_TYPE* DecompressData)(XnModuleNodeHandle hCodec, const void* pSrc, XnUInt32 nSrcSize, void* pDst, XnUInt32 nDstSize, XnUInt* pnBytesWritten);
+
+} XnModuleCodecInterface;
+
+typedef struct XnModuleScriptNodeInterface
+{
+ XnModuleProductionNodeInterface* pProductionNode;
+
+ const XnChar* (XN_CALLBACK_TYPE* GetSupportedFormat)(XnModuleNodeHandle hScript);
+ XnStatus (XN_CALLBACK_TYPE* LoadScriptFromFile)(XnModuleNodeHandle hScript, const XnChar* strFileName);
+ XnStatus (XN_CALLBACK_TYPE* LoadScriptFromString)(XnModuleNodeHandle hScript, const XnChar* strScript);
+ XnStatus (XN_CALLBACK_TYPE* Run)(XnModuleNodeHandle hScript, XnNodeInfoList* pCreatedNodes, XnEnumerationErrors* pErrors);
+
+} XnModuleScriptNodeInterface;
+
+#endif // __XN_MODULE_INTERFACE_H__
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnNode.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnNode.h
new file mode 100644
index 00000000..025741a3
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnNode.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef _XN_NODE_H_
+#define _XN_NODE_H_
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include <XnDataTypes.h>
+#include <XnBaseNode.h>
+
+//---------------------------------------------------------------------------
+// Types
+//---------------------------------------------------------------------------
+/**
+ * The building block of the data types - XnNode
+ */
+class XnNode : protected XnBaseNode
+{
+public:
+ static XnNode *Allocate() { return (XnNode*)xnAllocateBaseNode(); }
+ static void Deallocate(XnNode *pNode) { xnDeallocateBaseNode((XnBaseNode*)pNode); }
+
+ /**
+ * Constructor. Initialize internal representations
+ */
+ XnNode() { m_pNext = NULL; m_pPrevious = NULL; m_Data = NULL; }
+
+ /**
+ * Get the next XnNode (non-const version)
+ */
+ XnNode*& Next() {return (XnNode*&)m_pNext;}
+ /**
+ * Get the next XnNode (const version)
+ */
+ const XnNode* const Next() const {return (const XnNode*)m_pNext;}
+
+ /**
+ * Get the previous XnNode (non-const version)
+ */
+ XnNode*& Previous() {return (XnNode*&)m_pPrevious;}
+ /**
+ * Get the previous XnNode (non-const version)
+ */
+ const XnNode* const Previous() const {return (const XnNode*)m_pPrevious;}
+
+ /**
+ * Get the value in the node (non-const version)
+ */
+ XnValue& Data() {return m_Data;}
+ /**
+ * Get the value in the node (non-const version)
+ */
+ const XnValue& Data() const {return m_Data;}
+};
+
+#endif // _XN_NODE_H_
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnNodeAllocator.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnNodeAllocator.h
new file mode 100644
index 00000000..757e4005
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnNodeAllocator.h
@@ -0,0 +1,46 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef _NISIMPLENODEALLOCATOR_H
+#define _NISIMPLENODEALLOCATOR_H
+
+#include <IXnNodeAllocator.h>
+#include <XnNode.h>
+
+class XnNodeAllocator : public INiNodeAllocator
+{
+public:
+ /**
+ * Allocate a new XnNode
+ *
+ * @return NULL if allocating a new node failed
+ */
+ virtual XnNode *Allocate() { return XnNode::Allocate(); }
+
+ /**
+ * Release an XnNode
+ *
+ * @param pNode [in] The node to deallocate
+ */
+ virtual void Deallocate(XnNode *pNode) { XnNode::Deallocate(pNode); }
+};
+
+#endif //_NISIMPLENODEALLOCATOR_H
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnOS.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnOS.h
new file mode 100644
index 00000000..e934655c
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnOS.h
@@ -0,0 +1,784 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef __XN_OS_H__
+#define __XN_OS_H__
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include "XnPlatform.h"
+#include "XnMacros.h"
+#include "XnStatusCodes.h"
+#include "XnOSStrings.h"
+#include "XnOSMemory.h"
+
+//---------------------------------------------------------------------------
+// Defines
+//---------------------------------------------------------------------------
+#define XN_MASK_OS "xnOS"
+
+// uncomment next line to activate memory profiling
+//#define XN_MEM_PROFILING
+
+//---------------------------------------------------------------------------
+// OS Identifier
+//---------------------------------------------------------------------------
+#if (XN_PLATFORM == XN_PLATFORM_WIN32)
+ #include "Win32/XnOSWin32.h"
+#elif (XN_PLATFORM == XN_PLATFORM_LINUX_X86 || XN_PLATFORM == XN_PLATFORM_LINUX_ARM || XN_PLATFORM == XN_PLATFORM_MACOSX || XN_PLATFORM == XN_PLATFORM_ANDROID_ARM)
+ #include "Linux-x86/XnOSLinux-x86.h"
+#elif defined(_ARC)
+ #include "ARC/XnOSARC.h"
+#else
+ #error OpenNI OS Abstraction Layer - Unsupported Platform!
+#endif
+
+//---------------------------------------------------------------------------
+// Types
+//---------------------------------------------------------------------------
+#define XN_MAX_OS_NAME_LENGTH 255
+
+typedef struct xnOSInfo
+{
+ XnChar csOSName[XN_MAX_OS_NAME_LENGTH];
+ XnChar csCPUName[XN_MAX_OS_NAME_LENGTH];
+ XnUInt32 nProcessorsCount;
+ XnUInt64 nTotalMemory;
+} xnOSInfo;
+
+typedef XnBool (XN_CALLBACK_TYPE* XnConditionFunc)(void* pConditionData);
+
+//---------------------------------------------------------------------------
+// Global Variables
+//---------------------------------------------------------------------------
+/** The time since Xiron Core was initialized */
+extern XnOSTimer g_xnOSHighResGlobalTimer;
+
+//---------------------------------------------------------------------------
+// Files
+//---------------------------------------------------------------------------
+// File open modes
+/** Open the file for reading. */
+#define XN_OS_FILE_READ 0x01
+/** Open the file for writing. */
+#define XN_OS_FILE_WRITE 0x02
+/** Create a new file (but only if it doesn't exist). */
+#define XN_OS_FILE_CREATE_NEW_ONLY 0x04
+/** Truncate the file if it already exists. */
+#define XN_OS_FILE_TRUNCATE 0x08
+/** File be opened in append mode */
+#define XN_OS_FILE_APPEND 0x10
+/** All writes will be immediately written to disk */
+#define XN_OS_FILE_AUTO_FLUSH 0x20
+
+// Seek types
+/** The seek type enum list. */
+typedef enum {
+ /** Absolute seek from the file beginning. */
+ XN_OS_SEEK_SET = 0,
+ /** Relative seek from the current location. */
+ XN_OS_SEEK_CUR,
+ /** Absolute seek from the file ending. */
+ XN_OS_SEEK_END
+} XnOSSeekType;
+
+//---------------------------------------------------------------------------
+// Network
+//---------------------------------------------------------------------------
+// Network socket type
+/** The network socket type. */
+typedef enum {
+ /** UDP socket. */
+ XN_OS_UDP_SOCKET = 0,
+ /** TCP socket. */
+ XN_OS_TCP_SOCKET
+} XnOSSocketType;
+
+#define XN_OS_NETWORK_LOCAL_HOST "127.0.0.1"
+
+//---------------------------------------------------------------------------
+// Macros
+//---------------------------------------------------------------------------
+// Memory
+/** Validate that the input pointer X is not NULL. */
+#define XN_VALIDATE_INPUT_PTR(x) XN_VALIDATE_PTR(x, XN_STATUS_NULL_INPUT_PTR)
+
+/** Validate that the output pointer X is not NULL. */
+#define XN_VALIDATE_OUTPUT_PTR(x) XN_VALIDATE_PTR(x, XN_STATUS_NULL_OUTPUT_PTR)
+/** Validate that a X pointer after a memory allocation call is not NULL. */
+#define XN_VALIDATE_ALLOC_PTR(x) XN_VALIDATE_PTR(x, XN_STATUS_ALLOC_FAILED)
+
+/** Allocate Y bytes into the X pointer and make sure NULL wasn't returned. */
+#define XN_VALIDATE_ALLOC(x,y) \
+ x = (y*)xnOSMalloc(sizeof(y)); \
+ XN_VALIDATE_ALLOC_PTR(x);
+
+/** Allocate Z elements of Y type into the X pointer and make sure NULL wasn't returned. */
+#define XN_VALIDATE_CALLOC(x,y,z) \
+ x = (y*)xnOSCalloc(z, sizeof(y)); \
+ XN_VALIDATE_ALLOC_PTR(x);
+
+/** Allocate Y aligned bytes into the X pointer and make sure NULL wasn't returned. */
+#define XN_VALIDATE_ALIGNED_ALLOC(x,y,w) \
+ x = (y*)xnOSMallocAligned(sizeof(y), w); \
+ XN_VALIDATE_ALLOC_PTR(x);
+
+/** Allocate Z aligned elements of Y type into the X pointer and make sure NULL wasn't returned. */
+#define XN_VALIDATE_ALIGNED_CALLOC(x,y,z,w) \
+ x = (y*)xnOSCallocAligned(z, sizeof(y), w); \
+ XN_VALIDATE_ALLOC_PTR(x);
+
+/** Validate that the memory free request succeeded and set X to NULL. */
+#define XN_FREE_AND_NULL(x) \
+ if (x != NULL) \
+ { \
+ xnOSFree(x); \
+ x = NULL; \
+ }
+/** Validate that the aligned memory free request succeeded and set X to NULL. */
+#define XN_ALIGNED_FREE_AND_NULL(x) \
+ if (x != NULL) \
+ { \
+ xnOSFreeAligned(x); \
+ x = NULL; \
+ }
+
+
+/** Creates a new type object and validates that allocation succeeded. */
+#if XN_PLATFORM_VAARGS_TYPE == XN_PLATFORM_USE_WIN32_VAARGS_STYLE
+ #define XN_VALIDATE_NEW(ptr, type, ...) \
+ { \
+ (ptr) = XN_NEW(type, __VA_ARGS__); \
+ if ((ptr) == NULL) \
+ { \
+ return (XN_STATUS_ALLOC_FAILED); \
+ } \
+ }
+
+#elif XN_PLATFORM_VAARGS_TYPE == XN_PLATFORM_USE_GCC_VAARGS_STYLE
+ #define XN_VALIDATE_NEW(ptr, type, ...) \
+ { \
+ (ptr) = XN_NEW(type, ##__VA_ARGS__); \
+ if ((ptr) == NULL) \
+ { \
+ return (XN_STATUS_ALLOC_FAILED); \
+ } \
+ }
+#elif XN_PLATFORM_VAARGS_TYPE == XN_PLATFORM_USE_ARC_VAARGS_STYLE
+ #define XN_VALIDATE_NEW(ptr, type...) \
+ { \
+ (ptr) = XN_NEW(type); \
+ if ((ptr) == NULL) \
+ { \
+ return (XN_STATUS_ALLOC_FAILED); \
+ } \
+ }
+#else
+ #define XN_VALIDATE_NEW(ptr, type) \
+ { \
+ (ptr) = XN_NEW(type); \
+ if ((ptr) == NULL) \
+ { \
+ return (XN_STATUS_ALLOC_FAILED); \
+ } \
+ }
+#endif
+
+/** Creates a new type object, validates that allocation succeeded, and initializes the object (type must have an Init function). */
+#if XN_PLATFORM_VAARGS_TYPE == XN_PLATFORM_USE_WIN32_VAARGS_STYLE
+ #define XN_VALIDATE_NEW_AND_INIT(ptr, type, ...) \
+ { \
+ XN_VALIDATE_NEW(ptr, type, __VA_ARGS__); \
+ XnStatus rc = (ptr)->Init(); \
+ if (rc != XN_STATUS_OK) \
+ { \
+ XN_DELETE(ptr); \
+ return (rc); \
+ } \
+ }
+#elif XN_PLATFORM_VAARGS_TYPE == XN_PLATFORM_USE_GCC_VAARGS_STYLE
+ #define XN_VALIDATE_NEW_AND_INIT(ptr, type, ...) \
+ { \
+ XN_VALIDATE_NEW(ptr, type, ##__VA_ARGS__); \
+ XnStatus rc = (ptr)->Init(); \
+ if (rc != XN_STATUS_OK) \
+ { \
+ XN_DELETE(ptr); \
+ return (rc); \
+ } \
+ }
+#elif XN_PLATFORM_VAARGS_TYPE == XN_PLATFORM_USE_ARC_VAARGS_STYLE
+ #define XN_VALIDATE_NEW_AND_INIT(ptr, type...) \
+ { \
+ XN_VALIDATE_NEW(ptr, type); \
+ XnStatus rc = (ptr)->Init(); \
+ if (rc != XN_STATUS_OK) \
+ { \
+ XN_DELETE(ptr); \
+ return (rc); \
+ } \
+ }
+#else
+ #define XN_VALIDATE_NEW_AND_INIT(ptr, type) \
+ { \
+ XN_VALIDATE_NEW(ptr, type); \
+ XnStatus rc = (ptr)->Init(); \
+ if (rc != XN_STATUS_OK) \
+ { \
+ XN_DELETE(ptr); \
+ return (rc); \
+ } \
+ }
+#endif
+
+// Strings
+/** Append x into y (with z as the max size) and check the status via z. */
+#define XN_VALIDATE_STR_APPEND(w,x,y,z) \
+ z = xnOSStrAppend(w, x, y); \
+ XN_IS_STATUS_OK(z);
+
+/** Prefix x into y (with z as the max size) and check the status via z. */
+#define XN_VALIDATE_STR_PREFIX(w,x,y,z) \
+ z = xnOSStrPrefix(w, x, y); \
+ XN_IS_STATUS_OK(z);
+
+#define XN_VALIDATE_STR_COPY(w,x,y,z) \
+ z = xnOSStrCopy(w, x, y); \
+ XN_IS_STATUS_OK(z);
+
+#define XN_VALIDATE_STRN_COPY(v,w,x,y,z) \
+ z = xnOSStrNCopy(v, w, x, y); \
+ XN_IS_STATUS_OK(z);
+
+// INI
+/** Read a string from the INI file and check the status via z. */
+#define XN_VALIDATE_READ_INI_STR(u,v,w,x,y,z) \
+ z = xnOSReadStringFromINI(u, v, w, x, y); \
+ XN_IS_STATUS_OK(z);
+
+/** Read an int from the INI file and check the status via z. */
+#define XN_VALIDATE_READ_INI_INT(v,w,x,y,z) \
+ z = xnOSReadIntFromINI(v, w, x, y); \
+ XN_IS_STATUS_OK(z);
+
+/** Read a float from the INI file and check the status via z. */
+#define XN_VALIDATE_READ_INI_FLOAT(v,w,x,y,z) \
+ z = xnOSReadFloatFromINI(v, w, x, y); \
+ XN_IS_STATUS_OK(z);
+
+/** Read a double from the INI file and check the status via z. */
+#define XN_VALIDATE_READ_INI_DOUBLE(v,w,x,y,z) \
+ z = xnOSReadDoubleFromINI(v, w, x, y); \
+ XN_IS_STATUS_OK(z);
+
+// Mutex
+/** Lock the mutex x for a y period of time and check the status via z. */
+#define XN_VALIDATE_LOCK_MUTEX(x,y,z) \
+ z = xnOSLockMutex(x, y); \
+ XN_IS_STATUS_OK(z);
+
+/** UnLock the mutex x and check the status via z. */
+#define XN_VALIDATE_UNLOCK_MUTEX(x,z) \
+ z = xnOSUnLockMutex(x); \
+ XN_IS_STATUS_OK(z);
+
+// Files
+/** Returns XN_STATUS_OS_FILE_NOT_FOUND if the file x doesn't exists. */
+#define XN_VALIDATE_FILE_EXISTS_RET(x,y,z,w) \
+ y = xnOSDoesFileExist(x, &z); \
+ XN_IS_STATUS_OK(y); \
+ if (z == FALSE) \
+ { \
+ return (w); \
+ }
+#define XN_VALIDATE_FILE_EXISTS(x,y,z) \
+ XN_VALIDATE_FILE_EXISTS_RET(x,y,z,XN_STATUS_OS_FILE_NOT_FOUND)
+
+//---------------------------------------------------------------------------
+// Exported Function Declaration
+//---------------------------------------------------------------------------
+// Common
+XN_C_API XnStatus XN_C_DECL xnOSInit();
+XN_C_API XnStatus XN_C_DECL xnOSShutdown();
+XN_C_API XnStatus XN_C_DECL xnOSGetInfo(xnOSInfo* pOSInfo);
+
+
+#if XN_PLATFORM_VAARGS_TYPE == XN_PLATFORM_USE_WIN32_VAARGS_STYLE
+ #define XN_NEW(type, ...) new type(__VA_ARGS__)
+#elif XN_PLATFORM_VAARGS_TYPE == XN_PLATFORM_USE_GCC_VAARGS_STYLE
+ #define XN_NEW(type, ...) new type(__VA_ARGS__)
+#elif XN_PLATFORM_VAARGS_TYPE == XN_PLATFORM_USE_ARC_VAARGS_STYLE
+ #define XN_NEW(type, arg...) new type(arg)
+#else
+ #define XN_NEW(type, arg) new type(arg)
+#endif
+
+#define XN_NEW_ARR(type, count) new type[count]
+#define XN_DELETE(p) delete (p)
+#define XN_DELETE_ARR(p) delete[] (p)
+
+typedef enum
+{
+ XN_ALLOCATION_MALLOC,
+ XN_ALLOCATION_MALLOC_ALIGNED,
+ XN_ALLOCATION_CALLOC,
+ XN_ALLOCATION_CALLOC_ALIGNED,
+ XN_ALLOCATION_NEW,
+ XN_ALLOCATION_NEW_ARRAY
+} XnAllocationType;
+
+/**
+* Memory Profiling - Logs an allocation of memory.
+*/
+XN_C_API void* XN_C_DECL xnOSLogMemAlloc(void* pMemBlock, XnAllocationType nAllocType, XnUInt32 nBytes, const XnChar* csFunction, const XnChar* csFile, XnUInt32 nLine, const XnChar* csAdditional);
+
+/**
+* Memory Profiling - Logs freeing of memory.
+*/
+XN_C_API void XN_C_DECL xnOSLogMemFree(const void* pMemBlock);
+
+/**
+* Memory Profiling - Prints a current memory report to requested file.
+*/
+XN_C_API void XN_C_DECL xnOSWriteMemoryReport(const XnChar* csFileName);
+
+// for memory profiling, replace all malloc/calloc/free/new/delete calls
+#if (defined XN_MEM_PROFILING) && (!defined(XN_OS_IMPL))
+ #ifdef _MSC_VER
+ #pragma message("Compiling with Memory Profiling!")
+ #elif defined(__INTEL_COMPILER)
+ #warning "Compiling with Memory Profiling!"
+ //TODO: Add warning for linux compiler(s)
+ #endif
+
+ #ifdef __cplusplus
+ #include <new>
+ static void* operator new(size_t size)
+ {
+ void* p = xnOSMalloc(size);
+ return xnOSLogMemAlloc(p, XN_ALLOCATION_NEW, size, "", "", 0, "");
+ }
+ static void* operator new[](size_t size)
+ {
+ void* p = xnOSMalloc(size);
+ return xnOSLogMemAlloc(p, XN_ALLOCATION_NEW, size, "", "", 0, "");
+ }
+ static void* operator new(size_t size, const XnChar* csFunction, const XnChar* csFile, XnUInt32 nLine, const XnChar* csAdditional)
+ {
+ void* p = xnOSMalloc(size);
+ return xnOSLogMemAlloc(p, XN_ALLOCATION_NEW, size, csFunction, csFile, nLine, csAdditional);
+ }
+
+ // called only if ctor threw exception
+ static void operator delete(void* p, const XnChar* /*csFunction*/, const XnChar* /*csFile*/, XnUInt32 /*nLine*/, const XnChar* /*csAdditional*/)
+ {
+ xnOSLogMemFree(p);
+ xnOSFree(p);
+ }
+
+ static void operator delete(void* p)
+ {
+ xnOSLogMemFree(p);
+ xnOSFree(p);
+ }
+
+ static void* operator new[](size_t size, const XnChar* csFunction, const XnChar* csFile, XnUInt32 nLine, const XnChar* csAdditional)
+ {
+ void* p = xnOSMalloc(size);
+ return xnOSLogMemAlloc(p, XN_ALLOCATION_NEW_ARRAY, size, csFunction, csFile, nLine, csAdditional);
+ }
+
+ // called only if ctor threw exception
+ static void operator delete[](void* p, const XnChar* /*csFunction*/, const XnChar* /*csFile*/, XnUInt32 /*nLine*/, const XnChar* /*csAdditional*/)
+ {
+ xnOSLogMemFree(p);
+ xnOSFree(p);
+ }
+
+ static void operator delete[](void* p)
+ {
+ xnOSLogMemFree(p);
+ xnOSFree(p);
+ }
+
+ #define xnOSMalloc(nAllocSize) xnOSLogMemAlloc(xnOSMalloc(nAllocSize), XN_ALLOCATION_MALLOC, nAllocSize, __FUNCTION__, __FILE__, __LINE__, NULL)
+ #define xnOSMallocAligned(nAllocSize, nAlignment) xnOSLogMemAlloc(xnOSMallocAligned(nAllocSize, nAlignment), XN_ALLOCATION_MALLOC_ALIGNED, nAllocSize, __FUNCTION__, __FILE__, __LINE__, "Aligned to " XN_STRINGIFY(nAlignment))
+ #define xnOSCalloc(nAllocNum, nAllocSize) xnOSLogMemAlloc(xnOSCalloc(nAllocNum, nAllocSize), XN_ALLOCATION_CALLOC, nAllocNum*nAllocSize, __FUNCTION__, __FILE__, __LINE__, NULL)
+ #define xnOSCallocAligned(nAllocNum, nAllocSize, nAlignment) xnOSLogMemAlloc(xnOSCallocAligned(nAllocNum, nAllocSize, nAlignment), XN_ALLOCATION_CALLOC_ALIGNED, nAllocNum*nAllocSize, __FUNCTION__, __FILE__, __LINE__, "Aligned to " XN_STRINGIFY(nAlignment))
+ #define xnOSFree(pMemBlock) { xnOSLogMemFree(pMemBlock); xnOSFree(pMemBlock); }
+ #define xnOSFreeAligned(pMemBlock) { xnOSLogMemFree(pMemBlock); xnOSFreeAligned(pMemBlock); }
+
+ #undef XN_NEW
+ #undef XN_NEW_ARR
+
+ #if XN_PLATFORM_VAARGS_TYPE == XN_PLATFORM_USE_WIN32_VAARGS_STYLE
+ #define XN_NEW(type, ...) new (__FUNCTION__, __FILE__, __LINE__, XN_STRINGIFY(type)) type(__VA_ARGS__)
+ #elif XN_PLATFORM_VAARGS_TYPE == XN_PLATFORM_USE_GCC_VAARGS_STYLE
+ #define XN_NEW(type, arg...) new (__FUNCTION__, __FILE__, __LINE__, XN_STRINGIFY(type)) type(arg)
+ #else
+ #define XN_NEW(type, arg) new (__FUNCTION__, __FILE__, __LINE__, XN_STRINGIFY(type)) type(arg)
+ #endif
+
+ #define XN_NEW_ARR(type, count) new (__FUNCTION__, __FILE__, __LINE__, XN_STRINGIFY(count) " " XN_STRINGIFY(type)) type[count]
+
+ #endif
+#endif
+
+// Files
+XN_C_API XnStatus XN_C_DECL xnOSGetFileList(const XnChar* cpSearchPattern, const XnChar* cpPrefixPath, XnChar cpFileList[][XN_FILE_MAX_PATH], const XnUInt32 nMaxFiles, XnUInt32* pnFoundFiles);
+XN_C_API XnStatus XN_C_DECL xnOSOpenFile(const XnChar* cpFileName, const XnUInt32 nFlags, XN_FILE_HANDLE* pFile);
+XN_C_API XnStatus XN_C_DECL xnOSCloseFile(XN_FILE_HANDLE* pFile);
+XN_C_API XnStatus XN_C_DECL xnOSReadFile(const XN_FILE_HANDLE File, void* pBuffer, XnUInt32* pnBufferSize);
+XN_C_API XnStatus XN_C_DECL xnOSWriteFile(const XN_FILE_HANDLE File, const void* pBuffer, const XnUInt32 nBufferSize);
+XN_C_API XnStatus XN_API_DEPRECATED("Use xnOSSeekFile64() instead") XN_C_DECL
+ xnOSSeekFile (const XN_FILE_HANDLE File, const XnOSSeekType SeekType, const XnInt32 nOffset);
+XN_C_API XnStatus XN_C_DECL xnOSSeekFile64(const XN_FILE_HANDLE File, const XnOSSeekType SeekType, const XnInt64 nOffset);
+XN_C_API XnStatus XN_API_DEPRECATED("Use xnOSTellFile64() instead") XN_C_DECL
+ xnOSTellFile (const XN_FILE_HANDLE File, XnUInt32* nFilePos);
+XN_C_API XnStatus XN_C_DECL xnOSTellFile64(const XN_FILE_HANDLE File, XnUInt64* nFilePos);
+XN_C_API XnStatus XN_C_DECL xnOSFlushFile(const XN_FILE_HANDLE File);
+XN_C_API XnStatus XN_C_DECL xnOSDoesFileExist(const XnChar* cpFileName, XnBool* pbResult);
+XN_C_API XnStatus XN_C_DECL xnOSDoesDirecotyExist(const XnChar* cpDirName, XnBool* pbResult);
+XN_C_API XnStatus XN_C_DECL xnOSLoadFile(const XnChar* cpFileName, void* pBuffer, const XnUInt32 nBufferSize);
+XN_C_API XnStatus XN_C_DECL xnOSSaveFile(const XnChar* cpFileName, const void* pBuffer, const XnUInt32 nBufferSize);
+XN_C_API XnStatus XN_C_DECL xnOSAppendFile(const XnChar* cpFileName, const void* pBuffer, const XnUInt32 nBufferSize);
+XN_C_API XnStatus XN_API_DEPRECATED("Use xnOSGetFileSize64() instead") XN_C_DECL
+ xnOSGetFileSize (const XnChar* cpFileName, XnUInt32* pnFileSize);
+XN_C_API XnStatus XN_C_DECL xnOSGetFileSize64(const XnChar* cpFileName, XnUInt64* pnFileSize);
+XN_C_API XnStatus XN_C_DECL xnOSCreateDirectory(const XnChar* cpDirName);
+XN_C_API XnStatus XN_C_DECL xnOSGetDirName(const XnChar* cpFilePath, XnChar* cpDirName, const XnUInt32 nBufferSize);
+XN_C_API XnStatus XN_C_DECL xnOSGetFileName(const XnChar* cpFilePath, XnChar* cpFileName, const XnUInt32 nBufferSize);
+XN_C_API XnStatus XN_C_DECL xnOSGetFullPathName(const XnChar* strFilePath, XnChar* strFullPath, XnUInt32 nBufferSize);
+XN_C_API XnStatus XN_C_DECL xnOSGetCurrentDir(XnChar* cpDirName, const XnUInt32 nBufferSize);
+XN_C_API XnStatus XN_C_DECL xnOSSetCurrentDir(const XnChar* cpDirName);
+XN_C_API XnStatus XN_C_DECL xnOSDeleteFile(const XnChar* cpFileName);
+XN_C_API XnStatus XN_C_DECL xnOSDeleteEmptyDirectory(const XnChar* strDirName);
+XN_C_API XnStatus XN_C_DECL xnOSDeleteDirectoryTree(const XnChar* strDirName);
+
+// INI
+XN_C_API XnStatus XN_C_DECL xnOSReadStringFromINI(const XnChar* cpINIFile, const XnChar* cpSection, const XnChar* cpKey, XnChar* cpDest, const XnUInt32 nDestLength);
+XN_C_API XnStatus XN_C_DECL xnOSReadFloatFromINI(const XnChar* cpINIFile, const XnChar* cpSection, const XnChar* cpKey, XnFloat* fDest);
+XN_C_API XnStatus XN_C_DECL xnOSReadDoubleFromINI(const XnChar* cpINIFile, const XnChar* cpSection, const XnChar* cpKey, XnDouble* fDest);
+XN_C_API XnStatus XN_C_DECL xnOSReadIntFromINI(const XnChar* cpINIFile, const XnChar* cpSection, const XnChar* cpKey, XnUInt32* nDest);
+XN_C_API XnStatus XN_C_DECL xnOSWriteStringToINI(const XnChar* cpINIFile, const XnChar* cpSection, const XnChar* cpKey, const XnChar* cpSrc);
+XN_C_API XnStatus XN_C_DECL xnOSWriteFloatToINI(const XnChar* cpINIFile, const XnChar* cpSection, const XnChar* cpKey, const XnFloat fSrc);
+XN_C_API XnStatus XN_C_DECL xnOSWriteDoubleToINI(const XnChar* cpINIFile, const XnChar* cpSection, const XnChar* cpKey, const XnDouble fSrc);
+XN_C_API XnStatus XN_C_DECL xnOSWriteIntToINI(const XnChar* cpINIFile, const XnChar* cpSection, const XnChar* cpKey, const XnUInt32 nSrc);
+
+// Shared libraries
+XN_C_API XnStatus XN_C_DECL xnOSLoadLibrary(const XnChar* cpFileName, XN_LIB_HANDLE* pLibHandle);
+XN_C_API XnStatus XN_C_DECL xnOSFreeLibrary(const XN_LIB_HANDLE LibHandle);
+XN_C_API XnStatus XN_C_DECL xnOSGetProcAddress(const XN_LIB_HANDLE LibHandle, const XnChar* cpProcName, XnFarProc* pProcAddr);
+
+struct timespec;
+
+// Time
+XN_C_API XnStatus XN_C_DECL xnOSGetEpochTime(XnUInt32* nEpochTime);
+XN_C_API XnStatus XN_C_DECL xnOSGetTimeStamp(XnUInt64* nTimeStamp);
+XN_C_API XnStatus XN_C_DECL xnOSGetHighResTimeStamp(XnUInt64* nTimeStamp);
+XN_C_API XnStatus XN_C_DECL xnOSSleep(XnUInt32 nMilliseconds);
+XN_C_API XnStatus XN_C_DECL xnOSStartTimer(XnOSTimer* pTimer);
+XN_C_API XnStatus XN_C_DECL xnOSStartHighResTimer(XnOSTimer* pTimer);
+XN_C_API XnStatus XN_C_DECL xnOSQueryTimer(XnOSTimer Timer, XnUInt64* pnTimeSinceStart);
+XN_C_API XnStatus XN_C_DECL xnOSStopTimer(XnOSTimer* pTimer);
+XN_C_API XnStatus XN_C_DECL xnOSGetMonoTime(struct timespec* pTime);
+XN_C_API XnStatus XN_C_DECL xnOSGetTimeout(struct timespec* pTime, XnUInt32 nMilliseconds);
+XN_C_API XnStatus XN_C_DECL xnOSGetAbsTimeout(struct timespec* pTime, XnUInt32 nMilliseconds);
+
+// Threads
+typedef enum XnThreadPriority
+{
+ XN_PRIORITY_LOW,
+ XN_PRIORITY_NORMAL,
+ XN_PRIORITY_HIGH,
+ XN_PRIORITY_CRITICAL
+} XnThreadPriority;
+
+XN_C_API XnStatus XN_C_DECL xnOSCreateThread(XN_THREAD_PROC_PROTO pThreadProc, const XN_THREAD_PARAM pThreadParam, XN_THREAD_HANDLE* pThreadHandle);
+XN_C_API XnStatus XN_C_DECL xnOSTerminateThread(XN_THREAD_HANDLE* pThreadHandle);
+XN_C_API XnStatus XN_C_DECL xnOSCloseThread(XN_THREAD_HANDLE* pThreadHandle);
+XN_C_API XnStatus XN_C_DECL xnOSWaitForThreadExit(XN_THREAD_HANDLE ThreadHandle, XnUInt32 nMilliseconds);
+XN_C_API XnStatus XN_C_DECL xnOSSetThreadPriority(XN_THREAD_HANDLE ThreadHandle, XnThreadPriority nPriority);
+XN_C_API XnStatus XN_C_DECL xnOSGetCurrentThreadID(XN_THREAD_ID* pThreadID);
+XN_C_API XnStatus XN_C_DECL xnOSWaitAndTerminateThread(XN_THREAD_HANDLE* pThreadHandle, XnUInt32 nMilliseconds);
+
+// Processes
+XN_C_API XnStatus XN_C_DECL xnOSGetCurrentProcessID(XN_PROCESS_ID* pProcID);
+XN_C_API XnStatus XN_C_DECL xnOSCreateProcess(const XnChar* strExecutable, XnUInt32 nArgs, const XnChar** pstrArgs, XN_PROCESS_ID* pProcID);
+
+// Mutex
+XN_C_API XnStatus XN_C_DECL xnOSCreateMutex(XN_MUTEX_HANDLE* pMutexHandle);
+XN_C_API XnStatus XN_C_DECL xnOSCreateNamedMutex(XN_MUTEX_HANDLE* pMutexHandle, const XnChar* cpMutexName);
+XN_C_API XnStatus XN_C_DECL xnOSCreateNamedMutexEx(XN_MUTEX_HANDLE* pMutexHandle, const XnChar* cpMutexName, XnBool bAllowOtherUsers);
+XN_C_API XnStatus XN_C_DECL xnOSCloseMutex(XN_MUTEX_HANDLE* pMutexHandle);
+XN_C_API XnStatus XN_C_DECL xnOSLockMutex(const XN_MUTEX_HANDLE MutexHandle, XnUInt32 nMilliseconds);
+XN_C_API XnStatus XN_C_DECL xnOSUnLockMutex(const XN_MUTEX_HANDLE MutexHandle);
+
+// Critical Sections
+XN_C_API XnStatus XN_C_DECL xnOSCreateCriticalSection(XN_CRITICAL_SECTION_HANDLE* pCriticalSectionHandle);
+XN_C_API XnStatus XN_C_DECL xnOSCloseCriticalSection(XN_CRITICAL_SECTION_HANDLE* pCriticalSectionHandle);
+XN_C_API XnStatus XN_C_DECL xnOSEnterCriticalSection(XN_CRITICAL_SECTION_HANDLE* pCriticalSectionHandle);
+XN_C_API XnStatus XN_C_DECL xnOSLeaveCriticalSection(XN_CRITICAL_SECTION_HANDLE* pCriticalSectionHandle);
+
+// Events
+XN_C_API XnStatus XN_C_DECL xnOSCreateEvent(XN_EVENT_HANDLE* pEventHandle, XnBool bManualReset);
+XN_C_API XnStatus XN_C_DECL xnOSCreateNamedEvent(XN_EVENT_HANDLE* pEventHandle, const XnChar* cpEventName, XnBool bManualReset);
+XN_C_API XnStatus XN_C_DECL xnOSCreateNamedEventEx(XN_EVENT_HANDLE* pEventHandle, const XnChar* cpEventName, XnBool bManualReset, XnBool bAllowOtherUsers);
+XN_C_API XnStatus XN_C_DECL xnOSOpenNamedEvent(XN_EVENT_HANDLE* pEventHandle, const XnChar* cpEventName);
+XN_C_API XnStatus XN_C_DECL xnOSOpenNamedEventEx(XN_EVENT_HANDLE* pEventHandle, const XnChar* cpEventName, XnBool bAllowOtherUsers);
+XN_C_API XnStatus XN_C_DECL xnOSCloseEvent(XN_EVENT_HANDLE* pEventHandle);
+XN_C_API XnStatus XN_C_DECL xnOSSetEvent(const XN_EVENT_HANDLE EventHandle);
+XN_C_API XnStatus XN_C_DECL xnOSResetEvent(const XN_EVENT_HANDLE EventHandle);
+XN_C_API XnStatus XN_C_DECL xnOSWaitEvent(const XN_EVENT_HANDLE EventHandle, XnUInt32 nMilliseconds);
+XN_C_API XnBool XN_C_DECL xnOSIsEventSet(const XN_EVENT_HANDLE EventHandle);
+
+// Semaphores
+XN_C_API XnStatus XN_C_DECL xnOSCreateSemaphore(XN_SEMAPHORE_HANDLE* pSemaphoreHandle, XnUInt32 nInitialCount);
+XN_C_API XnStatus XN_C_DECL xnOSLockSemaphore(XN_SEMAPHORE_HANDLE hSemaphore, XnUInt32 nMilliseconds);
+XN_C_API XnStatus XN_C_DECL xnOSUnlockSemaphore(XN_SEMAPHORE_HANDLE hSemaphore);
+XN_C_API XnStatus XN_C_DECL xnOSCloseSemaphore(XN_SEMAPHORE_HANDLE* pSemaphoreHandle);
+
+/**
+* Waits for a condition to be met. The condition is evaluated every time an event is set.
+*
+* @param EventHandle [in] The Event handle.
+* @param nMilliseconds [in] A timeout in milliseconds to wait.
+* @param pConditionFunc [in] A function that should be called to evaluate condition.
+* @param pConditionData [in] A cookie to be passed to the condition functions.
+*/
+XN_C_API XnStatus XN_C_DECL xnOSWaitForCondition(const XN_EVENT_HANDLE EventHandle, XnUInt32 nMilliseconds, XnConditionFunc pConditionFunc, void* pConditionData);
+
+// Network
+struct xnOSSocket;
+typedef struct xnOSSocket* XN_SOCKET_HANDLE;
+
+#define XN_SOCKET_DEFAULT_TIMEOUT 0xFFFEFFFE
+
+XN_C_API XnStatus XN_C_DECL xnOSInitNetwork();
+XN_C_API XnStatus XN_C_DECL xnOSShutdownNetwork();
+XN_C_API XnStatus XN_C_DECL xnOSCreateSocket(const XnOSSocketType SocketType, const XnChar* cpIPAddress, const XnUInt16 nPort, XN_SOCKET_HANDLE* SocketPtr);
+XN_C_API XnStatus XN_C_DECL xnOSCloseSocket(XN_SOCKET_HANDLE Socket);
+XN_C_API XnStatus XN_C_DECL xnOSBindSocket(XN_SOCKET_HANDLE Socket);
+XN_C_API XnStatus XN_C_DECL xnOSListenSocket(XN_SOCKET_HANDLE Socket);
+XN_C_API XnStatus XN_C_DECL xnOSAcceptSocket(XN_SOCKET_HANDLE ListenSocket, XN_SOCKET_HANDLE* AcceptSocketPtr, XnUInt32 nMillisecsTimeout);
+XN_C_API XnStatus XN_C_DECL xnOSConnectSocket(XN_SOCKET_HANDLE Socket, XnUInt32 nMillisecsTimeout);
+XN_C_API XnStatus XN_C_DECL xnOSSetSocketBufferSize(XN_SOCKET_HANDLE Socket, const XnUInt32 nSocketBufferSize);
+XN_C_API XnStatus XN_C_DECL xnOSSendNetworkBuffer(XN_SOCKET_HANDLE Socket, const XnChar* cpBuffer, const XnUInt32 nBufferSize);
+XN_C_API XnStatus XN_C_DECL xnOSSendToNetworkBuffer(XN_SOCKET_HANDLE Socket, const XnChar* cpBuffer, const XnUInt32 nBufferSize, XN_SOCKET_HANDLE SocketTo);
+XN_C_API XnStatus XN_C_DECL xnOSReceiveNetworkBuffer(XN_SOCKET_HANDLE Socket, XnChar* cpBuffer, XnUInt32* pnBufferSize, XnUInt32 nMillisecsTimeout);
+XN_C_API XnStatus XN_C_DECL xnOSReceiveFromNetworkBuffer(XN_SOCKET_HANDLE Socket, XnChar* cpBuffer, XnUInt32* pnBufferSize, XN_SOCKET_HANDLE* SocketFrom);
+
+// Shared Memory
+typedef struct XnOSSharedMemory XnOSSharedMemory, *XN_SHARED_MEMORY_HANDLE;
+
+/**
+ * Creates a shared memory block and maps it to the process memory.
+ *
+ * @param strName [in] A machine-unique name that will be used by other processes to open this block.
+ * @param nSize [in] The size of the buffer.
+ * @param nAccessFlags [in] Creation flags. Can contain XN_OS_FILE_READ, XN_OS_FILE_WRITE or both.
+ * @param phSharedMem [out] A handle to the shared-memory block.
+ */
+XN_C_API XnStatus XN_C_DECL xnOSCreateSharedMemory(const XnChar* strName, XnUInt32 nSize, XnUInt32 nAccessFlags, XN_SHARED_MEMORY_HANDLE* phSharedMem);
+
+XN_C_API XnStatus XN_C_DECL xnOSCreateSharedMemoryEx(const XnChar* strName, XnUInt32 nSize, XnUInt32 nAccessFlags, XnBool bAllowOtherUsers, XN_SHARED_MEMORY_HANDLE* phSharedMem);
+
+/**
+ * Opens a shared memory block, and returns the address in which it was mapped to the process' memory.
+ *
+ * @param strName [in] A machine-unique name that will be used by other processes to open this block.
+ * @param nAccessFlags [in] Creation flags. Must contain XN_OS_FILE_READ, and optionally XN_OS_FILE_WRITE.
+ * @param phSharedMem [out] A handle to the shared-memory block.
+ */
+XN_C_API XnStatus XN_C_DECL xnOSOpenSharedMemory(const XnChar* strName, XnUInt32 nAccessFlags, XN_SHARED_MEMORY_HANDLE* phSharedMem);
+
+XN_C_API XnStatus XN_C_DECL xnOSOpenSharedMemoryEx(const XnChar* strName, XnUInt32 nAccessFlags, XnBool bAllowOtherUsers, XN_SHARED_MEMORY_HANDLE* phSharedMem);
+
+/**
+ * Closes a shared memory block.
+ *
+ * @param hSharedMem [in] A handle to the block to be closed.
+ */
+XN_C_API XnStatus XN_C_DECL xnOSCloseSharedMemory(XN_SHARED_MEMORY_HANDLE hSharedMem);
+
+/**
+ * Gets the address in which the shared-memory block is mapped in this process.
+ *
+ * @param hSharedMem [in] A handle to the shared memory block.
+ * @param ppAddress [out] The address.
+ */
+XN_C_API XnStatus XN_C_DECL xnOSSharedMemoryGetAddress(XN_SHARED_MEMORY_HANDLE hSharedMem, void** ppAddress);
+
+// Keyboard
+XN_C_API XnBool XN_C_DECL xnOSWasKeyboardHit();
+XN_C_API XnChar XN_C_DECL xnOSReadCharFromInput();
+
+// Debug Utilities
+XN_C_API XnStatus XN_C_DECL xnOSGetCurrentCallStack(XnUInt32 nFramesToSkip, XnChar** astrFrames, XnUInt32 nMaxNameLength, XnUInt32* pnFrames);
+
+XN_STATUS_MESSAGE_MAP_START(XN_ERROR_GROUP_OS)
+XN_STATUS_MESSAGE(XN_STATUS_ALLOC_FAILED, "Memory allocation failed!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_ALREADY_INIT, "Xiron OS already initialized!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_NOT_INIT, "Xiron OS was not initialized!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_FILE_NOT_FOUND, "File not found!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_INI_FILE_NOT_FOUND, "INI file not found!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_FILE_ALREDY_EXISTS, "File already exists!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_FILE_OPEN_FAILED, "Failed to open the file!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_FILE_CLOSE_FAILED, "Failed to close the file!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_FILE_READ_FAILED, "Failed to read from the file!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_FILE_WRITE_FAILED, "Failed to write to the file!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_FILE_SEEK_FAILED, "File seek failed!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_FILE_TELL_FAILED, "File Tell failed!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_FILE_FLUSH_FAILED, "File Flush failed!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_FILE_GET_SIZE_FAILED, "Get File Size failed!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_INI_READ_FAILED, "Failed to read from INI file!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_INI_WRITE_FAILED, "Failed to write into INI file!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_INVALID_SEEK_TYPE, "Invalid seek type!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_THREAD_CREATION_FAILED, "Xiron OS failed to create a thread!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_THREAD_TERMINATION_FAILED, "Xiron OS failed to terminate a thread!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_THREAD_CLOSE_FAILED, "Xiron OS failed to close a thread!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_THREAD_TIMEOUT, "Xiron OS got a thread timeout while waiting for a thread to exit!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_THREAD_WAIT_FAILED, "Xiron OS failed to wait for a thread to exit!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_THREAD_SET_PRIORITY_FAILED, "Xiron OS failed to set priority of a thread!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_THREAD_UNSUPPORTED_PRIORITY, "Thread priority is unsupported by Xiron OS!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_MUTEX_CREATION_FAILED, "Xiron OS failed to create a mutex!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_MUTEX_CLOSE_FAILED, "Xiron OS failed to close a mutex!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_MUTEX_LOCK_FAILED, "Xiron OS failed to lock a mutex!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_MUTEX_TIMEOUT, "Xiron OS got a mutex timeout!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_MUTEX_UNLOCK_FAILED, "Xiron OS failed to unlock a mutex!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_EVENT_CREATION_FAILED, "Xiron OS failed to create an event!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_EVENT_CLOSE_FAILED, "Xiron OS failed to close an event!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_EVENT_SET_FAILED, "Xiron OS failed to set an event!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_EVENT_RESET_FAILED, "Xiron OS failed to reset an event!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_EVENT_TIMEOUT, "Xiron OS got an event timeout!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_EVENT_WAIT_FAILED, "Xiron OS failed to wait on event!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_EVENT_CANCELED, "This Xiron OS event was canceled!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_CANT_LOAD_LIB, "Xiron OS failed to load shared library!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_CANT_FREE_LIB, "Xiron OS failed to free shared library!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_PROC_NOT_FOUND, "Xiron OS failed to get procedure address from shared library!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_NETWORK_INIT_FAILED, "Xiron OS failed to initialize the network subsystem!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_NETWORK_SHUTDOWN_FAILED, "Xiron OS failed to shutdown the network subsystem!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_NETWORK_SOCKET_CREATION_FAILED, "Xiron OS failed to create a network socket!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_NETWORK_INVALID_SOCKET_TYPE, "Invalid Xiron OS socket type!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_NETWORK_SOCKET_BUFFER_FAILED, "Failed to change the Xiron OS socket buffer size!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_NETWORK_SEND_FAILED, "Xiron OS failed to send a network buffer!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_NETWORK_RECEIVE_FAILED, "Xiron OS failed to receive a network buffer!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_NETWORK_SOCKET_BIND_FAILED, "Xiron OS failed to bind a network socket!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_NETWORK_SOCKET_LISTEN_FAILED, "Xiron OS failed to listen on a network socket!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_NETWORK_SOCKET_ACCEPT_FAILED, "Xiron OS failed to accept a network socket!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_NETWORK_SOCKET_CONNECT_FAILED, "Xiron OS failed to connect to a network socket!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_NETWORK_BAD_HOST_NAME, "Failed to resolve the host name!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_NETWORK_TIMEOUT, "Got a timeout while waiting for a network command to complete!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_TIMER_CREATION_FAILED, "Xiron OS failed to create a timer!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_TIMER_QUERY_FAILED, "Xiron OS failed to query a timer!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_INVALID_TIMER, "This Xiron OS timer is invalid!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_INVALID_FILE, "This Xiron OS file is invalid!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_INVALID_SOCKET, "This Xiron OS socket is invalid!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_INVALID_MUTEX, "This Xiron OS mutex is invalid!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_INVALID_THREAD, "This Xiron OS thread is invalid!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_INVALID_EVENT, "This Xiron OS event is invalid!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_INVALID_LIBRARY, "This Xiron OS shared library is invalid!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_INVALID_CRITICAL_SECTION, "This Xiron OS critical section is invalid!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_INVALID_FORMAT_STRING, "Xiron OS got an invalid format string!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_UNSUPPORTED_FUNCTION, "This Xiron OS function is not supported!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_FAILED_TO_CREATE_DIR, "Failed to create a directory!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_FAILED_TO_DELETE_FILE, "Failed to delete a file!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_FAILED_TO_CREATE_SHARED_MEMORY, "Failed to create shared memory!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_FAILED_TO_OPEN_SHARED_MEMORY, "Failed to open shared memory!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_FAILED_TO_CLOSE_SHARED_MEMORY, "Failed to close shared memory!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_ALREADY_INIT, "The Xiron USB subsystem was already initialize!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_NOT_INIT, "The Xiron USB subsystem was not initialized!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_INIT_FAILED, "The Xiron USB subsystem failed to initialize!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_SHUTDOWN_FAILED, "The Xiron USB subsystem failed to shutdown!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_ENUMERATE_FAILED, "The Xiron USB subsystem failed to enumerate devices!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_LOAD_FAILED, "The Xiron USB subsystem failed to load!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_FREE_FAILED, "The Xiron USB subsystem failed to free!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_REGISTER_FAILED, "The Xiron USB subsystem failed to register the device!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_UNREGISTER_FAILED, "The Xiron USB subsystem failed to unregister the device!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_DEVICE_NOT_VALID, "Invalid Xiron USB device handle!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_ENDPOINT_NOT_VALID, "Invalid Xiron USB endpoint handle!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_DRIVER_NOT_FOUND, "USB driver not found!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_DEVICE_NOT_FOUND, "USB device not found!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_DEVICE_OPEN_FAILED, "Failed to open the USB device!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_DEVICE_CLOSE_FAILED, "Failed to close the USB device!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_DEVICE_GETINFO_FAILED, "Failed to get information about the USB device!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_CONFIG_QUERY_FAILED, "USB config query failed!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_INTERFACE_QUERY_FAILED, "USB interface query failed!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_ENDPOINT_QUERY_FAILED, "USB endpoint query failed!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_SET_ENDPOINT_POLICY_FAILED, "Failed to set USB endpoint policy!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_UNKNOWN_ENDPOINT_TYPE, "Unknown USB endpoint type!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_UNKNOWN_ENDPOINT_DIRECTION, "Unknown USB endpoint direction!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_GET_SPEED_FAILED, "Failed to get the device speed!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_GET_DRIVER_VERSION, "Failed to get the USB driver version!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_UNKNOWN_DEVICE_SPEED, "Unknown USB device speed!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_CONTROL_SEND_FAILED, "Failed to send a USB control request!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_CONTROL_RECV_FAILED, "Failed to receive a USB control request!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_ENDPOINT_READ_FAILED, "Failed to read from a USB endpoint!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_ENDPOINT_WRITE_FAILED, "Failed to write into a USB endpoint!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_TRANSFER_TIMEOUT, "USB transfer timeout!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_TRANSFER_STALL, "USB transfer stall!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_TRANSFER_MICRO_FRAME_ERROR, "USB transfer micro frame error!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_TRANSFER_UNKNOWN_ERROR, "Unknown USB transfer error!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_ENDPOINT_NOT_FOUND, "USB endpoint not found on device!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_WRONG_ENDPOINT_TYPE, "Wrong USB endpoint type requested!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_WRONG_ENDPOINT_DIRECTION, "Wrong USB endpoint direction requested!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_WRONG_CONTROL_TYPE, "Wrong USB control type requested!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_UNSUPPORTED_ENDPOINT_TYPE, "Unsupported USB endpoint type!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_GOT_UNEXPECTED_BYTES, "Got unexpected bytes in USB transfer!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_TOO_MUCH_DATA, "Got too much data in USB transfer!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_NOT_ENOUGH_DATA, "Didn't get enough data in USB transfer!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_BUFFER_TOO_SMALL, "USB Buffer is too small!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_OVERLAPIO_FAILED, "USB Overlapped I/O operation failed!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_ABORT_FAILED, "Failed to abort USB endpoint!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_FLUSH_FAILED, "Failed to flush USB endpoint!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_RESET_FAILED, "Failed to reset USB endpoint!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_SET_INTERFACE_FAILED, "Failed to set USB interface!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_GET_INTERFACE_FAILED, "Failed to get USB interface!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_READTHREAD_NOT_INIT, "Read thread is not initialized for this USB end point!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_READTHREAD_ALREADY_INIT, "Read thread is already initialized for this USB end point!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_READTHREAD_SHUTDOWN_FAILED, "Read thread failed to shutdown properly!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_IS_BUSY, "USB is busy!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_NOT_BUSY, "USB is not busy!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_SET_CONFIG_FAILED, "Failed to set USB config!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_GET_CONFIG_FAILED, "Failed to get USB config!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_OPEN_ENDPOINT_FAILED, "Failed to open an USB endpoint!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_CLOSE_ENDPOINT_FAILED, "Failed to close an USB endpoint!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_ALREADY_OPEN, "A device is already opened!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_TRANSFER_PENDING, "USB transfer is still pending!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_INTERFACE_NOT_SUPPORTED, "USB interface is not supported!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_FAILED_TO_REGISTER_CALLBACK, "Failed to register the USB device callback!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_NETWORK_CONNECTION_CLOSED, "The network connection has been closed!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_EVENT_OPEN_FAILED, "Xiron OS failed to open an event!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_PROCESS_CREATION_FAILED, "Xiron OS failed to create a process!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_SEMAPHORE_CREATION_FAILED, "Xiron OS Failed to create a semaphore!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_SEMAPHORE_CLOSE_FAILED, "Xiron OS failed to close a semaphore!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_SEMAPHORE_LOCK_FAILED, "Xiron OS failed to lock a semaphore!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_SEMAPHORE_UNLOCK_FAILED, "Xiron OS failed to unlock a semaphore!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_SEMAPHORE_TIMEOUT, "Xiron OS got a semaphore timeout!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_INVALID_SEMAPHORE, "This Xiron OS semaphore is invalid!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_ENV_VAR_NOT_FOUND, "The environment variable could not be found!")
+XN_STATUS_MESSAGE(XN_STATUS_USB_NO_REQUEST_PENDING, "There is no request pending!")
+XN_STATUS_MESSAGE(XN_STATUS_OS_FAILED_TO_DELETE_DIR, "Failed to delete a directory!")
+XN_STATUS_MESSAGE_MAP_END(XN_ERROR_GROUP_OS)
+
+#endif //__XN_OS_H__
+
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnOSCpp.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnOSCpp.h
new file mode 100644
index 00000000..4058feb7
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnOSCpp.h
@@ -0,0 +1,163 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef __XN_OS_CPP_H__
+#define __XN_OS_CPP_H__
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include <XnOS.h>
+
+//---------------------------------------------------------------------------
+// Types
+//---------------------------------------------------------------------------
+class XnAutoCSLocker
+{
+public:
+ inline XnAutoCSLocker(const XnAutoCSLocker& other) : m_hCS(other.m_hCS), m_bLocked(FALSE)
+ {
+ Lock();
+ }
+
+ inline XnAutoCSLocker& operator=(const XnAutoCSLocker& other)
+ {
+ Unlock();
+ m_hCS = other.m_hCS;
+ Lock();
+ return *this;
+ }
+
+ inline XnAutoCSLocker(XN_CRITICAL_SECTION_HANDLE hCS) : m_hCS(hCS), m_bLocked(FALSE)
+ {
+ Lock();
+ }
+
+ inline ~XnAutoCSLocker()
+ {
+ Unlock();
+ }
+
+ inline void Lock()
+ {
+ if (!m_bLocked)
+ {
+ xnOSEnterCriticalSection(&m_hCS);
+ m_bLocked = TRUE;
+ }
+ }
+
+ inline void Unlock()
+ {
+ if (m_bLocked)
+ {
+ xnOSLeaveCriticalSection(&m_hCS);
+ m_bLocked = FALSE;
+ }
+ }
+
+private:
+ XN_CRITICAL_SECTION_HANDLE m_hCS;
+ XnBool m_bLocked;
+};
+
+class XnAutoMutexLocker
+{
+public:
+ inline XnAutoMutexLocker(XN_MUTEX_HANDLE hMutex, XnUInt32 nMilliseconds) : m_hMutex(hMutex)
+ {
+ m_nStatus = xnOSLockMutex(m_hMutex, nMilliseconds);
+ }
+
+ XnStatus GetStatus() const
+ {
+ return m_nStatus;
+ }
+
+ inline ~XnAutoMutexLocker()
+ {
+ if (m_nStatus == XN_STATUS_OK)
+ {
+ //Only unlock if we managed to lock in the first place
+ xnOSUnLockMutex(m_hMutex);
+ }
+ }
+
+private:
+ XN_MUTEX_HANDLE m_hMutex;
+ XnStatus m_nStatus;
+};
+
+class XnOSEvent
+{
+public:
+ XnOSEvent() : m_hEvent(NULL) {}
+
+ ~XnOSEvent()
+ {
+ Close();
+ }
+
+ operator XN_EVENT_HANDLE() const
+ {
+ return m_hEvent;
+ }
+
+ XnStatus Create(XnBool bManualReset)
+ {
+ return xnOSCreateEvent(&m_hEvent, bManualReset);
+ }
+
+ XnStatus Create(const XnChar* strName, XnBool bManualReset, XnBool bAllowOtherUsers = FALSE)
+ {
+ return xnOSCreateNamedEventEx(&m_hEvent, strName, bManualReset, bAllowOtherUsers);
+ }
+
+ XnStatus Open(const XnChar* strName, XnBool bEnableOtherUsers = FALSE)
+ {
+ return xnOSOpenNamedEventEx(&m_hEvent, strName, bEnableOtherUsers);
+ }
+
+ XnStatus Close()
+ {
+ return (m_hEvent != NULL) ? xnOSCloseEvent(&m_hEvent) : XN_STATUS_OK;
+ }
+
+ XnStatus Set()
+ {
+ return xnOSSetEvent(m_hEvent);
+ }
+
+ XnStatus Reset()
+ {
+ return xnOSResetEvent(m_hEvent);
+ }
+
+ XnStatus Wait(XnUInt32 nMilliseconds)
+ {
+ return xnOSWaitEvent(m_hEvent, nMilliseconds);
+ }
+
+private:
+ XN_EVENT_HANDLE m_hEvent;
+};
+
+#endif // __XN_OS_CPP_H__
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnOSMemory.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnOSMemory.h
new file mode 100644
index 00000000..183e4775
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnOSMemory.h
@@ -0,0 +1,47 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef __XNOSMEMORY_H__
+#define __XNOSMEMORY_H__
+
+#include "XnPlatform.h"
+
+// Memory
+XN_C_API void* XN_C_DECL xnOSMalloc(const XnSizeT nAllocSize);
+XN_C_API void* XN_C_DECL xnOSMallocAligned(const XnSizeT nAllocSize, const XnSizeT nAlignment);
+XN_C_API void* XN_C_DECL xnOSCalloc(const XnSizeT nAllocNum, const XnSizeT nAllocSize);
+XN_C_API void* XN_C_DECL xnOSCallocAligned(const XnSizeT nAllocNum, const XnSizeT nAllocSize, const XnSizeT nAlignment);
+XN_C_API void* XN_C_DECL xnOSRealloc(void* pMemory, const XnSizeT nAllocSize);
+XN_C_API void* XN_C_DECL xnOSReallocAligned(void* pMemory, const XnSizeT nAllocSize, const XnSizeT nAlignment);
+XN_C_API void* XN_C_DECL xnOSRecalloc(void* pMemory, const XnSizeT nAllocNum, const XnSizeT nAllocSize);
+XN_C_API void XN_C_DECL xnOSFree(const void* pMemBlock);
+XN_C_API void XN_C_DECL xnOSFreeAligned(const void* pMemBlock);
+XN_C_API void XN_C_DECL xnOSMemCopy(void* pDest, const void* pSource, XnSizeT nCount);
+XN_C_API XnInt32 XN_C_DECL xnOSMemCmp(const void *pBuf1, const void *pBuf2, XnSizeT nCount);
+XN_C_API void XN_C_DECL xnOSMemSet(void* pDest, XnUInt8 nValue, XnSizeT nCount);
+XN_C_API void XN_C_DECL xnOSMemMove(void* pDest, const void* pSource, XnSizeT nCount);
+XN_C_API XnUInt64 XN_C_DECL xnOSEndianSwapUINT64(XnUInt64 nValue);
+XN_C_API XnUInt32 XN_C_DECL xnOSEndianSwapUINT32(XnUInt32 nValue);
+XN_C_API XnUInt16 XN_C_DECL xnOSEndianSwapUINT16(XnUInt16 nValue);
+XN_C_API XnFloat XN_C_DECL xnOSEndianSwapFLOAT(XnFloat fValue);
+
+
+#endif // __XNOSMEMORY_H__
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnOSStrings.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnOSStrings.h
new file mode 100644
index 00000000..351904c4
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnOSStrings.h
@@ -0,0 +1,47 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef __XNOSSTRINGS_H__
+#define __XNOSSTRINGS_H__
+
+#include "XnPlatform.h"
+#include <stdarg.h>
+
+// Strings
+XN_C_API XnStatus XN_C_DECL xnOSStrPrefix(const XnChar* cpPrefixString, XnChar* cpDestString, const XnUInt32 nDestLength);
+XN_C_API XnStatus XN_C_DECL xnOSStrAppend(XnChar* cpDestString, const XnChar* cpSrcString, const XnUInt32 nDestLength);
+XN_C_API XnStatus XN_C_DECL xnOSStrCopy(XnChar* cpDestString, const XnChar* cpSrcString, const XnUInt32 nDestLength);
+XN_C_API XnUInt32 XN_C_DECL xnOSStrLen(const XnChar* cpStr);
+XN_C_API XnStatus XN_C_DECL xnOSStrNCopy(XnChar* cpDestString, const XnChar* cpSrcString, const XnUInt32 nCopyLength, const XnUInt32 nDestLength);
+XN_C_API XnStatus XN_C_DECL xnOSStrCRC32(const XnChar* cpString, XnUInt32* nCRC32);
+XN_C_API XnStatus XN_C_DECL xnOSStrNCRC32(XnUChar* cpBuffer, XnUInt32 nBufferSize, XnUInt32* nCRC32);
+XN_C_API XnStatus XN_C_DECL xnOSStrFormat(XnChar* cpDestString, const XnUInt32 nDestLength, XnUInt32* pnCharsWritten, const XnChar* cpFormat, ...);
+XN_C_API XnStatus XN_C_DECL xnOSStrFormatV(XnChar* cpDestString, const XnUInt32 nDestLength, XnUInt32* pnCharsWritten, const XnChar* cpFormat, va_list args);
+XN_C_API XnInt32 XN_C_DECL xnOSStrCmp(const XnChar* cpFirstString, const XnChar* cpSecondString);
+XN_C_API XnInt32 XN_C_DECL xnOSStrCaseCmp(const XnChar* cpFirstString, const XnChar* cpSecondString);
+XN_C_API void XN_C_DECL xnOSItoA(XnInt32 nValue, XnChar* cpStr, XnInt32 nBase);
+/** Should be freed using @ref xnOSFree() */
+XN_C_API XnChar* XN_C_DECL xnOSStrDup(const XnChar* strSource);
+XN_C_API XnStatus XN_C_DECL xnOSGetEnvironmentVariable(const XnChar* strEnv, XnChar* strDest, XnUInt32 nDestSize);
+XN_C_API XnStatus XN_C_DECL xnOSExpandEnvironmentStrings(const XnChar* strSrc, XnChar* strDest, XnUInt32 nDestSize);
+
+
+#endif // __XNOSSTRINGS_H__ \ No newline at end of file
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnOpenNI.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnOpenNI.h
new file mode 100644
index 00000000..13b5ff28
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnOpenNI.h
@@ -0,0 +1,50 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef __XN_OPEN_NI_H__
+#define __XN_OPEN_NI_H__
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include "XnTypes.h"
+#include "XnContext.h"
+#include "XnLicensing.h"
+#include "XnUtils.h"
+#include "XnPrdNodeInfo.h"
+#include "XnQueries.h"
+#include "XnPrdNode.h"
+#include "XnEnumerationErrors.h"
+
+#include "XnVersion.h"
+#include "XnStatusCodes.h"
+#include "XnStatus.h"
+
+//---------------------------------------------------------------------------
+// Defines
+//---------------------------------------------------------------------------
+#define XN_MASK_OPEN_NI "OpenNI"
+
+//---------------------------------------------------------------------------
+// Enumeration and Creations
+//---------------------------------------------------------------------------
+
+#endif // __XN_OPEN_NI_H__
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnPlatform.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnPlatform.h
new file mode 100644
index 00000000..d60d9580
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnPlatform.h
@@ -0,0 +1,124 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef __XN_PLATFORM_H__
+#define __XN_PLATFORM_H__
+
+//---------------------------------------------------------------------------
+// Platform Defines
+//---------------------------------------------------------------------------
+#define XN_PLATFORM_WIN32 1
+#define XN_PLATFORM_XBOX360 2
+#define XN_PLATFORM_PS3 3
+#define XN_PLATFORM_WII 4
+#define XN_PLATFORM_LINUX_X86 5
+#define XN_PLATFORM_FILES_ONLY 6
+#define XN_PLATFORM_ARC 6
+#define XN_PLATFORM_LINUX_ARM 7
+#define XN_PLATFORM_MACOSX 8
+#define XN_PLATFORM_ANDROID_ARM 9
+
+#define XN_PLATFORM_IS_LITTLE_ENDIAN 1
+#define XN_PLATFORM_IS_BIG_ENDIAN 2
+
+#define XN_PLATFORM_USE_NO_VAARGS 1
+#define XN_PLATFORM_USE_WIN32_VAARGS_STYLE 2
+#define XN_PLATFORM_USE_GCC_VAARGS_STYLE 3
+#define XN_PLATFORM_USE_ARC_VAARGS_STYLE 4
+
+//---------------------------------------------------------------------------
+// Platform Identifier
+//---------------------------------------------------------------------------
+
+#if defined(__MINGW32__) // gcc-windows
+ #include "mingw-win32/XnPlatformLinux-x86.h"
+#elif (_WIN32) // Microsoft Visual Studio
+ #ifndef RC_INVOKED
+ #if _MSC_VER < 1300 // Before MSVC7 (2003)
+ #error Xiron Platform Abstraction Layer - Win32 - Microsoft Visual Studio versions below 2003 (7.0) are not supported!
+ #endif
+
+ #if _MSC_VER > 1600 // After MSVC8 (2010)
+ #error Xiron Platform Abstraction Layer - Win32 - Microsoft Visual Studio versions above 2010 (10.0) are not supported!
+ #endif
+ #endif
+
+ #include "Win32/XnPlatformWin32.h"
+#elif defined(ANDROID) && defined(__arm__)
+ #include "Android-Arm/XnPlatformAndroid-Arm.h"
+#elif (linux && (i386 || __x86_64__))
+ #include "Linux-x86/XnPlatformLinux-x86.h"
+#elif (linux && __arm__)
+ #include "Linux-Arm/XnPlatformLinux-Arm.h"
+#elif _ARC
+ #include "ARC/XnPlatformARC.h"
+#elif (__APPLE__)
+ #include "MacOSX/XnPlatformMacOSX.h"
+#else
+ #error OpenNI Platform Abstraction Layer - Unsupported Platform!
+#endif
+
+//---------------------------------------------------------------------------
+// Basic Common Macros
+//---------------------------------------------------------------------------
+#ifndef TRUE
+ #define TRUE 1
+#endif
+
+#ifndef FALSE
+ #define FALSE 0
+#endif
+
+#define XN_MIN(a,b) (((a) < (b)) ? (a) : (b))
+
+#define XN_MAX(a,b) (((a) > (b)) ? (a) : (b))
+
+typedef void (*XnFuncPtr)();
+
+#define XN_COMPILER_ASSERT(x) typedef int compileAssert[x ? 1 : -1]
+
+struct XnRegistrationHandleImpl;
+typedef struct XnRegistrationHandleImpl* XnRegistrationHandle;
+
+//---------------------------------------------------------------------------
+// API Export/Import Macros
+//---------------------------------------------------------------------------
+
+#ifdef __cplusplus
+ #define XN_C_API_EXPORT extern "C" XN_API_EXPORT
+ #define XN_C_API_IMPORT extern "C" XN_API_IMPORT
+ #define XN_CPP_API_EXPORT XN_API_EXPORT
+ #define XN_CPP_API_IMPORT XN_API_IMPORT
+#else
+ #define XN_C_API_EXPORT XN_API_EXPORT
+ #define XN_C_API_IMPORT XN_API_IMPORT
+#endif
+
+#ifdef XN_EXPORTS
+ #define XN_C_API XN_C_API_EXPORT
+ #define XN_CPP_API XN_CPP_API_EXPORT
+#else
+ #define XN_C_API XN_C_API_IMPORT
+ #define XN_CPP_API XN_CPP_API_IMPORT
+#endif
+
+#endif //__XN_PLATFORM_H__
+
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnPrdNode.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnPrdNode.h
new file mode 100644
index 00000000..1c491be8
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnPrdNode.h
@@ -0,0 +1,2614 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef __XN_PRD_NODE_H__
+#define __XN_PRD_NODE_H__
+
+/**
+ * @ingroup cref
+ * @defgroup prd_node Production Nodes Functionality
+ * This page details functions that can be run on production nodes.
+ */
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include <XnTypes.h>
+
+//---------------------------------------------------------------------------
+// Functions
+//---------------------------------------------------------------------------
+
+/**
+ * @ingroup prd_node
+ * @defgroup node Production Node
+ *
+ * A production node is the most basic unit of processing in OpenNI. The following functions can be
+ * executed for every node in an OpenNI context.
+ * @{
+ */
+
+/**
+ * @brief Gets information about a specific node, like its description, and dependent nodes.
+ *
+ * @param hNode [in] A handle to the node.
+ */
+XN_C_API XnNodeInfo* XN_C_DECL xnGetNodeInfo(XnNodeHandle hNode);
+
+/**
+ * @brief Gets the instance name of a node by its handle.
+ *
+ * @param hNode [in] A handle to the node.
+ */
+XN_C_API const XnChar* XN_C_DECL xnGetNodeName(XnNodeHandle hNode);
+
+/**
+ * @brief Gets the context a node belongs to. The context ref count is increased. The user
+ * is responsible for releasing the context when it's no longer used.
+ *
+ * @param hNode [in] A handle to the node.
+ */
+XN_C_API XnContext* XN_C_DECL xnGetRefContextFromNodeHandle(XnNodeHandle hNode);
+
+typedef XnContext* XnContextPtr;
+XN_C_API XnContextPtr XN_API_DEPRECATED("Please use xnGetRefContextFromNodeHandle() instead") XN_C_DECL xnGetContextFromNodeHandle(XnNodeHandle hNode);
+
+/**
+ * @brief Checks if a production node supports specific capability.
+ *
+ * @param hInstance [in] A handle to the instance to be queried.
+ * @param strCapabilityName [in] The name of the capability to check.
+ */
+XN_C_API XnBool XN_C_DECL xnIsCapabilitySupported(XnNodeHandle hInstance, const XnChar* strCapabilityName);
+
+/**
+ * @brief Sets an integer property.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param strName [in] Property name
+ * @param nValue [in] New value
+ */
+XN_C_API XnStatus XN_C_DECL xnSetIntProperty(XnNodeHandle hInstance, const XnChar* strName, XnUInt64 nValue);
+/**
+ * @brief Sets a real property.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param strName [in] Property name
+ * @param dValue [in] New value
+ */
+XN_C_API XnStatus XN_C_DECL xnSetRealProperty(XnNodeHandle hInstance, const XnChar* strName, XnDouble dValue);
+/**
+ * @brief Sets a string property.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param strName [in] Property name
+ * @param strValue [in] New value
+ */
+XN_C_API XnStatus XN_C_DECL xnSetStringProperty(XnNodeHandle hInstance, const XnChar* strName, const XnChar* strValue);
+/**
+ * @brief Sets a buffer property.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param strName [in] Property name
+ * @param nBufferSize [in] The size of the buffer passed, in bytes.
+ * @param pBuffer [in] The data buffer.
+ */
+XN_C_API XnStatus XN_C_DECL xnSetGeneralProperty(XnNodeHandle hInstance, const XnChar* strName, XnUInt32 nBufferSize, const void* pBuffer);
+
+/**
+ * @brief Gets an integer property.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param strName [in] Property name
+ * @param pnValue [out] Current value
+ */
+XN_C_API XnStatus XN_C_DECL xnGetIntProperty(XnNodeHandle hInstance, const XnChar* strName, XnUInt64* pnValue);
+/**
+ * @brief Gets a real property.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param strName [in] Property name
+ * @param pdValue [out] Current value
+ */
+XN_C_API XnStatus XN_C_DECL xnGetRealProperty(XnNodeHandle hInstance, const XnChar* strName, XnDouble* pdValue);
+/**
+ * @brief Gets a string property.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param strName [in] Property name
+ * @param csValue [out] Current value
+ * @param nBufSize [in] The size of the csValue buffer.
+ */
+XN_C_API XnStatus XN_C_DECL xnGetStringProperty(XnNodeHandle hInstance, const XnChar* strName, XnChar* csValue, XnUInt32 nBufSize);
+/**
+ * @brief Gets a buffer property.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param strName [in] Property name
+ * @param nBufferSize [in] The size of the buffer passed, in bytes.
+ * @param pBuffer [in] The data buffer to be filled.
+ */
+XN_C_API XnStatus XN_C_DECL xnGetGeneralProperty(XnNodeHandle hInstance, const XnChar* strName, XnUInt32 nBufferSize, void* pBuffer);
+
+/**
+ * @brief Locks a node, not allowing any changes (any "set" function).
+ *
+ * @param hInstance [in] A handle to the node.
+ * @param phLock [out] A handle of the lock, that can be used to manage the lock.
+ */
+XN_C_API XnStatus XN_C_DECL xnLockNodeForChanges(XnNodeHandle hInstance, XnLockHandle* phLock);
+
+/**
+ * @brief Unlocks a previously locked node.
+ *
+ * @param hInstance [in] A handle to the node.
+ * @param hLock [in] The handle of the lock, returned from @ref xnLockNodeForChanges().
+ */
+XN_C_API XnStatus XN_C_DECL xnUnlockNodeForChanges(XnNodeHandle hInstance, XnLockHandle hLock);
+
+/**
+ * @brief Start changes request on a locked node, without releasing that lock.
+ *
+ * It allows "set" operations from the same context (same thread for that matter) until a call is made to
+ * @ref xnLockedNodeEndChanges().
+ *
+ * @param hInstance [in] A handle to the node.
+ * @param hLock [in] The handle of the lock, returned from @ref xnLockNodeForChanges().
+ */
+XN_C_API XnStatus XN_C_DECL xnLockedNodeStartChanges(XnNodeHandle hInstance, XnLockHandle hLock);
+
+/**
+ * @brief Ends changes request on a locked node.
+ *
+ * @param hInstance [in] A handle to the node.
+ * @param hLock [in] The handle of the lock, returned from @ref xnLockNodeForChanges().
+ */
+XN_C_API XnStatus XN_C_DECL xnLockedNodeEndChanges(XnNodeHandle hInstance, XnLockHandle hLock);
+
+/**
+ * @brief Adds another node to the list of needed nodes for this node.
+ *
+ * @param hInstance [in] A handle to the node.
+ * @param hNeededNode [in] The node that is needed by hInstance.
+ */
+XN_C_API XnStatus XN_C_DECL xnAddNeededNode(XnNodeHandle hInstance, XnNodeHandle hNeededNode);
+
+/**
+ * @brief Removes a needed node from the list of needed nodes.
+ *
+ * If this node is no longer needed by any other node, and @ref xnRefProductionNode() was not called on it,
+ * it will be destroyed.
+ *
+ * @param hInstance [in] A handle to the node.
+ * @param hNeededNode [in] The node to be removed from the list.
+ */
+XN_C_API XnStatus XN_C_DECL xnRemoveNeededNode(XnNodeHandle hInstance, XnNodeHandle hNeededNode);
+
+/** @} */
+
+//---------------------------------------------------------------------------
+// Device
+//---------------------------------------------------------------------------
+
+/**
+ * @ingroup prd_node
+ * @defgroup device Device
+ *
+ * A device node represents a physical device. The following functions can be
+ * executed for device nodes in an OpenNI context.
+ * @{
+ */
+
+/**
+ * @brief Creates a device node.
+ *
+ * @param pContext [in] The context in which to create the device
+ * @param phDevice [out] A handle to the created device
+ * @param pQuery [in] Optional. Can be used to select which device to create. If not specified, this function may create any device node that is available.
+ * @param pErrors [in] Optional. If provided, will be filled with information about device nodes that could not be created.
+ */
+XN_C_API XnStatus XN_C_DECL xnCreateDevice(XnContext* pContext, XnNodeHandle* phDevice, XnNodeQuery* pQuery, XnEnumerationErrors* pErrors);
+
+/** @} */
+
+//---------------------------------------------------------------------------
+// Device Identification Capability
+//---------------------------------------------------------------------------
+
+/**
+ * @ingroup device
+ * @defgroup device_id Device Identification Capability
+ *
+ * The Device Identification Capability (@ref XN_CAPABILITY_DEVICE_IDENTIFICATION) allows to identify
+ * the device according to its name, to a vendor-specific string and its serial number.
+ * @{
+ */
+
+/**
+ * Gets the device name.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param strBuffer [in] A buffer to accept the device name.
+ * @param pnBufferSize [in/out] Size of the buffer.
+ *
+ * @returns XN_STATUS_OK if succeeded, or XN_STATUS_OUTPUT_BUFFER_OVERFLOW if buffer is not sufficient.
+ * in such a case, the device name should be truncated to fit in the buffer, and pnBufferSize should be
+ * updated to the required size.
+ */
+XN_C_API XnStatus XN_C_DECL xnGetDeviceName(XnNodeHandle hInstance, XnChar* strBuffer, XnUInt32* pnBufferSize);
+
+/**
+ * Gets a vendor-specific string.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param strBuffer [in] A buffer to accept the string.
+ * @param pnBufferSize [in/out] Size of the buffer.
+ *
+ * @returns XN_STATUS_OK if succeeded, or XN_STATUS_OUTPUT_BUFFER_OVERFLOW if buffer is not sufficient.
+ * in such a case, the string should be truncated to fit in the buffer, and pnBufferSize should be
+ * updated to the required size.
+ */
+XN_C_API XnStatus XN_C_DECL xnGetVendorSpecificData(XnNodeHandle hInstance, XnChar* strBuffer, XnUInt32* pnBufferSize);
+
+/**
+ * Gets the serial number of the device.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param strBuffer [in] A buffer to accept the string.
+ * @param pnBufferSize [in/out] Size of the buffer.
+ *
+ * @returns XN_STATUS_OK if succeeded, or XN_STATUS_OUTPUT_BUFFER_OVERFLOW if buffer is not sufficient.
+ * in such a case, the string should be truncated to fit in the buffer, and pnBufferSize should be
+ * updated to the required size.
+ */
+XN_C_API XnStatus XN_C_DECL xnGetSerialNumber(XnNodeHandle hInstance, XnChar* strBuffer, XnUInt32* pnBufferSize);
+
+/** @} */
+
+//---------------------------------------------------------------------------
+// ErrorState Capability
+//---------------------------------------------------------------------------
+
+/**
+ * @ingroup node
+ * @defgroup err_state Error State Capability
+ *
+ * The Error State capability (@ref XN_CAPABILITY_ERROR_STATE) allows a node to report it is now in
+ * an error state, and so, might not function correctly. An application may, at all times, check the
+ * error state of a node, and it may also register a callback function to be called whenever that state
+ * changes.
+ *
+ * The error state of a node is represented using @ref XnStatus. A value of XN_STATUS_OK means the node
+ * is OK. Any other value represents some sort of error situation in the node.
+ * @{
+ */
+
+/**
+ * @brief Gets current error state of this node.
+ *
+ * @param hInstance [in] A handle to the instance.
+ *
+ * @returns The error state of this node.
+ */
+XN_C_API XnStatus XN_C_DECL xnGetNodeErrorState(XnNodeHandle hInstance);
+
+/**
+ * @brief Registers a callback function to error state changes.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param handler [in] A pointer to a function that will be called when error state changes.
+ * @param pCookie [in] A user cookie that will be passed to the callback function.
+ * @param phCallback [out] Optional. Will be filled with a handle to be passed to @ref xnUnregisterFromNodeErrorStateChange().
+ */
+XN_C_API XnStatus XN_C_DECL xnRegisterToNodeErrorStateChange
+ (XnNodeHandle hInstance, XnStateChangedHandler handler,
+ void* pCookie, XnCallbackHandle* phCallback);
+
+/**
+ * @brief Unregisters a callback function which was registered using @ref xnRegisterToNodeErrorStateChange().
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param hCallback [in] The handle to the callback returned from @ref xnRegisterToNodeErrorStateChange().
+ */
+XN_C_API void XN_C_DECL xnUnregisterFromNodeErrorStateChange
+ (XnNodeHandle hInstance, XnCallbackHandle hCallback);
+
+/** @} */
+
+//---------------------------------------------------------------------------
+// GeneralIntCapability
+//---------------------------------------------------------------------------
+
+/**
+ * @ingroup node
+ * @defgroup general_int General Int Capability
+ *
+ * The General Int Capability is a set of method that is used by several capabilities. It allows
+ * a general range value to be changed. If supported by the node, the value can also be set to
+ * @ref XN_AUTO_CONTROL for automatic adjustment.
+ *
+ * The capabilities supporting this interface are:
+ * - Brightness (@ref XN_CAPABILITY_BRIGHTNESS)
+ * - Contrast (@ref XN_CAPABILITY_CONTRAST)
+ * - Hue (@ref XN_CAPABILITY_HUE)
+ * - Saturation (@ref XN_CAPABILITY_SATURATION)
+ * - Sharpness (@ref XN_CAPABILITY_SHARPNESS)
+ * - Gamma (@ref XN_CAPABILITY_GAMMA)
+ * - WhiteBalance (@ref XN_CAPABILITY_COLOR_TEMPERATURE)
+ * - BacklightCompensation (@ref XN_CAPABILITY_BACKLIGHT_COMPENSATION)
+ * - Gain (@ref XN_CAPABILITY_GAIN)
+ * - Pan (@ref XN_CAPABILITY_PAN)
+ * - Tilt (@ref XN_CAPABILITY_TILT)
+ * - Roll (@ref XN_CAPABILITY_ROLL)
+ * - Zoom (@ref XN_CAPABILITY_ZOOM)
+ * - Exposure (@ref XN_CAPABILITY_EXPOSURE)
+ * - Iris (@ref XN_CAPABILITY_IRIS)
+ * - Focus (@ref XN_CAPABILITY_FOCUS)
+ * - Low Light Compensation (@ref XN_CAPABILITY_LOW_LIGHT_COMPENSATION)
+ * @{
+ */
+
+/**
+ * @brief Gets the range of this capability values
+ *
+ * @param hNode [in] A handle to the instance
+ * @param strCap [in] Name of the capability
+ * @param pnMin [out] Minimum value
+ * @param pnMax [out] Maximum value
+ * @param pnStep [out] Step size
+ * @param pnDefault [out] Default value
+ * @param pbIsAutoSupported [out] TRUE if auto adjustment is supported, FALSE otherwise
+ */
+XN_C_API XnStatus XN_C_DECL xnGetGeneralIntRange(XnNodeHandle hNode, const XnChar* strCap, XnInt32* pnMin, XnInt32* pnMax, XnInt32* pnStep, XnInt32* pnDefault, XnBool* pbIsAutoSupported);
+
+/**
+ * @brief Gets the current value of this capability
+ *
+ * @param hNode [in] A handle to the instance
+ * @param strCap [in] Name of the capability
+ * @param pnValue [out] Current value
+ */
+XN_C_API XnStatus XN_C_DECL xnGetGeneralIntValue(XnNodeHandle hNode, const XnChar* strCap, XnInt32* pnValue);
+
+/**
+ * @brief Sets the current value of this capability
+ *
+ * @param hNode [in] A handle to the instance
+ * @param strCap [in] Name of the capability
+ * @param nValue [in] Value to set
+ */
+XN_C_API XnStatus XN_C_DECL xnSetGeneralIntValue(XnNodeHandle hNode, const XnChar* strCap, XnInt32 nValue);
+
+/**
+ * @brief Registers a callback function to values changes.
+ *
+ * @param hNode [in] A handle to the instance.
+ * @param strCap [in] Name of the capability
+ * @param handler [in] A pointer to a function that will be called when value changes.
+ * @param pCookie [in] A user cookie that will be passed to the callback function.
+ * @param phCallback [out] Optional. Will be filled with a handle to be passed to @ref xnUnregisterFromGeneralIntValueChange().
+ */
+XN_C_API XnStatus XN_C_DECL xnRegisterToGeneralIntValueChange
+ (XnNodeHandle hNode, const XnChar* strCap, XnStateChangedHandler handler,
+ void* pCookie, XnCallbackHandle* phCallback);
+
+/**
+ * @brief Unregisters a callback function which was registered using @ref xnRegisterToGeneralIntValueChange().
+ *
+ * @param hNode [in] A handle to the instance.
+ * @param strCap [in] Name of the capability
+ * @param hCallback [in] The handle to the callback returned from @ref xnRegisterToGeneralIntValueChange().
+ */
+XN_C_API void XN_C_DECL xnUnregisterFromGeneralIntValueChange
+ (XnNodeHandle hNode, const XnChar* strCap, XnCallbackHandle hCallback);
+
+/** @} */
+
+//---------------------------------------------------------------------------
+// Generators
+//---------------------------------------------------------------------------
+
+/**
+ * @ingroup prd_node
+ * @defgroup generator Generator
+ *
+ * A Generator node is a production node that also generates continuous data. It supports all @ref node functions,
+ * and adds additional functions.
+ * @{
+ */
+
+/**
+ * @name Controlling Generation
+ * The following functions allows controlling if a node is currently generating data or not.
+ * @{
+ */
+
+/**
+ * @brief Starts generation of the output. This will also cause all dependencies to start generating.
+ *
+ * @param hInstance [in] A handle to the instance to start generating.
+ *
+ * @returns XN_STATUS_INVALID_OPERATION if this production node is not a generator.
+ */
+XN_C_API XnStatus XN_C_DECL xnStartGenerating(XnNodeHandle hInstance);
+
+/**
+ * @brief Checks if this node is currently generating.
+ *
+ * @param hInstance [in] A handle to the instance.
+ *
+ * @returns FALSE if this production node is not a generator.
+ */
+XN_C_API XnBool XN_C_DECL xnIsGenerating(XnNodeHandle hInstance);
+
+/**
+ * @brief Stops generation of the output.
+ *
+ * @param hInstance [in] A handle to the instance to stop generating.
+ *
+ * @returns XN_STATUS_INVALID_OPERATION if this production node is not a generator.
+ */
+XN_C_API XnStatus XN_C_DECL xnStopGenerating(XnNodeHandle hInstance);
+
+/**
+ * @brief Registers a callback function to be called when generation starts or stops.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param handler [in] A pointer to a function that will be called when generation starts/stops.
+ * @param pCookie [in] A user cookie that will be passed to the callback function.
+ * @param phCallback [out] Optional. Will be filled with a handle to be passed to @ref xnUnregisterFromGenerationRunningChange().
+ */
+XN_C_API XnStatus XN_C_DECL xnRegisterToGenerationRunningChange
+ (XnNodeHandle hInstance, XnStateChangedHandler handler,
+ void* pCookie, XnCallbackHandle* phCallback);
+
+/**
+ * @brief Unregisters a callback function which was registered using @ref xnRegisterToGenerationRunningChange().
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param hCallback [in] The handle to the callback returned from @ref xnRegisterToGenerationRunningChange().
+ */
+XN_C_API void XN_C_DECL xnUnregisterFromGenerationRunningChange
+ (XnNodeHandle hInstance, XnCallbackHandle hCallback);
+
+/// @}
+
+/**
+ * @name Checking if new data is available
+ * The following functions allows an application to know if and when a node has new data available.
+ * When new data is available, the node data is still not replaced, until explicitly done so using one
+ * of the update data functions.
+ * @{
+ */
+
+/**
+ * @brief Registers a callback function to be called when new data is available.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param handler [in] A pointer to a function that will be called when new data is available.
+ * @param pCookie [in] A user cookie that will be passed to the callback function.
+ * @param phCallback [out] Optional. Will be filled with a handle to be passed to @ref xnUnregisterFromNewDataAvailable().
+ */
+XN_C_API XnStatus XN_C_DECL xnRegisterToNewDataAvailable
+ (XnNodeHandle hInstance, XnStateChangedHandler handler,
+ void* pCookie, XnCallbackHandle* phCallback);
+
+/**
+ * @brief Unregisters a callback function which was registered using @ref xnRegisterToNewDataAvailable().
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param hCallback [in] The handle to the callback returned from @ref xnRegisterToNewDataAvailable().
+ */
+XN_C_API void XN_C_DECL xnUnregisterFromNewDataAvailable
+ (XnNodeHandle hInstance, XnCallbackHandle hCallback);
+
+/**
+ * @brief Checks whether this node has new data (and so a call to @ref xnWaitAndUpdateData() will not block).
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param pnTimestamp [out] [Optional] If not NULL, will be filled with that data timestamp.
+ */
+XN_C_API XnBool XN_C_DECL xnIsNewDataAvailable(XnNodeHandle hInstance, XnUInt64* pnTimestamp);
+
+/// @}
+
+/**
+ * @name Getting new data
+ * @{
+ */
+
+/**
+ * @brief Updates the data to the latest available one. If needed, the call will block until new data is available.
+ *
+ * @param hInstance [in] A handle to the instance to be updated.
+ *
+ * @returns XN_STATUS_INVALID_OPERATION if this production node is not a generator.
+ */
+XN_C_API XnStatus XN_C_DECL xnWaitAndUpdateData(XnNodeHandle hInstance);
+
+/// @}
+
+/**
+ * @name Data properties
+ * @{
+ */
+
+/**
+ * @brief Checks whether current data is new. Meaning, did the data change on the last call to @ref xnWaitAndUpdateAll(),
+ * @ref xnWaitOneUpdateAll() or @ref xnWaitAndUpdateData().
+ *
+ * @param hInstance [in] A handle to the instance.
+ */
+XN_C_API XnBool XN_C_DECL xnIsDataNew(XnNodeHandle hInstance);
+
+/**
+ * @brief Gets the current data.
+ *
+ * @param hInstance [in] A handle to the instance.
+ *
+ * @returns NULL if this production node is not a generator.
+ */
+XN_C_API const void* XN_C_DECL xnGetData(XnNodeHandle hInstance);
+
+/**
+ * @brief Gets the size of current data, in bytes.
+ *
+ * @param hInstance [in] A handle to the instance.
+ *
+ * @returns (XnUInt32)-1 if this production node is not a generator.
+ */
+XN_C_API XnUInt32 XN_C_DECL xnGetDataSize(XnNodeHandle hInstance);
+
+/**
+ * @brief Gets the timestamp of current data, in microseconds.
+ *
+ * @param hInstance [in] A handle to the instance.
+ *
+ * @returns (XnUInt64)-1 if this production node is not a generator.
+ */
+XN_C_API XnUInt64 XN_C_DECL xnGetTimestamp(XnNodeHandle hInstance);
+
+/**
+ * @brief Gets the frame ID of current data.
+ *
+ * @param hInstance [in] A handle to the instance.
+ *
+ * @returns (XnUInt32)-1 if this production node is not a generator.
+ */
+XN_C_API XnUInt32 XN_C_DECL xnGetFrameID(XnNodeHandle hInstance);
+
+/** @} */
+
+/** @} */
+
+//---------------------------------------------------------------------------
+// Mirror Capability
+//---------------------------------------------------------------------------
+
+/**
+ * @ingroup generator
+ * @defgroup mirror Mirror Capability
+ * The mirror capability (@ref XN_CAPABILITY_MIRROR) allows mirroring of the data produced by a @ref generator.
+ * Mirroring is useful if the sensor is placed in front of the user (so that it sees the user right hand as the
+ * left one), but applications want user to get a more natural feeling of control.
+ * @{
+ */
+
+/**
+ * @brief Sets current mirror configuration.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param bMirror [in] TRUE for mirroring output, FALSE otherwise.
+ */
+XN_C_API XnStatus XN_C_DECL xnSetMirror(XnNodeHandle hInstance, XnBool bMirror);
+
+/**
+ * @brief Gets current mirroring configuration.
+ *
+ * @param hInstance [in] A handle to the instance.
+ */
+XN_C_API XnBool XN_C_DECL xnIsMirrored(XnNodeHandle hInstance);
+
+/**
+ * @brief Registers a callback function to mirror changes.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param handler [in] A pointer to a function that will be called when mirror changes.
+ * @param pCookie [in] A user cookie that will be passed to the callback function.
+ * @param phCallback [out] Optional. Will be filled with a handle to be passed to @ref xnUnregisterFromMirrorChange().
+ */
+XN_C_API XnStatus XN_C_DECL xnRegisterToMirrorChange
+ (XnNodeHandle hInstance, XnStateChangedHandler handler,
+ void* pCookie, XnCallbackHandle* phCallback);
+
+/**
+ * @brief Unregisters a callback function which was registered using @ref xnRegisterToMirrorChange().
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param hCallback [in] The handle to the callback returned from @ref xnRegisterToMirrorChange().
+ */
+XN_C_API void XN_C_DECL xnUnregisterFromMirrorChange
+ (XnNodeHandle hInstance, XnCallbackHandle hCallback);
+
+/** @} */
+
+//---------------------------------------------------------------------------
+// Alternative View Point Capability
+//---------------------------------------------------------------------------
+
+/**
+ * @ingroup generator
+ * @defgroup altviewpoint Alternative View Point Capability
+ * The Alternative View Point capability (@ref XN_CAPABILITY_ALTERNATIVE_VIEW_POINT) allows a @ref generator
+ * to transform its data to appear as if the sensor is placed in another location. For example, when more
+ * than one sensor is active (or one sensor that produces several outputs coming from close locations, yet not
+ * the same one), one sensor can change its data to appear as if coming from the location of the other sensor,
+ * so that both data buffers represent the same (for example depth and image maps, where the same coordinates
+ * in the map represent the same location is the scene).
+ * @{
+ */
+
+/**
+ * @brief Checks if this generator can change its output to look like it was taken from a different location, represented by another generator.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param hOther [in] The view point to be checked.
+ *
+ * @returns TRUE if view point is supported, FALSE otherwise.
+ */
+XN_C_API XnBool XN_C_DECL xnIsViewPointSupported(XnNodeHandle hInstance, XnNodeHandle hOther);
+
+/**
+ * @brief Sets the view point of this generator to look like as if placed at another generator location.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param hOther [in] The view point to be set.
+ */
+XN_C_API XnStatus XN_C_DECL xnSetViewPoint(XnNodeHandle hInstance, XnNodeHandle hOther);
+
+/**
+ * @brief Sets the view point of this generator to its normal one.
+ *
+ * @param hInstance [in] A handle to the instance.
+ */
+XN_C_API XnStatus XN_C_DECL xnResetViewPoint(XnNodeHandle hInstance);
+
+/**
+ * @brief Checks if current view point is as if coming from the other node view point.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param hOther [in] The view point to be checked.
+ */
+XN_C_API XnBool XN_C_DECL xnIsViewPointAs(XnNodeHandle hInstance, XnNodeHandle hOther);
+
+/**
+ * @brief Registers a callback function to view point changes.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param handler [in] A pointer to a function that will be called when view point changes.
+ * @param pCookie [in] A user cookie that will be passed to the callback function.
+ * @param phCallback [out] Optional. Will be filled with a handle to be passed to @ref xnUnregisterFromViewPointChange().
+ */
+XN_C_API XnStatus XN_C_DECL xnRegisterToViewPointChange(XnNodeHandle hInstance, XnStateChangedHandler handler, void* pCookie, XnCallbackHandle* phCallback);
+
+/**
+ * @brief Unregisters a callback function which was registered using @ref xnRegisterToViewPointChange().
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param hCallback [in] The handle to the callback returned from @ref xnRegisterToViewPointChange().
+ */
+XN_C_API void XN_C_DECL xnUnregisterFromViewPointChange(XnNodeHandle hInstance, XnCallbackHandle hCallback);
+
+/** @} */
+
+//---------------------------------------------------------------------------
+// FrameSync Capability
+//---------------------------------------------------------------------------
+
+/**
+ * @ingroup generator
+ * @defgroup framesync Frame-Sync Capability
+ * The Frame Sync capability (@ref XN_CAPABILITY_FRAME_SYNC) allows two sensors producing frame data to synchronize
+ * their frames so that they arrive at the same time. This allows smaller latency between two maps of the same scene
+ * (for example depth and image).
+ * @{
+ */
+
+/**
+ * @brief Checks if this generator can frame sync to another node.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param hOther [in] The node to be checked.
+ *
+ * @returns TRUE if frame sync to node is supported, FALSE otherwise.
+ */
+XN_C_API XnBool XN_C_DECL xnCanFrameSyncWith(XnNodeHandle hInstance, XnNodeHandle hOther);
+
+/**
+ * @brief Activates frame sync with the other node.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param hOther [in] The node to sync to.
+ */
+XN_C_API XnStatus XN_C_DECL xnFrameSyncWith(XnNodeHandle hInstance, XnNodeHandle hOther);
+
+/**
+ * @brief Stops frame sync with the other node.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param hOther [in] The node to sync to.
+ */
+XN_C_API XnStatus XN_C_DECL xnStopFrameSyncWith(XnNodeHandle hInstance, XnNodeHandle hOther);
+
+/**
+ * @brief Checks if current view point is as if coming from the other node view point.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param hOther [in] The node to be checked.
+ */
+XN_C_API XnBool XN_C_DECL xnIsFrameSyncedWith(XnNodeHandle hInstance, XnNodeHandle hOther);
+
+/**
+ * @brief Registers a callback function to view point changes.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param handler [in] A pointer to a function that will be called when frame sync changes.
+ * @param pCookie [in] A user cookie that will be passed to the callback function.
+ * @param phCallback [out] Optional. Will be filled with a handle to be passed to @ref xnUnregisterFromFrameSyncChange().
+ */
+XN_C_API XnStatus XN_C_DECL xnRegisterToFrameSyncChange(XnNodeHandle hInstance, XnStateChangedHandler handler, void* pCookie, XnCallbackHandle* phCallback);
+
+/**
+ * @brief Unregisters a callback function which was registered using @ref xnRegisterToFrameSyncChange().
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param hCallback [in] The handle to the callback returned from @ref xnRegisterToFrameSyncChange().
+ */
+XN_C_API void XN_C_DECL xnUnregisterFromFrameSyncChange(XnNodeHandle hInstance, XnCallbackHandle hCallback);
+
+/** @} */
+
+//---------------------------------------------------------------------------
+// Map Generators
+//---------------------------------------------------------------------------
+
+/**
+ * @ingroup prd_node
+ * @defgroup mapgen Map Generator
+ * A Map Generator node is a @ref generator that has output data in the form of a pixel map. It supports all @ref generator functions,
+ * and adds additional functions.
+ * @{
+ */
+
+/**
+ * @brief Gets the number of supported modes. This is useful for allocating an array that will be passed to @ref xnGetSupportedMapOutputModes().
+ *
+ * @param hInstance [in] A handle to the instance.
+ *
+ * @returns 0 if this production node is not a map generator.
+ */
+XN_C_API XnUInt32 XN_C_DECL xnGetSupportedMapOutputModesCount(XnNodeHandle hInstance);
+
+/**
+ * @brief Gets a list of all supported modes. The size of the array that should be passed can be obtained by calling @ref xnGetSupportedMapOutputModesCount().
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param aModes [in/out] An array to be filled with supported modes.
+ * @param pnCount [in/out] In: number of elements allocated in the array. Out: number of elements
+ * actually written to the array.
+ *
+ * @returns XN_STATUS_INVALID_OPERATION if this production node is not a map generator.
+ */
+XN_C_API XnStatus XN_C_DECL xnGetSupportedMapOutputModes(XnNodeHandle hInstance, XnMapOutputMode* aModes, XnUInt32* pnCount);
+
+/**
+ * @brief Sets the output mode.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param pOutputMode [in] The output mode to be set.
+ *
+ * @returns XN_STATUS_INVALID_OPERATION if this production node is not a map generator.
+ */
+XN_C_API XnStatus XN_C_DECL xnSetMapOutputMode(XnNodeHandle hInstance, const XnMapOutputMode* pOutputMode);
+
+/**
+ * @brief Gets the current output mode.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param pOutputMode [out] Current output mode.
+ *
+ * @returns XN_STATUS_INVALID_OPERATION if this production node is not a map generator.
+ */
+XN_C_API XnStatus XN_C_DECL xnGetMapOutputMode(XnNodeHandle hInstance, XnMapOutputMode* pOutputMode);
+
+/**
+ * @brief Registers a callback function to mode changes.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param handler [in] A pointer to a function that will be called when mode changes.
+ * @param pCookie [in] A user cookie that will be passed to the callback function.
+ * @param phCallback [out] Optional. Will be filled with a handle to be passed to @ref xnUnregisterFromMapOutputModeChange.
+ *
+ * @returns XN_STATUS_INVALID_OPERATION if this production node is not a map generator.
+ */
+XN_C_API XnStatus XN_C_DECL xnRegisterToMapOutputModeChange(XnNodeHandle hInstance, XnStateChangedHandler handler,
+ void* pCookie, XnCallbackHandle* phCallback);
+
+/**
+ * @brief Unregisters a callback function which was registered using @ref xnRegisterToMapOutputModeChange.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param hCallback [in] The handle to the callback returned from @ref xnRegisterToMapOutputModeChange.
+ */
+XN_C_API void XN_C_DECL xnUnregisterFromMapOutputModeChange(XnNodeHandle hInstance, XnCallbackHandle hCallback);
+
+/**
+ * @brief Gets the number of bytes per pixel for this map generator.
+ *
+ * @param hInstance [in] A handle to the instance.
+ *
+ * @returns (XnUInt32)-1 if this production node is not a map generator.
+ */
+XN_C_API XnUInt32 XN_C_DECL xnGetBytesPerPixel(XnNodeHandle hInstance);
+
+/** @} */
+
+//---------------------------------------------------------------------------
+// Cropping Capability
+//---------------------------------------------------------------------------
+
+
+/**
+ * @ingroup mapgen
+ * @defgroup cropping Cropping Capability
+ * The Cropping capability (@ref XN_CAPABILITY_CROPPING) allows a @ref mapgen to output a selected area
+ * of the frame instead of the entire frame. When cropping is turned on, the data buffer looks just like
+ * resolution is smaller, meaning data is packed. For example if the MapGenerator is working in VGA resolution
+ * (640x480) and the application chose a cropping of 300x200, then after first 300 pixels the next pixel row
+ * begins. Pixels outside the cropping area are not returned in the buffer (and not just being blacked out).
+ * This is very useful for performance boost.
+ * @{
+ */
+
+/**
+ * @brief Sets the cropping.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param pCropping [in] The cropping configuration to be set.
+ *
+ * @returns XN_STATUS_INVALID_OPERATION if this production node does not support the Cropping capability.
+ */
+XN_C_API XnStatus XN_C_DECL xnSetCropping(XnNodeHandle hInstance, const XnCropping* pCropping);
+
+/**
+ * @brief Gets current cropping configuration.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param pCropping [out] Current cropping configuration.
+ *
+ * @returns XN_STATUS_INVALID_OPERATION if this production node does not support the Cropping capability.
+ */
+XN_C_API XnStatus XN_C_DECL xnGetCropping(XnNodeHandle hInstance, XnCropping* pCropping);
+
+/**
+ * @brief Registers a callback function to cropping changes.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param handler [in] A pointer to a function that will be called when cropping changes.
+ * @param pCookie [in] A user cookie that will be passed to the callback function.
+ * @param phCallback [out] Optional. Will be filled with a handle to be passed to @ref xnUnregisterFromCroppingChange().
+ */
+XN_C_API XnStatus XN_C_DECL xnRegisterToCroppingChange(XnNodeHandle hInstance, XnStateChangedHandler handler,
+ void* pCookie, XnCallbackHandle* phCallback);
+
+/**
+ * @brief Unregisters a callback function which was registered using @ref xnRegisterToCroppingChange().
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param hCallback [in] The handle to the callback returned from xnRegisterToCroppingChange().
+ */
+XN_C_API void XN_C_DECL xnUnregisterFromCroppingChange(XnNodeHandle hInstance, XnCallbackHandle hCallback);
+
+/** @} */
+
+//---------------------------------------------------------------------------
+// Anti Flicker Capability
+//---------------------------------------------------------------------------
+
+/**
+ * @ingroup mapgen
+ * @defgroup anti_flicker Anti Flicker Capability
+ * The Anti Flicker capability (@ref XN_CAPABILITY_ANTI_FLICKER) allows a @ref mapgen to time its frames
+ * in such a way that no flickering will take place due to electric light frequencies.
+ * @{
+ */
+
+/**
+ * @brief Sets the power line frequency: 50 Hz, 60 Hz, or 0 to turn off anti-flicker.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param nFrequency [in] The frequency to be used.
+ */
+XN_C_API XnStatus XN_C_DECL xnSetPowerLineFrequency(XnNodeHandle hGenerator, XnPowerLineFrequency nFrequency);
+
+/**
+ * @brief Gets the power line frequency.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @returns (XnUInt32)-1 if node does not support this capability
+ */
+XN_C_API XnPowerLineFrequency XN_C_DECL xnGetPowerLineFrequency(XnNodeHandle hGenerator);
+
+/**
+ * @brief Registers a callback function to power line frequency changes.
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param handler [in] A pointer to a function that will be called when power line frequency changes.
+ * @param pCookie [in] A user cookie that will be passed to the callback function.
+ * @param phCallback [out] Optional. Will be filled with a handle to be passed to @ref xnUnregisterFromPowerLineFrequencyChange().
+ */
+XN_C_API XnStatus XN_C_DECL xnRegisterToPowerLineFrequencyChange
+ (XnNodeHandle hGenerator, XnStateChangedHandler handler,
+ void* pCookie, XnCallbackHandle* phCallback);
+
+/**
+ * @brief Unregisters a callback function which was registered using @ref xnRegisterToPowerLineFrequencyChange().
+ *
+ * @param hGenerator [in] A handle to the instance.
+ * @param hCallback [in] The handle to the callback returned from @ref xnRegisterToPowerLineFrequencyChange().
+ */
+XN_C_API void XN_C_DECL xnUnregisterFromPowerLineFrequencyChange
+ (XnNodeHandle hGenerator, XnCallbackHandle hCallback);
+
+/** @} */
+
+//---------------------------------------------------------------------------
+// Depth Generators
+//---------------------------------------------------------------------------
+
+/**
+ * @ingroup prd_node
+ * @defgroup depthgen Depth Generator
+ * A Depth Generator node is a @ref mapgen that outputs depth maps. It supports all @ref mapgen functions,
+ * and adds additional functions.
+ * @{
+ */
+
+/**
+ * @brief Creates a depth generator.
+ *
+ * @param pContext [in] The context in which to create the depth generator
+ * @param phDepthGenerator [out] A handle to the created depth generator
+ * @param pQuery [in] Optional. Can be used to select which depth generator to create. If not specified, this function may create any depth generator that is available.
+ * @param pErrors [in] Optional. If provided, will be filled with information about depth generators that could not be created.
+ */
+XN_C_API XnStatus XN_C_DECL xnCreateDepthGenerator(
+ XnContext* pContext,
+ XnNodeHandle* phDepthGenerator,
+ XnNodeQuery* pQuery,
+ XnEnumerationErrors* pErrors);
+
+/**
+ * @brief Gets the maximum depth the device can produce.
+ *
+ * @param hInstance [in] A handle to the instance.
+ *
+ * @returns -1 if this production node is not a depth generator.
+ */
+XN_C_API XnDepthPixel XN_C_DECL xnGetDeviceMaxDepth(XnNodeHandle hInstance);
+
+/**
+ * @brief Gets the Field-Of-View of the depth generator, in radians.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param pFOV [in] A struct to be filled with field of view.
+ *
+ * @returns XN_STATUS_INVALID_OPERATION if this production node is not a depth generator.
+ */
+XN_C_API XnStatus XN_C_DECL xnGetDepthFieldOfView(XnNodeHandle hInstance, XnFieldOfView* pFOV);
+
+/**
+ * @brief Registers a callback function to field of view changes.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param handler [in] A pointer to a function that will be called when field of view changes.
+ * @param pCookie [in] A user cookie that will be passed to the callback function.
+ * @param phCallback [out] Optional. Will be filled with a handle to be passed to @ref xnUnregisterFromDepthFieldOfViewChange.
+ *
+ * @returns XN_STATUS_INVALID_OPERATION if this production node does not support the User Position capability.
+ */
+XN_C_API XnStatus XN_C_DECL xnRegisterToDepthFieldOfViewChange(XnNodeHandle hInstance, XnStateChangedHandler handler,
+ void* pCookie, XnCallbackHandle* phCallback);
+
+/**
+ * @brief Unregisters a callback function which was registered using @ref xnRegisterToDepthFieldOfViewChange.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param hCallback [in] The handle to the callback returned from @ref xnRegisterToDepthFieldOfViewChange.
+ */
+XN_C_API void XN_C_DECL xnUnregisterFromDepthFieldOfViewChange(XnNodeHandle hInstance, XnCallbackHandle hCallback);
+
+/**
+ * @brief Converts a list of points from projective coordinates to real world coordinates.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param nCount [in] The number of points to translate.
+ * @param aProjective [in] An array of projective coordinates points.
+ * @param aRealWorld [in/out] An array to be filled with real world coordinates points.
+ *
+ * @returns XN_STATUS_INVALID_OPERATION if this production node is not a depth generator.
+ */
+XN_C_API XnStatus XN_C_DECL xnConvertProjectiveToRealWorld(
+ XnNodeHandle hInstance, XnUInt32 nCount, const XnPoint3D* aProjective, XnPoint3D* aRealWorld);
+
+/**
+ * @brief Converts a list of points from projective coordinates to real world coordinates.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param nCount [in] The number of points to translate.
+ * @param aRealWorld [in] An array of real world coordinates points.
+ * @param aProjective [in/out] An array to be filled with projective coordinates points.
+ *
+ * @returns XN_STATUS_INVALID_OPERATION if this production node is not a depth generator.
+ */
+XN_C_API XnStatus XN_C_DECL xnConvertRealWorldToProjective(
+ XnNodeHandle hInstance, XnUInt32 nCount, const XnPoint3D* aRealWorld, XnPoint3D* aProjective);
+
+/**
+ * @brief Gets the current depth-map. This map is updated after a call to @ref xnWaitAndUpdateData().
+ *
+ * @param hInstance [in] A handle to the instance.
+ *
+ * @returns NULL if this production node is not a depth generator.
+ */
+XN_C_API XnDepthPixel* XN_C_DECL xnGetDepthMap(XnNodeHandle hInstance);
+
+/**
+ * @brief Gets the current depth-map meta data.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param pMetaData [in] The struct to be filled.
+ */
+XN_C_API void XN_C_DECL xnGetDepthMetaData(XnNodeHandle hInstance, XnDepthMetaData* pMetaData);
+
+/** @} */
+
+//---------------------------------------------------------------------------
+// User Position Capability
+//---------------------------------------------------------------------------
+
+/**
+ * @ingroup depthgen
+ * @defgroup userpos User Position Capability
+ * The User Position capability (@ref XN_CAPABILITY_USER_POSITION) allows a @ref depthgen to change its
+ * output, so that it would be optimized in specific locations in the scene.
+ * @{
+ */
+
+/**
+ * @brief Gets the number of user positions supported by this generator.
+ *
+ * @param hInstance [in] A handle to the instance.
+ *
+ * @returns 0 if this production node does not support the User Position capability.
+ */
+XN_C_API XnUInt32 XN_C_DECL xnGetSupportedUserPositionsCount(XnNodeHandle hInstance);
+
+/**
+ * @brief Sets the current user position.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param nIndex [in] The user position to set.
+ * @param pPosition [in] The user position in the frame.
+ *
+ * @returns XN_STATUS_INVALID_OPERATION if this production node does not support the User Position capability.
+ */
+XN_C_API XnStatus XN_C_DECL xnSetUserPosition(XnNodeHandle hInstance, XnUInt32 nIndex, const XnBoundingBox3D* pPosition);
+
+/**
+ * @brief Gets the current user position.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param nIndex [in] The user position to get.
+ * @param pPosition [out] The user position.
+ *
+ * @returns XN_STATUS_INVALID_OPERATION if this production node does not support the User Position capability.
+ */
+XN_C_API XnStatus XN_C_DECL xnGetUserPosition(XnNodeHandle hInstance, XnUInt32 nIndex, XnBoundingBox3D* pPosition);
+
+/**
+ * @brief Registers a callback function to user position changes.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param handler [in] A pointer to a function that will be called when user position changes.
+ * @param pCookie [in] A user cookie that will be passed to the callback function.
+ * @param phCallback [out] Optional. Will be filled with a handle to be passed to @ref xnUnregisterFromUserPositionChange.
+ *
+ * @returns XN_STATUS_INVALID_OPERATION if this production node does not support the User Position capability.
+ */
+XN_C_API XnStatus XN_C_DECL xnRegisterToUserPositionChange(XnNodeHandle hInstance, XnStateChangedHandler handler,
+ void* pCookie, XnCallbackHandle* phCallback);
+
+/**
+ * @brief Unregisters a callback function which was registered using @ref xnRegisterToUserPositionChange.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param hCallback [in] The handle to the callback returned from @ref xnRegisterToUserPositionChange.
+ */
+XN_C_API void XN_C_DECL xnUnregisterFromUserPositionChange(XnNodeHandle hInstance, XnCallbackHandle hCallback);
+
+/** @} */
+
+//---------------------------------------------------------------------------
+// Image Generators
+//---------------------------------------------------------------------------
+
+/**
+ * @ingroup prd_node
+ * @defgroup imagegen Image Generator
+ * An Image Generator node is a @ref mapgen that outputs image maps. It supports all @ref mapgen functions,
+ * and adds additional functions.
+ * Image maps may arrive in different pixel formats.
+ * @{
+ */
+
+/**
+ * @brief Creates an image generator.
+ *
+ * @param pContext [in] The context in which to create the image generator.
+ * @param phImageGenerator [out] A handle to the created image generator.
+ * @param pQuery [in] Optional. Can be used to select which image generator to create. If not specified, this function may create any image generator that is available.
+ * @param pErrors [in] Optional. If provided, will be filled with information about image generators that could not be created.
+ */
+XN_C_API XnStatus XN_C_DECL xnCreateImageGenerator(
+ XnContext* pContext,
+ XnNodeHandle* phImageGenerator,
+ XnNodeQuery* pQuery,
+ XnEnumerationErrors* pErrors
+ );
+
+/**
+ * @brief Gets the current RGB24 image-map.
+ * This map is updated after a call to @ref xnWaitAndUpdateData(). It is assumed that the node is currently in RGB24 pixel format.
+ *
+ * @param hInstance [in] A handle to the instance.
+ *
+ * @returns NULL if this production node is not an image generator.
+ */
+XN_C_API XnRGB24Pixel* XN_C_DECL xnGetRGB24ImageMap(XnNodeHandle hInstance);
+
+/**
+ * @brief Gets the current YUV422 image-map.
+ * This map is updated after a call to @ref xnWaitAndUpdateData(). It is assumed that the node is currently in YUV422 pixel format.
+ *
+ * @param hInstance [in] A handle to the instance.
+ *
+ * @returns NULL if this production node is not an image generator.
+ */
+XN_C_API XnYUV422DoublePixel* XN_C_DECL xnGetYUV422ImageMap(XnNodeHandle hInstance);
+
+/**
+ * @brief Gets the current Grayscale8 image-map.
+ * This map is updated after a call to @ref xnWaitAndUpdateData(). It is assumed that the node is currently in Grayscale8 pixel format.
+ *
+ * @param hInstance [in] A handle to the instance.
+ *
+ * @returns NULL if this production node is not an image generator.
+ */
+XN_C_API XnGrayscale8Pixel* XN_C_DECL xnGetGrayscale8ImageMap(XnNodeHandle hInstance);
+
+/**
+ * @brief Gets the current Grayscale16 image-map.
+ * This map is updated after a call to @ref xnWaitAndUpdateData(). It is assumed that the node is currently in Grayscale16 pixel format.
+ *
+ * @param hInstance [in] A handle to the instance.
+ *
+ * @returns NULL if this production node is not an image generator.
+ */
+XN_C_API XnGrayscale16Pixel* XN_C_DECL xnGetGrayscale16ImageMap(XnNodeHandle hInstance);
+
+/**
+ * @brief Gets the current image-map as a byte buffer.
+ *
+ * This map is updated after a call to @ref xnWaitAndUpdateData().
+ * It is highly advised not to use this function. Instead, if you know the format of the image, use
+ * @ref xnGetRGB24ImageMap(), @ref xnGetYUV422ImageMap(), @ref xnGetGrayscale8ImageMap() or
+ * @ref xnGetGrayscale16ImageMap().
+ *
+ * @param hInstance [in] A handle to the instance.
+ *
+ * @returns NULL if this production node is not an image generator.
+ */
+XN_C_API XnUInt8* XN_C_DECL xnGetImageMap(XnNodeHandle hInstance);
+
+/**
+ * @brief Checks if a specific pixel format is supported.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param Format [in] The format to check for.
+ */
+XN_C_API XnBool XN_C_DECL xnIsPixelFormatSupported(XnNodeHandle hInstance, XnPixelFormat Format);
+
+/**
+ * @brief Sets the pixel format of the image map.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param Format [in] The format to set.
+ *
+ * @returns XN_STATUS_INVALID_OPERATION if this production node is not an image generator.
+ */
+XN_C_API XnStatus XN_C_DECL xnSetPixelFormat(XnNodeHandle hInstance, XnPixelFormat Format);
+
+/**
+ * @brief Gets current pixel format.
+ *
+ * @param hInstance [in] A handle to the instance.
+ *
+ * @returns -1 if this production node is not an image generator.
+ */
+XN_C_API XnPixelFormat XN_C_DECL xnGetPixelFormat(XnNodeHandle hInstance);
+
+/**
+ * @brief Registers a callback function to pixel format changes.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param handler [in] A pointer to a function that will be called when pixel format changes.
+ * @param pCookie [in] A user cookie that will be passed to the callback function.
+ * @param phCallback [out] Optional. Will be filled with a handle to be passed to @ref xnUnregisterFromPixelFormatChange.
+ *
+ * @returns XN_STATUS_INVALID_OPERATION if this production node does not support the User Position capability.
+ */
+XN_C_API XnStatus XN_C_DECL xnRegisterToPixelFormatChange(XnNodeHandle hInstance, XnStateChangedHandler handler,
+ void* pCookie, XnCallbackHandle* phCallback);
+
+/**
+ * @brief Unregisters a callback function which was registered using @ref xnRegisterToPixelFormatChange.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param hCallback [in] The handle to the callback returned from @ref xnRegisterToPixelFormatChange.
+ */
+XN_C_API void XN_C_DECL xnUnregisterFromPixelFormatChange(XnNodeHandle hInstance, XnCallbackHandle hCallback);
+
+/**
+ * @brief Gets the current image-map meta data.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param pMetaData [in] The struct to be filled.
+ */
+XN_C_API void XN_C_DECL xnGetImageMetaData(XnNodeHandle hInstance, XnImageMetaData* pMetaData);
+
+/** @} */
+
+//---------------------------------------------------------------------------
+// IR Generators
+//---------------------------------------------------------------------------
+
+/**
+ * @ingroup prd_node
+ * @defgroup irgen IR Generator
+ * An IR Generator node is a @ref mapgen that outputs infra-red maps. It supports all @ref mapgen functions,
+ * and adds additional functions.
+ * @{
+ */
+
+/**
+ * @brief Creates an IR generator.
+ *
+ * @param pContext [in] The context in which to create the IR generator.
+ * @param phIRGenerator [out] A handle to the created IR generator.
+ * @param pQuery [in] Optional. Can be used to select which IR generator to create. If not specified, this function may create any IR generator that is available.
+ * @param pErrors [in] Optional. If provided, will be filled with information about IR generators that could not be created.
+ */
+XN_C_API XnStatus XN_C_DECL xnCreateIRGenerator(
+ XnContext* pContext,
+ XnNodeHandle* phIRGenerator,
+ XnNodeQuery* pQuery,
+ XnEnumerationErrors* pErrors
+ );
+
+/**
+ * @brief Gets the current IR-map. This map is updated after a call to @ref xnWaitAndUpdateData().
+ *
+ * @param hInstance [in] A handle to the instance.
+ *
+ * @returns NULL if this production node is not an IR generator.
+ */
+XN_C_API XnIRPixel* XN_C_DECL xnGetIRMap(XnNodeHandle hInstance);
+
+/**
+ * @brief Gets the current IR-map meta data.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param pMetaData [in] The struct to be filled.
+ */
+XN_C_API void XN_C_DECL xnGetIRMetaData(XnNodeHandle hInstance, XnIRMetaData* pMetaData);
+
+/** @} */
+
+//---------------------------------------------------------------------------
+// Gesture Generators
+//---------------------------------------------------------------------------
+
+/**
+ * @ingroup prd_node
+ * @defgroup gestures Gesture Generator
+ * A Gestures Generator node is a @ref generator that recognizes certain gestures. It supports all @ref generator functions,
+ * and adds additional functions.
+ * @{
+ */
+
+/**
+ * @brief Creates a Gesture Generator.
+ *
+ * @param pContext [in] The context in which to create the gesture generator.
+ * @param phGestureGenerator [out] A handle to the created gesture generator.
+ * @param pQuery [in] Optional. Can be used to select which Gesture node to create. If not specified, this function may create any gesture node that is available.
+ * @param pErrors [in] Optional. If provided, will be filled with information about gesture nodes that could not be created.
+ */
+XN_C_API XnStatus XN_C_DECL xnCreateGestureGenerator(
+ XnContext* pContext,
+ XnNodeHandle* phGestureGenerator,
+ XnNodeQuery* pQuery,
+ XnEnumerationErrors* pErrors
+ );
+
+/**
+ * @brief Turn on gesture. The generator will now look for this gesture
+ *
+ * @param hInstance [in] A handle to the instance
+ * @param strGesture [in] The name of the gesture to look for
+ * @param pArea [in] The area in which to look for the gesture (in Real-World coordinates)
+ */
+XN_C_API XnStatus XN_C_DECL xnAddGesture(XnNodeHandle hInstance, const XnChar* strGesture, XnBoundingBox3D* pArea);
+/**
+ * @brief Turn off gesture. The generator will no longer look for this gesture
+ *
+ * @param hInstance [in] A handle to the instance
+ * @param strGesture [in] The name of the gesture to not look for anymore
+ */
+XN_C_API XnStatus XN_C_DECL xnRemoveGesture(XnNodeHandle hInstance, const XnChar* strGesture);
+/**
+ * @brief Get the names of the gestures that are currently active
+ *
+ * @param hInstance [in] A handle to the instance
+ * @param pstrGestures [out] Preallocated memory, for the gesture names
+ * @param nGestures [in,out] The size of the preallocated memory. Changed to number of gestures
+ */
+XN_C_API XnStatus XN_C_DECL xnGetActiveGestures(XnNodeHandle hInstance, XnChar** pstrGestures, XnUInt16* nGestures);
+/**
+ * @brief Get the names of the gestures that are currently active
+ *
+ * @param hInstance [in] A handle to the instance
+ * @param pstrGestures [out] Preallocated memory, for the gesture names
+ * @param nNameLength [in] Memory size for each gesture name
+ * @param nGestures [in,out] The size of the preallocated memory. Changed to number of gestures
+ */
+XN_C_API XnStatus XN_C_DECL xnGetAllActiveGestures(XnNodeHandle hInstance, XnChar** pstrGestures, XnUInt32 nNameLength, XnUInt16* nGestures);
+/**
+ * @brief Get the names of all gestures available
+ *
+ * @param hInstance [in] A handle to the instance
+ * @param pstrGestures [out] Preallocated memory, for the gesture names
+ * @param nGestures [in,out] The size of the preallocated memory. Changed to number of gestures
+ */
+XN_C_API XnStatus XN_C_DECL xnEnumerateGestures(XnNodeHandle hInstance, XnChar** pstrGestures, XnUInt16* nGestures);
+/**
+ * @brief Get the names of all gestures available
+ *
+ * @param hInstance [in] A handle to the instance
+ * @param pstrGestures [out] Preallocated memory, for the gesture names
+ * @param nNameLength [in] Memory size for each gesture name
+ * @param nGestures [in,out] The size of the preallocated memory. Changed to number of gestures
+ */
+XN_C_API XnStatus XN_C_DECL xnEnumerateAllGestures(XnNodeHandle hInstance, XnChar** pstrGestures, XnUInt32 nNameLength, XnUInt16* nGestures);
+
+/**
+ * @brief Get the number of all gestures available
+ *
+ * @param hInstance [in] A handle to the instance
+ * @return the number of gestures available
+ */
+XN_C_API XnUInt16 XN_C_DECL xnGetNumberOfAvailableGestures(XnNodeHandle hInstance);
+
+
+/**
+ * @brief Check if a specific gesture is available in this generator
+ *
+ * @param hInstance [in] A handle to the instance
+ * @param strGesture [in] Name of the gesture to check
+ */
+XN_C_API XnBool XN_C_DECL xnIsGestureAvailable(XnNodeHandle hInstance, const XnChar* strGesture);
+/**
+ * @brief Check if the specific gesture supports 'in progress' callbacks
+ *
+ * @param hInstance [in] A handle to the instance
+ * @param strGesture [in] Name of the gesture to check
+ */
+XN_C_API XnBool XN_C_DECL xnIsGestureProgressSupported(XnNodeHandle hInstance, const XnChar* strGesture);
+/**
+ * @brief Register to all gesture callbacks.
+ *
+ * @param hInstance [in] A handle to the instance
+ * @param RecognizedCB [in] A callback to be called when a gesture is recognized
+ * @param ProgressCB [in] A callback to be called when a gesture is on its way to be recognized
+ * @param pCookie [in] User's cookie, to be delivered to the callbacks
+ * @param phCallback [out] The handle to these callbacks, to allow unregistration
+ */
+XN_C_API XnStatus XN_C_DECL xnRegisterGestureCallbacks(XnNodeHandle hInstance, XnGestureRecognized RecognizedCB, XnGestureProgress ProgressCB, void* pCookie, XnCallbackHandle* phCallback);
+/**
+ * @brief Unregister from gesture callbacks
+ *
+ * @param hInstance [in] A handle to the instance
+ * @param hCallback [in] The handle received from registration
+ */
+XN_C_API void XN_C_DECL xnUnregisterGestureCallbacks(XnNodeHandle hInstance, XnCallbackHandle hCallback);
+/**
+ * @brief Register to when gestures are added or removed
+ *
+ * @param hInstance [in] A handle to the instance
+ * @param handler [in] The callback to be called when gesture configuration changes.
+ * @param pCookie [in] User's cookie, to be delivered to the callbacks
+ * @param phCallback [out] The handle to these callbacks, to allow unregistration
+ */
+XN_C_API XnStatus XN_C_DECL xnRegisterToGestureChange(XnNodeHandle hInstance, XnStateChangedHandler handler, void* pCookie, XnCallbackHandle* phCallback);
+/**
+ * @brief Unregister from when gestures are added or removed
+ *
+ * @param hInstance [in] A handle to the instance
+ * @param hCallback [in] The handle received from registration
+ */
+XN_C_API void XN_C_DECL xnUnregisterFromGestureChange(XnNodeHandle hInstance, XnCallbackHandle hCallback);
+
+/**
+ * @brief Register to when a gesture is in progress
+ *
+ * @param hInstance [in] A handle to the instance
+ * @param handler [in] The callback to be called when the gesture is in progress
+ * @param pCookie [in] User's cookie, to be delivered to the callback
+ * @param phCallback [out] The handle to the callback, to allow unregistration
+ */
+XN_C_API XnStatus XN_C_DECL xnRegisterToGestureIntermediateStageCompleted(XnNodeHandle hInstance, XnGestureIntermediateStageCompleted handler, void* pCookie, XnCallbackHandle* phCallback);
+/**
+ * @brief Unregister from when a gesture is in progress
+ *
+ * @param hInstance [in] A handle to the instance
+ * @param hCallback [in] The handle received from registration
+ */
+XN_C_API void XN_C_DECL xnUnregisterFromGestureIntermediateStageCompleted(XnNodeHandle hInstance, XnCallbackHandle hCallback);
+/**
+ * @brief Register to when a gesture is ready for its next stage (specific to the gesture)
+ *
+ * @param hInstance [in] A handle to the instance
+ * @param handler [in] The callback to be called when the gesture is ready for its next stage
+ * @param pCookie [in] User's cookie, to be delivered to the callback
+ * @param phCallback [out] The handle to this callback, to allow unregistration
+ */
+XN_C_API XnStatus XN_C_DECL xnRegisterToGestureReadyForNextIntermediateStage(XnNodeHandle hInstance, XnGestureReadyForNextIntermediateStage handler, void* pCookie, XnCallbackHandle* phCallback);
+/**
+ * @brief Unregister from when a gesture is ready for its next stage
+ *
+ * @param hInstance [in] A handle to the instance
+ * @param hCallback [in] The handle received from registration
+ */
+XN_C_API void XN_C_DECL xnUnregisterFromGestureReadyForNextIntermediateStage(XnNodeHandle hInstance, XnCallbackHandle hCallback);
+/** @} */
+
+//---------------------------------------------------------------------------
+// Scene Analysis
+//---------------------------------------------------------------------------
+
+/**
+ * @ingroup prd_node
+ * @defgroup scene Scene Analyzer
+ * A Scene Analyzer node is a @ref mapgen that performs scene analysis. It supports all @ref mapgen functions,
+ * and adds additional functions.
+ * @{
+ */
+
+/**
+ * @brief Creates an scene analyzer.
+ *
+ * @param pContext [in] The context in which to create the scene analyzer.
+ * @param phSceneAnalyzer [out] A handle to the created scene analyzer.
+ * @param pQuery [in] Optional. Can be used to select which scene analyzer to create. If not specified, this function may create any scene analyzer that is available.
+ * @param pErrors [in] Optional. If provided, will be filled with information about scene analyzers that could not be created.
+ */
+XN_C_API XnStatus XN_C_DECL xnCreateSceneAnalyzer(
+ XnContext* pContext,
+ XnNodeHandle* phSceneAnalyzer,
+ XnNodeQuery* pQuery,
+ XnEnumerationErrors* pErrors
+ );
+
+/**
+ * @brief Gets the label map, describing the current segmentation of the scene.
+ *
+ * @param hInstance [in] A handle to the instance
+ */
+XN_C_API const XnLabel* XN_C_DECL xnGetLabelMap(XnNodeHandle hInstance);
+/**
+ * @brief Gets a description of the floor, if it was found.
+ *
+ * @param hInstance [in] A handle to the instance
+ * @param pPlane [out] A description of the floor
+ */
+XN_C_API XnStatus XN_C_DECL xnGetFloor(XnNodeHandle hInstance, XnPlane3D* pPlane);
+
+/**
+ * @brief Gets the current scene meta data.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param pMetaData [in] The struct to be filled.
+ */
+XN_C_API void XN_C_DECL xnGetSceneMetaData(XnNodeHandle hInstance, XnSceneMetaData* pMetaData);
+
+/** @} */
+
+//---------------------------------------------------------------------------
+// User Generator
+//---------------------------------------------------------------------------
+
+/**
+ * @ingroup prd_node
+ * @defgroup user User Generator
+ * A User Generator node is a @ref generator that identifies a user in the scene. It supports all @ref generator functions,
+ * and adds additional functions.
+ * @{
+ */
+
+/**
+ * @brief Creates a user generator.
+ *
+ * @param pContext [in] The context in which to create the user generator.
+ * @param phUserGenerator [out] A handle to the created user generator.
+ * @param pQuery [in] Optional. Can be used to select which user generator to create. If not specified, this function may create any user generator that is available.
+ * @param pErrors [in] Optional. If provided, will be filled with information about user generators that could not be created.
+ */
+XN_C_API XnStatus XN_C_DECL xnCreateUserGenerator(
+ XnContext* pContext,
+ XnNodeHandle* phUserGenerator,
+ XnNodeQuery* pQuery,
+ XnEnumerationErrors* pErrors
+ );
+
+/**
+ * @brief Get current number of users
+ *
+ * @param hInstance [in] A handle to the instance
+ */
+XN_C_API XnUInt16 XN_C_DECL xnGetNumberOfUsers(XnNodeHandle hInstance);
+/**
+ * @brief Get the current users
+ *
+ * @param hInstance [in] A handle to the instance
+ * @param pUsers [out] Preallocated memory for the users
+ * @param pnUsers [in,out] The size of the preallocated memory. Changes to the number of users
+ */
+XN_C_API XnStatus XN_C_DECL xnGetUsers(XnNodeHandle hInstance, XnUserID* pUsers, XnUInt16* pnUsers);
+/**
+ * @brief Get the center of mass of a user
+ *
+ * @param hInstance [in] A handle to the instance
+ * @param user [in] The user for which to get the center of mass
+ * @param pCoM [out] The center of mass
+ */
+XN_C_API XnStatus XN_C_DECL xnGetUserCoM(XnNodeHandle hInstance, XnUserID user, XnPoint3D* pCoM);
+/**
+ * @brief Get the pixels that belong to a user.
+ *
+ * The output is in a XnSceneMetaData object, holding a map of the pixels of the scene,
+ * with the user's label as the value in the places corresponding with the user's pixels.
+ * Pixels outside the user will not contain the user's ID.
+ * ID 0 means a request for the pixels of all users. In this case, the background will get the label 0.
+ *
+ * @param hInstance [in] A handle to the instance
+ * @param user [in] The user for which to get the pixels
+ * @param pScene [out] XnSceneMetaData object, that holds the pixels of the user
+ */
+XN_C_API XnStatus XN_C_DECL xnGetUserPixels(XnNodeHandle hInstance, XnUserID user, XnSceneMetaData* pScene);
+/**
+ * @brief Register to user callbacks
+ *
+ * @param hInstance [in] A handle to the instance
+ * @param NewUserCB [in] Callback to be called when a new user is identified
+ * @param LostUserCB [in] Callback to be called when an existing user is no longer identified
+ * @param pCookie [in] User's cookie, to be delivered to the callbacks
+ * @param phCallback [out] The handle to these callbacks, to allow unregistration
+ */
+XN_C_API XnStatus XN_C_DECL xnRegisterUserCallbacks(XnNodeHandle hInstance, XnUserHandler NewUserCB, XnUserHandler LostUserCB, void* pCookie, XnCallbackHandle* phCallback);
+/**
+ * @brief Unregister from user callbacks
+ *
+ * @param hInstance [in] A handle to the instance
+ * @param hCallback [in] The handle received from registration
+ */
+XN_C_API void XN_C_DECL xnUnregisterUserCallbacks(XnNodeHandle hInstance, XnCallbackHandle hCallback);
+
+/**
+ * @brief Register to when the user exits the scene (but not lost yet)
+ *
+ * @param hInstance [in] A handle to the instance
+ * @param handler [in] Callback to be called when a user leaves the scene
+ * @param pCookie [in] User's cookie, to be delivered to the callbacks
+ * @param phCallback [out] The handle to this callback, to allow unregistration
+ */
+XN_C_API XnStatus XN_C_DECL xnRegisterToUserExit(XnNodeHandle hInstance, XnUserHandler handler, void* pCookie, XnCallbackHandle* phCallback);
+/**
+ * @brief Unregister from when a user exits the scene
+ *
+ * @param hInstance [in] A handle to the instance
+ * @param hCallback [in] The handle received from registration
+ */
+XN_C_API void XN_C_DECL xnUnregisterFromUserExit(XnNodeHandle hInstance, XnCallbackHandle hCallback);
+/**
+ * @brief Register to when a user re-enters the scene after exiting
+ *
+ * @param hInstance [in] A handle to the instance
+ * @param handler [in] Callback to be called when a user leaves the scene
+ * @param pCookie [in] User's cookie, to be delivered to the callbacks
+ * @param phCallback [out] The handle to this callback, to allow unregistration
+ */
+XN_C_API XnStatus XN_C_DECL xnRegisterToUserReEnter(XnNodeHandle hInstance, XnUserHandler handler, void* pCookie, XnCallbackHandle* phCallback);
+/**
+ * @brief Unregister from when a user re-enters the scene
+ *
+ * @param hInstance [in] A handle to the instance
+ * @param hCallback [in] The handle received from registration
+ */
+XN_C_API void XN_C_DECL xnUnregisterFromUserReEnter(XnNodeHandle hInstance, XnCallbackHandle hCallback);
+/** @} */
+
+//---------------------------------------------------------------------------
+// Skeleton Capability
+//---------------------------------------------------------------------------
+
+/**
+ * @ingroup user
+ * @defgroup skeleton Skeleton Capability
+ * The Skeleton capability (@ref XN_CAPABILITY_SKELETON) allows a @ref user to also output the skeleton
+ * data of the user, meaning, where every joint is located.
+ * @{
+ */
+
+/**
+ * @brief Check if generator supports a specific joint.
+ *
+ * @param hInstance [in] A handle to the instance
+ * @param eJoint [in] The joint to check
+ */
+XN_C_API XnBool XN_C_DECL xnIsJointAvailable(XnNodeHandle hInstance, XnSkeletonJoint eJoint);
+/**
+* @brief Check if generator supports a specific profile.
+*
+* @param hInstance [in] A handle to the instance
+* @param eProfile [in] The profile to check
+*/
+XN_C_API XnBool XN_C_DECL xnIsProfileAvailable(XnNodeHandle hInstance, XnSkeletonProfile eProfile);
+/**
+* @brief Set the profile. this will set some joints to be active, and others to be inactive.
+*
+* @param hInstance [in] A handle to the instance
+* @param eProfile [in] The profile to set
+*/
+XN_C_API XnStatus XN_C_DECL xnSetSkeletonProfile(XnNodeHandle hInstance, XnSkeletonProfile eProfile);
+/**
+* @brief Change the state of a specific joint, to be active or inactive
+*
+* @param hInstance [in] A handle to the instance
+* @param eJoint [in] The joint
+* @param bState [in] The new state
+*/
+XN_C_API XnStatus XN_C_DECL xnSetJointActive(XnNodeHandle hInstance, XnSkeletonJoint eJoint, XnBool bState);
+/**
+* @brief Check if joint is currently active
+*
+* @param hInstance [in] A handle to the instance
+* @param eJoint [in] The joint to check
+*/
+XN_C_API XnBool XN_C_DECL xnIsJointActive(XnNodeHandle hInstance, XnSkeletonJoint eJoint);
+/**
+* @brief Register to joint configuration changes - when joints are activated and deactivated
+*
+* @param hInstance [in] A handle to the instance
+* @param handler [in] The callback to be called when a joint is activated or deactivated
+* @param pCookie [in] User's cookie, to be delivered to the callbacks
+* @param phCallback [out] The handle to these callbacks, to allow unregistration
+*/
+XN_C_API XnStatus XN_C_DECL xnRegisterToJointConfigurationChange(XnNodeHandle hInstance, XnStateChangedHandler handler, void* pCookie, XnCallbackHandle* phCallback);
+/**
+* @brief Unregister from joint configuration changes
+*
+* @param hInstance [in] A handle to the instance
+* @param hCallback [in] The handle received from registration
+*/
+XN_C_API void XN_C_DECL xnUnregisterFromJointConfigurationChange(XnNodeHandle hInstance, XnCallbackHandle hCallback);
+/**
+* @brief Get all active joints
+*
+* @param hInstance [in] A handle to the instance
+* @param pJoints [out] Preallocated memory for the joints
+* @param pnJoints [in,out] The size of the preallocated memory. Changed to the number of the active joints.
+*/
+XN_C_API XnStatus XN_C_DECL xnEnumerateActiveJoints(XnNodeHandle hInstance, XnSkeletonJoint* pJoints, XnUInt16* pnJoints);
+/**
+* @brief Get a specific joint's full information
+*
+* @param hInstance [in] A handle to the instance
+* @param user [in] The ID of the user to which the skeleton belongs
+* @param eJoint [in] The interesting joint
+* @param pJoint [out] The joint's full information
+*/
+XN_C_API XnStatus XN_C_DECL xnGetSkeletonJoint(XnNodeHandle hInstance, XnUserID user, XnSkeletonJoint eJoint, XnSkeletonJointTransformation* pJoint);
+/**
+* @brief Get a specific joint's position
+*
+* @param hInstance [in] A handle to the instance
+* @param user [in] The ID of the user to which the skeleton belongs
+* @param eJoint [in] The interesting joint
+* @param pJoint [out] The joint's current position
+*/
+XN_C_API XnStatus XN_C_DECL xnGetSkeletonJointPosition(XnNodeHandle hInstance, XnUserID user, XnSkeletonJoint eJoint, XnSkeletonJointPosition* pJoint);
+/**
+* @brief Get a specific joint's orientation
+*
+* @param hInstance [in] A handle to the instance
+* @param user [in] The ID of the user to which the skeleton belongs
+* @param eJoint [in] The interesting joint
+* @param pJoint [out] The joint's current orientation
+*/
+XN_C_API XnStatus XN_C_DECL xnGetSkeletonJointOrientation(XnNodeHandle hInstance, XnUserID user, XnSkeletonJoint eJoint, XnSkeletonJointOrientation* pJoint);
+/**
+ * @brief Check if skeleton is being tracked
+ *
+ * @param hInstance [in] A handle to the instance
+ * @param user [in] Id of the user to check
+ */
+XN_C_API XnBool XN_C_DECL xnIsSkeletonTracking(XnNodeHandle hInstance, XnUserID user);
+/**
+* @brief Check if skeleton is being calibrated
+*
+* @param hInstance [in] A handle to the instance
+* @param user [in] Id of the user to check
+*/
+XN_C_API XnBool XN_C_DECL xnIsSkeletonCalibrated(XnNodeHandle hInstance, XnUserID user);
+/**
+* @brief Check if skeleton is being calibrated
+*
+* @param hInstance [in] A handle to the instance
+* @param user [in] Id of the user to check
+*/
+XN_C_API XnBool XN_C_DECL xnIsSkeletonCalibrating(XnNodeHandle hInstance, XnUserID user);
+/**
+* @brief Request calibration when possible
+*
+* @param hInstance [in] A handle to the instance
+* @param user [in] Id of the user to check
+* @param bForce [in] Disregard previous calibration
+*/
+XN_C_API XnStatus XN_C_DECL xnRequestSkeletonCalibration(XnNodeHandle hInstance, XnUserID user, XnBool bForce);
+/**
+* @brief stop calibration
+*
+* @param hInstance [in] A handle to the instance
+* @param user [in] Id of the user to check
+*/
+XN_C_API XnStatus XN_C_DECL xnAbortSkeletonCalibration(XnNodeHandle hInstance, XnUserID user);
+/**
+* @brief Save the calibration data to file
+*
+* @param hInstance [in] A handle to the instance
+* @param user [in] the user for which the calibration is saved
+* @param strFileName [in] The file to which to save the calibration data
+*/
+XN_C_API XnStatus XN_C_DECL xnSaveSkeletonCalibrationDataToFile(XnNodeHandle hInstance, XnUserID user, const XnChar* strFileName);
+/**
+* @brief Load previously saved calibration data from file
+*
+* @param hInstance [in] A handle to the instance
+* @param user [in] the user to be assigned the calibration data
+* @param strFileName [in] The file from which to load the calibration data.
+*/
+XN_C_API XnStatus XN_C_DECL xnLoadSkeletonCalibrationDataFromFile(XnNodeHandle hInstance, XnUserID user, const XnChar* strFileName);
+/**
+ * @brief Save the calibration data
+ *
+ * @param hInstance [in] A handle to the instance
+ * @param user [in] the user for which the calibration is saved
+ * @param nSlot [in] The slot to use for saving the calibration data
+ */
+XN_C_API XnStatus XN_C_DECL xnSaveSkeletonCalibrationData(XnNodeHandle hInstance, XnUserID user, XnUInt32 nSlot);
+/**
+* @brief Load previously saved calibration data.
+*
+* @param hInstance [in] A handle to the instance
+* @param user [in] the user to be assigned the calibration data
+* @param nSlot [in] The slot to use for saving the calibration data.
+*/
+XN_C_API XnStatus XN_C_DECL xnLoadSkeletonCalibrationData(XnNodeHandle hInstance, XnUserID user, XnUInt32 nSlot);
+/**
+* @brief Clear the requested slot from any saved calibration data.
+*
+* @param hInstance [in] A handle to the instance
+* @param nSlot [in] The slot to clear
+*/
+XN_C_API XnStatus XN_C_DECL xnClearSkeletonCalibrationData(XnNodeHandle hInstance, XnUInt32 nSlot);
+/**
+* @brief Check if a specific slot already holds calibration data
+*
+* @param hInstance [in] A handle to the instance
+* @param nSlot [in] The slot to check
+*/
+XN_C_API XnBool XN_C_DECL xnIsSkeletonCalibrationData(XnNodeHandle hInstance, XnUInt32 nSlot);
+/**
+* @brief Start tracking a skeleton
+*
+* @param hInstance [in] A handle to the instance
+* @param user [in] Id of the user to check
+*/
+XN_C_API XnStatus XN_C_DECL xnStartSkeletonTracking(XnNodeHandle hInstance, XnUserID user);
+/**
+* @brief Stop tracking a skeleton
+*
+* @param hInstance [in] A handle to the instance
+* @param user [in] Id of the user to check
+*/
+XN_C_API XnStatus XN_C_DECL xnStopSkeletonTracking(XnNodeHandle hInstance, XnUserID user);
+/**
+* @brief Reset the skeleton - discard calibration
+*
+* @param hInstance [in] A handle to the instance
+* @param user [in] Id of the user to check
+*/
+XN_C_API XnStatus XN_C_DECL xnResetSkeleton(XnNodeHandle hInstance, XnUserID user);
+/**
+* @brief Check if a specific pose is required for calibration
+*
+* @param hInstance [in] A handle to the instance
+*/
+XN_C_API XnBool XN_C_DECL xnNeedPoseForSkeletonCalibration(XnNodeHandle hInstance);
+/**
+* @brief Get the pose that is required for calibration
+*
+* @param hInstance [in] A handle to the instance
+* @param strPose [in] Name of the required pose
+*/
+XN_C_API XnStatus XN_C_DECL xnGetSkeletonCalibrationPose(XnNodeHandle hInstance, XnChar* strPose);
+/**
+* @brief Set the skeleton's smoothing factor
+*
+* @param hInstance [in] A handle to the instance
+* @param fFactor [in] The smoothing factor
+*/
+XN_C_API XnStatus XN_C_DECL xnSetSkeletonSmoothing(XnNodeHandle hInstance, XnFloat fFactor);
+/**
+* @brief Register to calibration callbacks.
+*
+* @param hInstance [in] A handle to the instance
+* @param CalibrationStartCB [in] Callback to be called when calibration is starting
+* @param CalibrationEndCB [in] Callback to be called when calibration is complete
+* @param pCookie [in] User's cookie, to be delivered to the callbacks
+* @param phCallback [out] The handle to these callbacks, to allow unregistration
+*/
+XN_C_API XnStatus XN_API_DEPRECATED("Please use RegisterToCalibrationStart/Complete") XN_C_DECL xnRegisterCalibrationCallbacks(XnNodeHandle hInstance, XnCalibrationStart CalibrationStartCB, XnCalibrationEnd CalibrationEndCB, void* pCookie, XnCallbackHandle* phCallback);
+/**
+* @brief Unregister from calibration callbacks
+*
+* @param hInstance [in] A handle to the instance
+* @param hCallback [in] The handle received from registration
+*/
+XN_C_API void XN_API_DEPRECATED("Please use UnregisterFromCalibrationStart/Complete") XN_C_DECL xnUnregisterCalibrationCallbacks(XnNodeHandle hInstance, XnCallbackHandle hCallback);
+/**
+* @brief Register to calibration start callback
+*
+* @param hInstance [in] A handle to the instance
+* @param handler [in] Callback to be called when calibration starts
+* @param pCookie [in] User's cookie, to be delivered to the callback
+* @param phCallback [out] the handle to this callback, to allow unregistration
+*/
+XN_C_API XnStatus XN_C_DECL xnRegisterToCalibrationStart(XnNodeHandle hInstance, XnCalibrationStart handler, void* pCookie, XnCallbackHandle* phCallback);
+/**
+* @brief Unregister from calibration start callback
+*
+* @param [in] hInstance A handle to the instance
+* @param [in] hCallback The handle received from registration
+*/
+XN_C_API void XN_C_DECL xnUnregisterFromCalibrationStart(XnNodeHandle hInstance, XnCallbackHandle hCallback);
+
+/**
+* @brief Register to calibration status while calibration is in progress
+*
+* @param hInstance [in] A handle to the instance
+* @param handler [in] Callback to be called when calibration is in progress
+* @param pCookie [in] User's cookie, to be delivered to the callbacks
+* @param phCallback [out] The handle to this callback, to allow unregistration
+*/
+XN_C_API XnStatus XN_C_DECL xnRegisterToCalibrationInProgress(XnNodeHandle hInstance, XnCalibrationInProgress handler, void* pCookie, XnCallbackHandle* phCallback);
+/**
+* @brief Unregister from calibration status while in progress
+*
+* @param hInstance [in] A handle to the instance
+* @param hCallback [in] The handle received from registration
+*/
+XN_C_API void XN_C_DECL xnUnregisterFromCalibrationInProgress(XnNodeHandle hInstance, XnCallbackHandle hCallback);
+/**
+* @brief Register to when calibration is complete, with status
+*
+* @param hInstance [in] A handle to the instance
+* @param handler [in] Callback to be called when calibration is complete
+* @param pCookie [in] User's cookie, to be delivered to the callbacks
+* @param phCallback [out] The handle to this callback, to allow unregistration
+*/
+XN_C_API XnStatus XN_C_DECL xnRegisterToCalibrationComplete(XnNodeHandle hInstance, XnCalibrationComplete handler, void* pCookie, XnCallbackHandle* phCallback);
+/**
+* @brief Unregister from calibration complete with status
+*
+* @param hInstance [in] A handle to the instance
+* @param hCallback [in] The handle received from registration
+*/
+XN_C_API void XN_C_DECL xnUnregisterFromCalibrationComplete(XnNodeHandle hInstance, XnCallbackHandle hCallback);
+/** @} */
+
+//---------------------------------------------------------------------------
+// Pose Detection Capability
+//---------------------------------------------------------------------------
+
+/**
+ * @ingroup user
+ * @defgroup pose Pose Detection Capability
+ * The Pose capability (@ref XN_CAPABILITY_POSE_DETECTION) allows a @ref user to recognize when the user
+ * is in a specific pose.
+ * @{
+ */
+
+/**
+* @brief Get the number of the supported poses
+*
+* @param hInstance [in] A handle to the instance
+*/
+XN_C_API XnUInt32 XN_C_DECL xnGetNumberOfPoses(XnNodeHandle hInstance);
+/**
+* @brief Get the names of the supported poses
+*
+* @param hInstance [in] A handle to the instance
+* @param pstrPoses [out] Pre-allocated memory for the names of the supported poses
+* @param pnPoses [in,out] In input - size of the preallocated memory, in output - the number of pose names
+*/
+XN_C_API XnStatus XN_C_DECL xnGetAvailablePoses(XnNodeHandle hInstance, XnChar** pstrPoses, XnUInt32* pnPoses);
+/**
+* @brief Get the names of the supported poses
+*
+* @param hInstance [in] A handle to the instance
+* @param pstrPoses [out] Pre-allocated memory for the names of the supported poses
+* @param nNameLength [in] Memory size for each pose name
+* @param pnPoses [in,out] In input - size of the preallocated memory, in output - the number of pose names
+*/
+XN_C_API XnStatus XN_C_DECL xnGetAllAvailablePoses(XnNodeHandle hInstance, XnChar** pstrPoses, XnUInt32 nNameLength, XnUInt32* pnPoses);
+
+/**
+* @brief Tests if a pose is supported
+*
+* @param hInstance [in] A handle to the instance
+* @param strPose [in] The pose string to test
+* @return True if the pose is supported and False otherwise.
+*/
+XN_C_API XnBool XN_C_DECL xnIsPoseSupported(XnNodeHandle hInstance, const XnChar* strPose);
+
+/**
+* @brief Gets the current pose status
+*
+* @param hInstance [in] A handle to the instance
+* @param userID [in] The user whose pose status we are interested in.
+* @param poseName [in] The pose we want to get a status on.
+* @param poseTime [out] The time stamp in which the user entered into the pose (0 if not in pose).
+* @param eStatus [out] The status of the user's pose, i.e. the progress error for getting into
+* pose (XnPoseDetectionStatus, the same as received from the in progress
+* callback. See @ref xnRegisterToPoseDetectionInProgress).
+* @param eState [out] The state of the user pose (i.e. in pose, out of pose).
+* @return The success status. The data is invalid if failed.
+*/
+XN_C_API XnStatus xnGetPoseStatus(XnNodeHandle hInstance, XnUserID userID, const XnChar* poseName, XnUInt64* poseTime, XnPoseDetectionStatus* eStatus, XnPoseDetectionState* eState);
+/**
+* @brief Start detection of a specific pose for a specific user
+*
+* @param hInstance [in] A handle to the instance
+* @param strPose [in] Name of requested pose
+* @param user [in] Id of user
+*/
+XN_C_API XnStatus XN_C_DECL xnStartPoseDetection(XnNodeHandle hInstance,const XnChar* strPose, XnUserID user);
+/**
+* @brief Stop detection of poses for a specific user
+*
+* @param hInstance [in] A handle to the instance
+* @param user [in] Id of user
+*/
+XN_C_API XnStatus XN_C_DECL xnStopPoseDetection(XnNodeHandle hInstance, XnUserID user);
+/**
+* @brief Stop detection of a specific pose for a specific user
+*
+* @param hInstance [in] A handle to the instance
+* @param user [in] Id of user
+* @param strPose [in] Name of the pose
+*/
+XN_C_API XnStatus XN_C_DECL xnStopSinglePoseDetection(XnNodeHandle hInstance, XnUserID user, const XnChar* strPose);
+/**
+* @brief Register to callbacks for pose events
+*
+* @param hInstance [in] A handle to the instance
+* @param PoseDetectionStartCB [in] Function to be called when the pose is detected
+* @param PoseDetectionEndCB [in] Function to be called when the user is out of pose
+* @param pCookie [in] User's cookie, to be delivered to the callbacks
+* @param phCallback [out] The handle to these callbacks, to allow unregistration
+*/
+XN_C_API XnStatus XN_API_DEPRECATED("Please use PoseDetected and/or OutOfPose callbacks") XN_C_DECL xnRegisterToPoseCallbacks(XnNodeHandle hInstance, XnPoseDetectionCallback PoseDetectionStartCB, XnPoseDetectionCallback PoseDetectionEndCB, void* pCookie, XnCallbackHandle* phCallback);
+/**
+* @brief Unregister from pose events
+*
+* @param hInstance [in] A handle to the instance
+* @param hCallback [in] The handle received from registration
+*/
+XN_C_API void XN_API_DEPRECATED("Please use PoseDetected and/or OutOfPose callbacks") XN_C_DECL xnUnregisterFromPoseCallbacks(XnNodeHandle hInstance, XnCallbackHandle hCallback);
+
+/**
+* @brief Register to callback when a user is in pose
+*
+* @param hInstance [in] A handle to the instance
+* @param handler [in] Callback to be called when the pose is detected
+* @param pCookie [in] User's cookie, to be delivered to the callback
+* @param phCallback [out] the handle to this callback, to allow unregistration
+*/
+XN_C_API XnStatus xnRegisterToPoseDetected(XnNodeHandle hInstance, XnPoseDetectionCallback handler, void* pCookie, XnCallbackHandle* phCallback);
+/**
+* @brief Unregister from pose detected callback
+*
+* @param [in] hInstance A handle to the instance
+* @param [in] hCallback The handle received from registration
+*/
+XN_C_API void xnUnregisterFromPoseDetected(XnNodeHandle hInstance, XnCallbackHandle hCallback);
+
+/**
+* @brief Register to callback when a use is no longer in pose
+*
+* @param hInstance [in] A handle to the instance
+* @param handler [in] Callback to be called when user isn't in pose anymore
+* @param pCookie [in] User's cookie, to be delivered to the callback
+* @param phCallback [out] the handle to this callback, to allow unregistration
+*/
+XN_C_API XnStatus xnRegisterToOutOfPose(XnNodeHandle hInstance, XnPoseDetectionCallback handler, void* pCookie, XnCallbackHandle* phCallback);
+/**
+* @brief Unregister from out of pose callback
+*
+* @param [in] hInstance A handle to the instance
+* @param [in] hCallback The handle received from registration
+*/
+XN_C_API void xnUnregisterFromOutOfPose(XnNodeHandle hInstance, XnCallbackHandle hCallback);
+
+/**
+* @brief Register to callback for status when pose is detected
+*
+* @param hInstance [in] A handle to the instance
+* @param handler [in] Function to be called when pose detection is in progress
+* @param pCookie [in] User's cookie, to be delivered to the callbacks
+* @param phCallback [out] The handle to these callbacks, to allow unregistration
+*/
+XN_C_API XnStatus XN_C_DECL xnRegisterToPoseDetectionInProgress(XnNodeHandle hInstance, XnPoseDetectionInProgress handler, void* pCookie, XnCallbackHandle* phCallback);
+/**
+* @brief Unregister from pose status callback
+*
+* @param hInstance [in] A handle to the instance
+* @param hCallback [in] The handle received from registration
+*/
+XN_C_API void XN_C_DECL xnUnregisterFromPoseDetectionInProgress(XnNodeHandle hInstance, XnCallbackHandle hCallback);
+
+/** @} */
+
+//---------------------------------------------------------------------------
+// Hands Generator
+//---------------------------------------------------------------------------
+
+/**
+ * @ingroup prd_node
+ * @defgroup hands Hands Generator
+ * A Hands Generator node is a @ref generator that tracks hand points. It supports all @ref generator functions,
+ * and adds additional functions.
+ * @{
+ */
+
+/**
+ * @brief Creates an hands generator.
+ *
+ * @param pContext [in] The context in which to create the hands generator.
+ * @param phHandsGenerator [out] A handle to the created hands generator.
+ * @param pQuery [in] Optional. Can be used to select which hands generator to create. If not specified, this function may create any hands generator that is available.
+ * @param pErrors [in] Optional. If provided, will be filled with information about hands generators that could not be created.
+ */
+XN_C_API XnStatus XN_C_DECL xnCreateHandsGenerator(
+ XnContext* pContext,
+ XnNodeHandle* phHandsGenerator,
+ XnNodeQuery* pQuery,
+ XnEnumerationErrors* pErrors
+ );
+
+/**
+* @brief Register to hands callbacks
+*
+* @param hInstance [in] A handle to the instance
+* @param CreateCB [in] Callback to be called when a new hand is created
+* @param UpdateCB [in] Callback to be called when an existing hand has a new position
+* @param DestroyCB [in] Callback to be called when an existing hand has vanished
+* @param pCookie [in] User's cookie, to be delivered to the callbacks
+* @param phCallback [out] The handle to these callbacks, to allow unregistration
+*/
+XN_C_API XnStatus XN_C_DECL xnRegisterHandCallbacks(XnNodeHandle hInstance, XnHandCreate CreateCB, XnHandUpdate UpdateCB, XnHandDestroy DestroyCB, void* pCookie, XnCallbackHandle* phCallback);
+/**
+* @brief Unregister from hands callbacks
+*
+* @param hInstance [in] A handle to the instance
+* @param hCallback [in] The handle received from registration
+*/
+XN_C_API void XN_C_DECL xnUnregisterHandCallbacks(XnNodeHandle hInstance, XnCallbackHandle hCallback);
+/**
+* @brief Stop tracking a specific hand
+*
+* @param hInstance [in] A handle to the instance
+* @param user [in] The hand to stop tracking
+*/
+XN_C_API XnStatus XN_C_DECL xnStopTracking(XnNodeHandle hInstance, XnUserID user);
+/**
+* @brief Stop tracking all hands
+*
+* @param hInstance [in] A handle to the instance
+*/
+XN_C_API XnStatus XN_C_DECL xnStopTrackingAll(XnNodeHandle hInstance);
+/**
+* @brief Start tracking at a specific position
+*
+* @param hInstance [in] A handle to the instance
+* @param pPosition [in] The position at which there is a new hand
+*/
+XN_C_API XnStatus XN_C_DECL xnStartTracking(XnNodeHandle hInstance, const XnPoint3D* pPosition);
+/**
+* @brief Change smoothing factor
+*
+* @param hInstance [in] A handle to the instance
+* @param fFactor [in] Smoothing factor, in the range 0..1. 0 Means no smoothing, 1 means infinite smoothing. Inside the range is generator dependent.
+*/
+XN_C_API XnStatus XN_C_DECL xnSetTrackingSmoothing(XnNodeHandle hInstance, XnFloat fFactor);
+/** @} */
+
+//---------------------------------------------------------------------------
+// Hand Touching FOV Edge Capability
+//---------------------------------------------------------------------------
+
+/**
+* @ingroup user
+* @defgroup touchingEdge Hand Touching FOV Edge Capability
+* The Touching FOV Edge capability (@ref XN_CAPABILITY_HAND_TOUCHING_FOV_EDGE) allows callbacks when a hand (from hands generator) is touching the edge of the FOV
+* @{
+*/
+
+/**
+* @brief Register to when a hand is approaching the edge of the FOV
+*
+* @param hInstance [in] A handle to the instance
+* @param handler [in] Callback to be called when a hand is approaching the FOV
+* @param pCookie [in] User's cookie, to be delivered to the callbacks
+* @param phCallback [out] The handle to these callbacks, to allow unregistration
+*/
+XN_C_API XnStatus XN_C_DECL xnRegisterToHandTouchingFOVEdge(XnNodeHandle hInstance, XnHandTouchingFOVEdge handler, void* pCookie, XnCallbackHandle* phCallback);
+/**
+* @brief Unregister from hand approaching the edge of the FOV
+*
+* @param hInstance [in] A handle to the instance
+* @param hCallback [in] The handle received from registration
+*/
+XN_C_API void XN_C_DECL xnUnregisterFromHandTouchingFOVEdge(XnNodeHandle hInstance, XnCallbackHandle hCallback);
+/** @} */
+
+//---------------------------------------------------------------------------
+// Audio Generator
+//---------------------------------------------------------------------------
+
+/**
+ * @ingroup prd_node
+ * @defgroup audio Audio Generator
+ * An Audio Generator node is a @ref generator that outputs audio data. It supports all @ref generator functions,
+ * and adds additional functions.
+ * @{
+ */
+
+/**
+ * @brief Creates an audio generator.
+ *
+ * @param pContext [in] The context in which to create the audio generator.
+ * @param phAudioGenerator [out] A handle to the created audio generator.
+ * @param pQuery [in] Optional. Can be used to select which audio generator to create. If not specified, this function may create any audio generator that is available.
+ * @param pErrors [in] Optional. If provided, will be filled with information about audio generators that could not be created.
+ */
+XN_C_API XnStatus XN_C_DECL xnCreateAudioGenerator(
+ XnContext* pContext,
+ XnNodeHandle* phAudioGenerator,
+ XnNodeQuery* pQuery,
+ XnEnumerationErrors* pErrors
+ );
+
+XN_C_API XnUChar* XN_C_DECL xnGetAudioBuffer(XnNodeHandle hInstance);
+XN_C_API XnUInt32 XN_C_DECL xnGetSupportedWaveOutputModesCount(XnNodeHandle hInstance);
+XN_C_API XnStatus XN_C_DECL xnGetSupportedWaveOutputModes(XnNodeHandle hInstance, XnWaveOutputMode* aSupportedModes, XnUInt32* pnCount);
+XN_C_API XnStatus XN_C_DECL xnSetWaveOutputMode(XnNodeHandle hInstance, const XnWaveOutputMode* OutputMode);
+XN_C_API XnStatus XN_C_DECL xnGetWaveOutputMode(XnNodeHandle hInstance, XnWaveOutputMode* OutputMode);
+XN_C_API XnStatus XN_C_DECL xnRegisterToWaveOutputModeChanges(XnNodeHandle hInstance, XnStateChangedHandler handler, void* pCookie, XnCallbackHandle* phCallback);
+XN_C_API void XN_C_DECL xnUnregisterFromWaveOutputModeChanges(XnNodeHandle hInstance, XnCallbackHandle hCallback);
+
+/**
+ * @brief Gets the current audio meta data.
+ *
+ * @param hInstance [in] A handle to the instance.
+ * @param pMetaData [in] The struct to be filled.
+ */
+XN_C_API void XN_C_DECL xnGetAudioMetaData(XnNodeHandle hInstance, XnAudioMetaData* pMetaData);
+
+/** @} */
+
+//---------------------------------------------------------------------------
+// Mocks
+//---------------------------------------------------------------------------
+
+/**
+ * @ingroup prd_node
+ * @defgroup mocks Mock Nodes
+ * @{
+ */
+
+XN_C_API XnStatus XN_C_DECL xnMockDepthSetData(XnNodeHandle hInstance, XnUInt32 nFrameID, XnUInt64 nTimestamp, XnUInt32 nDataSize, const XnDepthPixel* pData);
+XN_C_API XnStatus XN_C_DECL xnMockImageSetData(XnNodeHandle hInstance, XnUInt32 nFrameID, XnUInt64 nTimestamp, XnUInt32 nDataSize, const XnUInt8* pData);
+XN_C_API XnStatus XN_C_DECL xnMockIRSetData(XnNodeHandle hInstance, XnUInt32 nFrameID, XnUInt64 nTimestamp, XnUInt32 nDataSize, const XnIRPixel* pData);
+XN_C_API XnStatus XN_C_DECL xnMockAudioSetData(XnNodeHandle hInstance, XnUInt32 nFrameID, XnUInt64 nTimestamp, XnUInt32 nDataSize, const XnUInt8* pData);
+XN_C_API XnStatus XN_C_DECL xnMockRawSetData(XnNodeHandle hInstance, XnUInt32 nFrameID, XnUInt64 nTimestamp, XnUInt32 nDataSize, const void* pData);
+
+/** @} */
+
+//---------------------------------------------------------------------------
+// Codecs
+//---------------------------------------------------------------------------
+
+/**
+ * @ingroup prd_node
+ * @defgroup codec Codec
+ * A Codec node is a @ref node that allows compression and decompression of data. It supports all @ref node functions,
+ * and adds additional functions.
+ * @{
+ */
+
+XN_C_API XnStatus XN_C_DECL xnCreateCodec(XnContext* pContext, XnCodecID codecID, XnNodeHandle hInitializerNode, XnNodeHandle* phCodec);
+XN_C_API XnCodecID XN_C_DECL xnGetCodecID(XnNodeHandle hCodec);
+XN_C_API XnStatus XN_C_DECL xnEncodeData(XnNodeHandle hCodec, const void* pSrc, XnUInt32 nSrcSize,
+ void* pDst, XnUInt32 nDstSize, XnUInt* pnBytesWritten);
+XN_C_API XnStatus XN_C_DECL xnDecodeData(XnNodeHandle hCodec, const void* pSrc, XnUInt32 nSrcSize,
+ void* pDst, XnUInt32 nDstSize, XnUInt* pnBytesWritten);
+
+/** @} */
+
+//---------------------------------------------------------------------------
+// Recorder
+//---------------------------------------------------------------------------
+/**
+ * @ingroup prd_node
+ * @defgroup recorder Recorder
+ * A Recorder node is a @ref node that allows recording of data. It supports all @ref node functions,
+ * and adds additional functions.
+ * @{
+ */
+
+/**
+ * @brief Creates a recorder.
+ *
+ * @param pContext [in] The context in which to create the recorder.
+ * @param strFormatName [in] Optional. The name of the format the recorded file will be in. If NULL, file will be in ONI format.
+ * @param phRecorder [out] A pointer to the created recorder handle.
+ */
+XN_C_API XnStatus XN_C_DECL xnCreateRecorder(XnContext* pContext, const XnChar* strFormatName, XnNodeHandle* phRecorder);
+
+/**
+ * @brief Tells the recorder where to record.
+ *
+ * @param hRecorder [in] A handle to the recorder
+ * @param destType [in] The type of medium to record to. Currently only XN_RECORD_MEDIUM_FILE is supported.
+ * @param strDest [in] Recording destination. If destType is XN_RECORD_MEDIUM_FILE, this specifies a file name.
+ */
+XN_C_API XnStatus XN_C_DECL xnSetRecorderDestination(XnNodeHandle hRecorder, XnRecordMedium destType, const XnChar* strDest);
+
+/**
+ * @brief Returns the recoder's destination
+ *
+ * @param hRecorder [in] A handle to the recorder
+ * @param pDestType [out] The type of medium the recorder is set to record.
+ * @param strDest [out] Recording destination. If destType is XN_RECORD_MEDIUM_FILE, this specifies a file name.
+ * @param nBufSize [in] The size of the strDest buffer.
+ */
+XN_C_API XnStatus XN_C_DECL xnGetRecorderDestination(XnNodeHandle hRecorder, XnRecordMedium* pDestType, XnChar* strDest, XnUInt32 nBufSize);
+
+/**
+ * @brief Adds a node to recording and start recording it. This function must be called on each node that is to be
+ * recorded with this recorder.
+ *
+ * @param hRecorder [in] A handle to the recorder.
+ * @param hNode [in] The node to add to the recording.
+ * @param compression [in] The type of compression that will be used to encode the node's data
+ * (See @ref XnCodecIDs.h). If XN_CODEC_NULL is specified, a default compression
+ * will be chosen according to the node type.
+ */
+XN_C_API XnStatus XN_C_DECL xnAddNodeToRecording(XnNodeHandle hRecorder, XnNodeHandle hNode, XnCodecID compression);
+
+/**
+ * @brief Removes node from recording and stop recording it. This function can be called on a node that was added to
+ * recording with @ref xnAddNodeToRecording.
+ *
+ * @param hRecorder [in] A handle to the recorder.
+ * @param hNode [in] The node to remove from recording.
+ */
+XN_C_API XnStatus XN_C_DECL xnRemoveNodeFromRecording(XnNodeHandle hRecorder, XnNodeHandle hNode);
+
+/**
+ * @brief Records one frame of data from each node that was added to the recorder with @ref xnAddNodeToRecording.
+ *
+ * @param hRecorder [in] A handle to the recorder.
+ */
+XN_C_API XnStatus XN_C_DECL xnRecord(XnNodeHandle hRecorder);
+
+/**
+ * @brief Gets a string representation of the recording format.
+ *
+ * @param hRecorder [in] A handle to the recorder.
+ */
+XN_C_API const XnChar* XN_C_DECL xnGetRecorderFormat(XnNodeHandle hRecorder);
+
+/** @} */
+
+//---------------------------------------------------------------------------
+// Player
+//---------------------------------------------------------------------------
+
+/**
+ * @ingroup prd_node
+ * @defgroup player Player
+ * A Player node is a @ref node that allows playing of a recording. It supports all @ref node functions,
+ * and adds additional functions.
+ * @{
+ */
+
+/**
+ * @brief Creates a player.
+ *
+ * @param pContext [in] The context in which to create the player.
+ * @param strFormatName [in] The name of the recording format that the created player should play.
+ * @param phPlayer [out] Pointer to the created player handle.
+ */
+XN_C_API XnStatus XN_C_DECL xnCreatePlayer(XnContext* pContext, const XnChar* strFormatName, XnNodeHandle* phPlayer);
+
+/**
+ * @brief Determines whether the player will automatically rewind to the beginning of the recording when reaching the end.
+ *
+ * @param hPlayer [in] A handle to the player.
+ * @param bRepeat [in] Determines whether the player will repeat or not.
+ *
+ * @remark If bRepeat is set to TRUE, the player will automatically rewind when reaching the end.
+ * @remark If bRepeat is set to FALSE, the player will stop playing when reaching the end, and will raise the event that was registered with @ref xnRegisterToEndOfFileReached(). In this state, @ref xnIsPlayerAtEOF() returns TRUE.
+ */
+XN_C_API XnStatus XN_C_DECL xnSetPlayerRepeat(XnNodeHandle hPlayer, XnBool bRepeat);
+
+/**
+ * @brief Sets the source for the player, i.e. where the played events will come from.
+
+ * The only supported source type at this point is a file.
+ *
+ * @param hPlayer [in] A handle to the player.
+ * @param sourceType [in] The type of source to set. Currently only XN_RECORD_MEDIUM_FILE is supported.
+ * @param strSource [in] The source from which to play. If sourceType is XN_RECORD_MEDIUM_FILE, strSource specifies a file name.
+ *
+ * @sa xnGetPlayerSource()
+ */
+XN_C_API XnStatus XN_C_DECL xnSetPlayerSource(XnNodeHandle hPlayer, XnRecordMedium sourceType, const XnChar* strSource);
+
+/**
+ * @brief Gets the player's source, i.e where the played events come from.
+ *
+ * @param hPlayer [in] A handle to the player.
+ * @param pSourceType [out] The player's source type.
+ * @param strSource [in] The player's source.
+ * @param nBufSize [in] The size of the buffer specified by strSource.
+ *
+ * @sa xnSetPlayerSource()
+ */
+XN_C_API XnStatus XN_C_DECL xnGetPlayerSource(XnNodeHandle hPlayer, XnRecordMedium* pSourceType, XnChar* strSource, XnUInt32 nBufSize);
+
+/**
+ * @brief Reads the next data element from the player.
+ *
+ * Can cause data updates and/or property updates of the played nodes.
+ *
+ * @param hPlayer [in] A handle to the player.
+ */
+XN_C_API XnStatus XN_C_DECL xnPlayerReadNext(XnNodeHandle hPlayer);
+
+/**
+ * @brief Seeks the player to a specific timestamp, so that playing will continue from that point onwards.
+ * @note For the built-in ONI player, this function is not currently supported and always returns XN_STATUS_NOT_IMPLEMENTED.
+ *
+ * @param hPlayer [in] A handle to the player.
+ * @param nTimeOffset [in] The offset, in microseconds, to move, relative to the specified origin. See the remark below.
+ * @param origin [in] The origin to seek from. See the remark below.
+ *
+ * @remark The meaning of the nTimeOffset parameter changes according to the origin parameter:
+ *
+ * <table>
+ * <tr><td><b>origin</b></td><td><b>Meaning of the nTimeOffset parameter</b></td>
+ * <tr><td>XN_PLAYER_SEEK_SET</td><td>nTimeOffset specifies the total time passed since the beginning of the recording. Note that nTimeOffset will be case to XnUInt64 in this case.</td>
+ * <tr><td>XN_PLAYER_SEEK_CUR</td><td>nTimeOffset specifies a period of time to move, relative to the current player position. A positive value means move forward, and a negative value means move backwards.</td>
+ * <tr><td>XN_PLAYER_SEEK_END</td><td>nTimeOffset specifies a period of time to move, relative to the end of the recording. This must be a negative value.</td></tr>
+ * </table>
+ */
+XN_C_API XnStatus XN_C_DECL xnSeekPlayerToTimeStamp(XnNodeHandle hPlayer, XnInt64 nTimeOffset, XnPlayerSeekOrigin origin);
+
+/**
+ * @brief Seeks the player to a specific frame of a specific played node, so that playing will continue from that frame onwards.
+ *
+ * @param hPlayer [in] A handle to the player.
+ * @param strNodeName [in] The name of the node whose frame is to be sought.
+ * @param nFrameOffset [in] The number of frames to move, relative to the specified origin. See the remark below.
+ * @param origin [in] The origin to seek from. See the remark below.
+ *
+ * @remark The meaning of the nTimeOffset parameter changes according to the origin parameter:
+ *
+ * <table>
+ * <tr><td><b>origin</b></td><td><b>Meaning of the nFrameOffset parameter</b></td>
+ * <tr><td>XN_PLAYER_SEEK_SET</td><td>nFrameOffset specifies the total number of frames since the beginning of the node's recording. Note that nFrameOffset will be case to XnUInt64 in this case.</td>
+ * <tr><td>XN_PLAYER_SEEK_CUR</td><td>nFrameOffset specifies the number of frames to move, relative to the current frame of the specifies node. A positive value means move forward, and a negative value means move backwards.</td>
+ * <tr><td>XN_PLAYER_SEEK_END</td><td>nFrameOffset specifies the number of frames to move, relative to the end of the node's recording. This must be a negative value.</td></tr>
+ * </table>
+ *
+ * @note You can get different results using this function for different values of strNodeName, because the frame numbers of different nodes are not necessarily in sync.
+ */
+XN_C_API XnStatus XN_C_DECL xnSeekPlayerToFrame(XnNodeHandle hPlayer, const XnChar* strNodeName, XnInt32 nFrameOffset, XnPlayerSeekOrigin origin);
+
+/**
+ * @brief Reports the current timestamp of a player, i.e. the amount of time passed since the beginning of the recording.
+ *
+ * @param hPlayer [in] A handle to the player.
+ * @param pnTimestamp [out] A pointer to the retrieved timestamp in microseconds.
+ */
+XN_C_API XnStatus XN_C_DECL xnTellPlayerTimestamp(XnNodeHandle hPlayer, XnUInt64* pnTimestamp);
+
+/**
+ * @brief Reports the current frame number of a specific node played by a player.
+ *
+ * @param hPlayer [in] A handle to the player.
+ * @param strNodeName [in] The name of the node for which to report the frame number.
+ * @param pnFrame [out] A pointer to the reported frame number.
+ *
+ * @remark Different nodes that belong to the player can have different frame numbers, because the nodes are not necessarily in sync.
+ */
+XN_C_API XnStatus XN_C_DECL xnTellPlayerFrame(XnNodeHandle hPlayer, const XnChar* strNodeName, XnUInt32* pnFrame);
+
+/**
+ * @brief Retrieves the number of frames of a specific node played by a player.
+ *
+ * @param hPlayer [in] A handle to the player.
+ * @param strNodeName [in] The name of the node for which to retrieve the number of frames.
+ * @param pnFrames [out] A pointer to the retrieved number of frames.
+ */
+XN_C_API XnStatus XN_C_DECL xnGetPlayerNumFrames(XnNodeHandle hPlayer, const XnChar* strNodeName, XnUInt32* pnFrames);
+
+/**
+ * @brief Gets the name of the format supported by a player.
+ *
+ * @param hPlayer [in] A handle to the player.
+ * @returns The name of the format supported by the player, or NULL if hPlayer is NULL.
+ */
+XN_C_API const XnChar* XN_C_DECL xnGetPlayerSupportedFormat(XnNodeHandle hPlayer);
+
+/**
+ * @brief Retrieves a list of the nodes played by a player.
+ *
+ * @param hPlayer [in] A handle to the player.
+ * @param ppList [out] A pointer to the retrieved list of nodes.
+ *
+ * @remark This function fills the pointer that is pointed to by ppList with a newly allocated node info list
+ * of the played nodes. This list must later be freed by the caller with @ref xnNodeInfoListFree().
+ */
+XN_C_API XnStatus XN_C_DECL xnEnumeratePlayerNodes(XnNodeHandle hPlayer, XnNodeInfoList** ppList);
+
+/**
+ * @brief Checks whether the player is at the end-of-file marker.
+ * @note In the built-in ONI player, this function will never return TRUE for a player that is in repeat mode, although the event registered with @ref xnRegisterToEndOfFileReached() will be fired.
+ *
+ * @param hPlayer [in] A handle to the player.
+ *
+ * @sa xnSetPlayerRepeat()
+ */
+XN_C_API XnBool XN_C_DECL xnIsPlayerAtEOF(XnNodeHandle hPlayer);
+
+/**
+ * @brief Registers a callback function to be called when end-of-file is reached.
+ *
+ * @param hPlayer [in] A handle to the player.
+ * @param handler [in] A pointer to a function that will be called.
+ * @param pCookie [in] A user cookie that will be passed to the callback function.
+ * @param phCallback [out] Will be filled with a handle to be passed to @ref xnUnregisterFromEndOfFileReached().
+ *
+ * @sa xnSetPlayerRepeat()
+ */
+XN_C_API XnStatus XN_C_DECL xnRegisterToEndOfFileReached
+ (XnNodeHandle hPlayer, XnStateChangedHandler handler,
+ void* pCookie, XnCallbackHandle* phCallback);
+
+/**
+ * @brief Unregisters a callback function which was registered using @ref xnRegisterToEndOfFileReached().
+ *
+ * @param hInstance [in] A handle to the player.
+ * @param hCallback [in] The handle to the callback returned from @ref xnRegisterToEndOfFileReached().
+ */
+XN_C_API void XN_C_DECL xnUnregisterFromEndOfFileReached
+ (XnNodeHandle hInstance, XnCallbackHandle hCallback);
+
+/**
+ * @brief Sets the playback speed, as a ratio of the time passed in the recording.
+ * A value of 1.0 means the player will try to output frames in the rate they were recorded (according to
+ * their timestamps).
+ * A value bigger than 1.0 means fast-forward, and a value between 0.0 and 1.0 means slow-motion.
+ * The special value of XN_PLAYBACK_SPEED_FASTEST (0.0) means there will be no delay, and that frames will
+ * be returned as soon as asked for.
+ *
+ * @param hInstance [in] A handle to the player.
+ * @param dSpeed [in] The speed ratio (see function description).
+ */
+XN_C_API XnStatus XN_C_DECL xnSetPlaybackSpeed(XnNodeHandle hInstance, XnDouble dSpeed);
+
+/**
+ * @brief Gets the playback speed. see @ref xnSetPlaybackSpeed() for more details.
+ *
+ * @param hInstance [in] A handle to the player.
+ * @returns speed ratio, or -1.0 if this node is not a player.
+ */
+XN_C_API XnDouble XN_C_DECL xnGetPlaybackSpeed(XnNodeHandle hInstance);
+
+/** @} */
+
+//---------------------------------------------------------------------------
+// ScriptNode
+//---------------------------------------------------------------------------
+
+/**
+ * @ingroup prd_node
+ * @defgroup script_node Script Node
+ * A Script node is a @ref node that allows running scripts, and acts as a lifetime manager for nodes created
+ * by that script.
+ * @{
+ */
+
+XN_C_API XnStatus XN_C_DECL xnCreateScriptNode(XnContext* pContext, const XnChar* strFormat, XnNodeHandle* phScript);
+XN_C_API const XnChar* XN_C_DECL xnScriptNodeGetSupportedFormat(XnNodeHandle hScript);
+XN_C_API XnStatus XN_C_DECL xnLoadScriptFromFile(XnNodeHandle hScript, const XnChar* strFileName);
+XN_C_API XnStatus XN_C_DECL xnLoadScriptFromString(XnNodeHandle hScript, const XnChar* strScript);
+XN_C_API XnStatus XN_C_DECL xnScriptNodeRun(XnNodeHandle hScript, XnEnumerationErrors* pErrors);
+
+/** @} */
+
+#endif // __XN_PRD_NODE_H__
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnPrdNodeInfo.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnPrdNodeInfo.h
new file mode 100644
index 00000000..23a081d5
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnPrdNodeInfo.h
@@ -0,0 +1,126 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef __XN_PRD_NODE_INFO_H__
+#define __XN_PRD_NODE_INFO_H__
+
+/**
+ * @ingroup cref
+ * @defgroup prdnodeinfo Production Node Info
+ * This page describes the functionality of a production node info object. Each info object
+ * can represent a possible production node, or an existing one.
+ * @{
+ */
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include <XnTypes.h>
+
+//---------------------------------------------------------------------------
+// Functions
+//---------------------------------------------------------------------------
+
+
+
+/**
+ * Allocates a node info object, and sets its details.
+ *
+ * @param pDescription [in] The description for the new node info object.
+ * @param strCreationInfo [in] The creation info for the new node info object.
+ * @param pNeededNodes [in] A list of node info's that are needed by the new node info.
+ * @param ppNodeInfo [out] A pointer to pointer to the new node info object.
+ */
+XN_C_API XnStatus XN_C_DECL xnNodeInfoAllocate(const XnProductionNodeDescription* pDescription, const XnChar* strCreationInfo, XnNodeInfoList* pNeededNodes, XnNodeInfo** ppNodeInfo);
+
+/**
+ * Frees a node info object
+ *
+ * @param pNodeInfo [in] The node info object to free.
+ */
+XN_C_API void XN_C_DECL xnNodeInfoFree(XnNodeInfo* pNodeInfo);
+
+/**
+ * Sets the instance name of the node info object. The name can only be set BEFORE the instance is
+ * created.
+ *
+ * @param pNodeInfo [in] A production node info object.
+ * @param strInstanceName [in] The name to give to this instance.
+ */
+XN_C_API XnStatus XN_C_DECL xnNodeInfoSetInstanceName(XnNodeInfo* pNodeInfo, const XnChar* strInstanceName);
+
+/**
+ * Gets the description of the production node.
+ *
+ * @param pNodeInfo [in] A production node info object.
+ */
+XN_C_API const XnProductionNodeDescription* XN_C_DECL xnNodeInfoGetDescription(XnNodeInfo* pNodeInfo);
+
+/**
+ * Creates a printable representation of the production tree.
+ *
+ * @param pNodeInfo [in] A production node info object.
+ * @param csResult [in] A buffer to be filled with the printable representation.
+ * @param nSize [in] Size of the buffer.
+ */
+XN_C_API XnStatus XN_C_DECL xnNodeInfoGetTreeStringRepresentation(XnNodeInfo* pNodeInfo, XnChar* csResult, XnUInt32 nSize);
+
+/**
+ * Gets the instance name of the production node.
+ *
+ * @param pNodeInfo [in] A production node info object.
+ */
+XN_C_API const XnChar* XN_C_DECL xnNodeInfoGetInstanceName(XnNodeInfo* pNodeInfo);
+
+/**
+ * Gets the creation info of the production node.
+ *
+ * @param pNodeInfo [in] A production node info object.
+ */
+XN_C_API const XnChar* XN_C_DECL xnNodeInfoGetCreationInfo(XnNodeInfo* pNodeInfo);
+
+/**
+ * Gets the list of needed nodes of the production node.
+ *
+ * @param pNodeInfo [in] A production node info object.
+ */
+XN_C_API XnNodeInfoList* XN_C_DECL xnNodeInfoGetNeededNodes(XnNodeInfo* pNodeInfo);
+
+/**
+ * Gets the handle of the production node. For nodes that weren't created yet, NULL is returned.
+ * If a handle is returned, it should be released when no longer used by calling @ref xnProductionNodeRelease().
+ *
+ * @param pNodeInfo [in] A production node info object.
+ */
+XN_C_API XnNodeHandle XN_C_DECL xnNodeInfoGetRefHandle(XnNodeInfo* pNodeInfo);
+
+XN_C_API XnNodeHandle XN_API_DEPRECATED("Please use xnNodeInfoGetRefHandle() instead") XN_C_DECL xnNodeInfoGetHandle(XnNodeInfo* pNodeInfo);
+
+/**
+ * Gets the additional data object attached to the node info object.
+ *
+ * @param pNodeInfo [in] A production node info object.
+ */
+XN_C_API const void* XN_C_DECL xnNodeInfoGetAdditionalData(XnNodeInfo* pNodeInfo);
+
+/** @} */
+
+#endif // __XN_PRD_NODE_INFO_H__
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnPrdNodeInfoList.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnPrdNodeInfoList.h
new file mode 100644
index 00000000..6fa22eb0
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnPrdNodeInfoList.h
@@ -0,0 +1,226 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef __XN_PRD_NODE_INFO_LIST_H__
+#define __XN_PRD_NODE_INFO_LIST_H__
+
+/**
+ * @ingroup cref
+ * @defgroup infolist Production Node Info List
+ * This page details functions for handling production nodes lists. The lists are implemented as
+ * doubly-linked lists, but it's not recommended to access the list members directly.
+ * instead, use the provided functions for handling the list.
+ *
+ * @section append Adding and Removing Node Info Objects
+ *
+ * Nodes can be added to the list using @ref xnNodeInfoListAdd(). Note that once an info object
+ * is part of the list, it will be freed if that list is freed. A node can be removed by calling @ref
+ * xnNodeInfoListRemove(), which also frees that element.
+ *
+ * A short example:
+ * @code
+// Start with an empty list
+XnNodeInfoList* pList;
+nRetVal = xnNodeInfoListAllocate(&pList);
+// TODO: check error code
+
+// Add first
+pList = xnNodeInfoListAdd(pList, pDescription1, NULL, NULL);
+
+// Add second
+pList = xnNodeInfoListAdd(pList, pDescription2, NULL, NULL);
+ * @endcode
+ *
+ * @section enum Enumeration
+ *
+ * Forward Iteration:
+ * @code
+for (XnNodeInfoListIterator it = xnNodeInfoListGetFirst(pList);
+ xnNodeInfoListIteratorIsValid(it);
+ it = xnNodeInfoListGetNext(it))
+{
+ XnNodeInfo* pCurrent = xnNodeInfoListGetCurrent(it);
+ ...
+}
+ * @endcode
+ *
+ * Backwards Iteration:
+ * @code
+for (XnNodeInfoListIterator it = xnNodeInfoListGetLast(pList);
+ xnNodeInfoListIteratorIsValid(it);
+ it = xnNodeInfoListGetPrevious(it))
+{
+ XnNodeInfo* pCurrent = xnNodeInfoListGetCurrent(it);
+ ...
+}
+ * @endcode
+ * @{
+ */
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include <XnTypes.h>
+
+//---------------------------------------------------------------------------
+// Functions
+//---------------------------------------------------------------------------
+
+/**
+ * Allocates a @ref XnNodeInfoList object. This object should be freed using @ref xnNodeInfoListFree().
+ *
+ * @param ppList [out] The list.
+ */
+XN_C_API XnStatus XN_C_DECL xnNodeInfoListAllocate(XnNodeInfoList** ppList);
+
+/**
+ * Frees a @ref XnNodeInfoList object previously allocated with @ref xnNodeInfoListAllocate().
+ *
+ * @param pList [out] The list.
+ */
+XN_C_API void XN_C_DECL xnNodeInfoListFree(XnNodeInfoList* pList);
+
+/**
+ * Creates and adds a single @ref XnNodeInfo object to the list. See also @ref xnNodeInfoListAddEx().
+ *
+ * @param pList [in] The list.
+ * @param pDescription [in] The description of this production node.
+ * @param strCreationInfo [in] Optional. Additional needed information for instantiation.
+ * @param pNeededNodes [in] Optional. A list of needed nodes.
+ */
+XN_C_API XnStatus XN_C_DECL xnNodeInfoListAdd(XnNodeInfoList* pList, const XnProductionNodeDescription* pDescription, const XnChar* strCreationInfo, XnNodeInfoList* pNeededNodes);
+
+/**
+ * Creates and adds a single @ref XnNodeInfo object to the list, with additional data. This data can be later
+ * extracted using the @ref xnNodeInfoGetAdditionalData(). Before the node info object is freed, the pFreeHandler
+ * callback will be called, so it could free the additional data object.
+ *
+ * @param pList [in] The list.
+ * @param pDescription [in] The description of this production node.
+ * @param strCreationInfo [in] Optional. Additional needed information for instantiation.
+ * @param pNeededNodes [in] Optional. A list of needed nodes.
+ * @param pAdditionalData [in] Additional data, which is specific to this node.
+ * @param pFreeHandler [in] Optional. A callback function for freeing the additional data.
+ */
+XN_C_API XnStatus XN_C_DECL xnNodeInfoListAddEx(XnNodeInfoList* pList, const XnProductionNodeDescription* pDescription, const XnChar* strCreationInfo, XnNodeInfoList* pNeededNodes, const void* pAdditionalData, XnFreeHandler pFreeHandler);
+
+/**
+ * Adds a single @ref XnNodeInfo object to the list.
+ *
+ * @param pList [in] The list.
+ * @param pNode [in] The node to add.
+ */
+XN_C_API XnStatus XN_C_DECL xnNodeInfoListAddNode(XnNodeInfoList* pList, XnNodeInfo* pNode);
+
+/**
+ * Adds a node from another list to this list (the node is not removed from the other list).
+ *
+ * @param pList [in] The list.
+ * @param otherListIt [in] An iterator obtained from another list.
+ */
+XN_C_API XnStatus XN_C_DECL xnNodeInfoListAddNodeFromList(XnNodeInfoList* pList, XnNodeInfoListIterator otherListIt);
+
+/**
+ * Removes an element from the list, and frees it.
+ *
+ * @param pList [in] The list.
+ * @param it [in] Iterator to the element that should be removed.
+ */
+XN_C_API XnStatus XN_C_DECL xnNodeInfoListRemove(XnNodeInfoList* pList, XnNodeInfoListIterator it);
+
+/**
+ * Clears a node info list, freeing all the elements in it.
+ *
+ * @param pList [in] The list to be freed.
+ */
+XN_C_API XnStatus XN_C_DECL xnNodeInfoListClear(XnNodeInfoList* pList);
+
+/**
+ * Appends another list at the end of this list. Note that the other list becomes empty,
+ * but still needs to be freed.
+ *
+ * @param pList [in] A list.
+ * @param pOther [in] The list to be appended.
+ */
+XN_C_API XnStatus XN_C_DECL xnNodeInfoListAppend(XnNodeInfoList* pList, XnNodeInfoList* pOther);
+
+/**
+* Checks if the given list is empty
+*
+* @param pList [in] A list.
+*/
+XN_C_API XnBool XN_C_DECL xnNodeInfoListIsEmpty(XnNodeInfoList* pList);
+
+/**
+ * Gets the first element of the list.
+ *
+ * @param pList [in] [Optional] A list.
+ *
+ * @returns an iterator to the first element of the list, or NULL if the list is empty.
+ */
+XN_C_API XnNodeInfoListIterator XN_C_DECL xnNodeInfoListGetFirst(XnNodeInfoList* pList);
+
+/**
+ * Gets the last element of the list.
+ *
+ * @param pList [in] [Optional] A list.
+ *
+ * @returns an iterator to the last element of the list, or NULL if the list is empty.
+ */
+XN_C_API XnNodeInfoListIterator XN_C_DECL xnNodeInfoListGetLast(XnNodeInfoList* pList);
+
+/**
+ * Checks if the current iterator points to a valid location.
+ *
+ * @param it [in] An iterator.
+ */
+XN_C_API XnBool XN_C_DECL xnNodeInfoListIteratorIsValid(XnNodeInfoListIterator it);
+
+/**
+ * Gets current element from an iterator.
+ *
+ * @param it [in] An iterator.
+ *
+ * @returns an @ref XnNodeInfo pointer.
+ */
+XN_C_API XnNodeInfo* XN_C_DECL xnNodeInfoListGetCurrent(XnNodeInfoListIterator it);
+
+/**
+ * Gets an iterator to the next element from a current iterator.
+ *
+ * @param it [in] An iterator.
+ *
+ * @returns an iterator to the next element.
+ */
+XN_C_API XnNodeInfoListIterator XN_C_DECL xnNodeInfoListGetNext(XnNodeInfoListIterator it);
+
+/**
+ * Gets an iterator to the previous element from a current iterator.
+ *
+ * @param it [in] An iterator.
+ *
+ * @returns an iterator to the previous element.
+ */
+XN_C_API XnNodeInfoListIterator XN_C_DECL xnNodeInfoListGetPrevious(XnNodeInfoListIterator it);
+
+/** @} */
+
+#endif // __XN_PRD_NODE_INFO_LIST_H__
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnProfiling.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnProfiling.h
new file mode 100644
index 00000000..87d20269
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnProfiling.h
@@ -0,0 +1,131 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef _XN_PROFILING_H_
+#define _XN_PROFILING_H_
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include <XnOS.h>
+
+//---------------------------------------------------------------------------
+// Defines
+//---------------------------------------------------------------------------
+#define INVALID_PROFILING_HANDLE -1
+
+//---------------------------------------------------------------------------
+// Types
+//---------------------------------------------------------------------------
+typedef XnInt32 XnProfilingHandle;
+
+//---------------------------------------------------------------------------
+// Exported Function Declaration
+//---------------------------------------------------------------------------
+
+/**
+* Initializes profiling.
+*
+* @param nProfilingInterval [in] The number of milliseconds between profiler printings. A value
+* of zero means profiling is off.
+*/
+XN_C_API XnStatus XN_C_DECL xnProfilingInit(XnUInt32 nProfilingInterval = 0);
+
+/**
+* Initializes using INI file.
+*
+* @param cpINIFileName [in] Name of INI file.
+* @param cpSectionName [in] Name of section in INI file.
+*/
+XN_C_API XnStatus XN_C_DECL xnProfilingInitFromINI(const XnChar* cpINIFileName, const XnChar* cpSectionName);
+
+/**
+* Shuts down profiling.
+*/
+XN_C_API XnStatus XN_C_DECL xnProfilingShutdown();
+
+/**
+* Returns TRUE if profiling is active, or FALSE otherwise.
+*/
+XN_C_API XnBool XN_C_DECL xnProfilingIsActive();
+
+/**
+* Start a profiled section. This function is not meant to be used directly. Please use the
+* XN_PROFILING_START_SECTION macro.
+*
+* @param csSectionName [in] The name of the profiled section.
+* @param bMT [in] TRUE if this section is multi-threaded, FALSE otherwise.
+* @param pHandle [out] A handle to be used each time this section executes again.
+*/
+XN_C_API XnStatus XN_C_DECL xnProfilingSectionStart(const char* csSectionName, XnBool bMT, XnProfilingHandle* pHandle);
+
+/**
+* Ends a profiled section. This function is not meant to be used directly. Please use the
+* XN_PROFILING_END_SECTION macro.
+*
+* @param pHandle [in] A handle returned from xnProfilingSectionStart.
+*/
+XN_C_API XnStatus XN_C_DECL xnProfilingSectionEnd(XnProfilingHandle* pHandle);
+
+
+/**
+* Starts a profiled section. The code section between this declaration
+* and the following XN_PROFILING_END_SECTION declaration will be time-measured.
+*
+* @param name [in] The name of the section (for printing purposes).
+* @param mt [in] TRUE if this section is multi-threaded, FALSE otherwise.
+*/
+#define _XN_PROFILING_START_SECTION(name, mt) \
+ { \
+ static XnProfilingHandle __profiling = INVALID_PROFILING_HANDLE; \
+ if (xnProfilingIsActive()) \
+ { \
+ xnProfilingSectionStart(name, mt, &__profiling); \
+ }
+
+#define XN_PROFILING_START_SECTION(name) _XN_PROFILING_START_SECTION(name, FALSE)
+#define XN_PROFILING_START_MT_SECTION(name) _XN_PROFILING_START_SECTION(name, TRUE)
+
+/**
+* Ends a profiled section.
+*/
+#define XN_PROFILING_END_SECTION \
+ if (__profiling != INVALID_PROFILING_HANDLE) \
+ { \
+ xnProfilingSectionEnd(&__profiling); \
+ } \
+ }
+
+/**
+* Starts a profiled section, giving it the name of the current function.
+* The code section between this declaration and the following XN_PROFILING_END_FUNCTION
+* declaration will be time-measured.
+*
+* @param name [in] The name of the section (for printing purposes).
+*/
+#define XN_PROFILING_START_FUNCTION XN_PROFILING_START_SECTION(__FUNCTION__)
+
+/**
+* Ends a profiled function.
+*/
+#define XN_PROFILING_END_FUNCTION XN_PROFILING_END_SECTION
+
+#endif //_XN_PROFILING_H_
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnPropNames.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnPropNames.h
new file mode 100644
index 00000000..68f47138
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnPropNames.h
@@ -0,0 +1,62 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef __XN_PROP_NAMES_H__
+#define __XN_PROP_NAMES_H__
+
+//ProductionNode
+#define XN_PROP_STATE_READY "xnStateReady" // int. Meant only for mock nodes.
+
+//Generator
+#define XN_PROP_IS_GENERATING "xnIsGenerating" //int
+#define XN_PROP_MIRROR "xnMirror" //int
+#define XN_PROP_TIMESTAMP "xnTimeStamp" //int
+#define XN_PROP_FRAME_ID "xnFrameID" //int
+#define XN_PROP_NEWDATA "xnNewData" //general. Meant only for mock nodes.
+#define XN_PROP_FRAME_SYNCED_WITH "xnFrameSyncedWith" // String. name of the frame synced
+
+//MapGenerator
+#define XN_PROP_MAP_OUTPUT_MODE "xnMapOutputMode" //general
+#define XN_PROP_SUPPORTED_MAP_OUTPUT_MODES_COUNT "xnSupportedMapOutputModesCount" //int
+#define XN_PROP_SUPPORTED_MAP_OUTPUT_MODES "xnSupportedMapOutputModes" //general
+#define XN_PROP_CROPPING "xnCropping" //general
+#define XN_PROP_BYTES_PER_PIXEL "xnBytesPerPixel" //int
+
+//ImageGenerator
+#define XN_PROP_SUPPORTED_PIXEL_FORMATS "xnSupportedPixelFormats" //general
+#define XN_PROP_PIXEL_FORMAT "xnPixelFormat" //int
+
+//GestureGenerator
+#define XN_PROP_GESTURE_RECOGNIZED "xnGestureRecognized" //general
+#define XN_PROP_GESTURE_PROGRESS "xnGestureProgress" //general
+
+//DepthGenerator
+#define XN_PROP_DEVICE_MAX_DEPTH "xnDeviceMaxDepth" //int
+#define XN_PROP_SUPPORTED_USER_POSITIONS_COUNT "xnSupportedUserPositionsCount" //int
+#define XN_PROP_USER_POSITIONS "xnUserPositions" //general
+#define XN_PROP_FIELD_OF_VIEW "xnFOV" // general (XnFieldOfView)
+
+//AudioGenerator
+#define XN_PROP_WAVE_OUTPUT_MODE "xnWaveOutputMode" //general
+#define XN_PROP_WAVE_SUPPORTED_OUTPUT_MODES_COUNT "xnWaveSupportedOutputModesCount" //int
+#define XN_PROP_WAVE_SUPPORTED_OUTPUT_MODES "xnWaveSupportedOutputModes" //general
+
+#endif //__XN_PROP_NAMES_H__
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnQueries.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnQueries.h
new file mode 100644
index 00000000..a78ebc1d
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnQueries.h
@@ -0,0 +1,159 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef __XN_QUERIES_H__
+#define __XN_QUERIES_H__
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include "XnTypes.h"
+
+//---------------------------------------------------------------------------
+// Exported Functions
+//---------------------------------------------------------------------------
+/**
+ * @ingroup cref
+ * @defgroup queries Queries
+ * This page details functions for building queries. Queries can be used during enumeration, and provide
+ * an easy way for filtering results before they return to user.
+ * @{
+ */
+
+/**
+ * Allocates a new query object. This object must be freed using @ref xnNodeQueryFree().
+ *
+ * @param ppQuery [out] Created query object.
+ */
+XN_C_API XnStatus XN_C_DECL xnNodeQueryAllocate(XnNodeQuery** ppQuery);
+
+/**
+ * Frees a query object previously created using @ref xnNodeQueryAllocate().
+ *
+ * @param pQuery [in] Query object.
+ */
+XN_C_API void XN_C_DECL xnNodeQueryFree(XnNodeQuery* pQuery);
+
+/**
+ * Sets the requested vendor.
+ *
+ * @param pQuery [in] Query object.
+ * @param strVendor [in] Vendor Name.
+ */
+XN_C_API XnStatus XN_C_DECL xnNodeQuerySetVendor(XnNodeQuery* pQuery, const XnChar* strVendor);
+
+/**
+ * Sets the requested name.
+ *
+ * @param pQuery [in] Query object.
+ * @param strName [in] Product Name.
+ */
+XN_C_API XnStatus XN_C_DECL xnNodeQuerySetName(XnNodeQuery* pQuery, const XnChar* strName);
+
+/**
+ * Sets the minimum required version.
+ *
+ * @param pQuery [in] Query object.
+ * @param pMinVersion [in] Min Version.
+ */
+XN_C_API XnStatus XN_C_DECL xnNodeQuerySetMinVersion(XnNodeQuery* pQuery, const XnVersion* pMinVersion);
+
+/**
+ * Sets the maximum required version.
+ *
+ * @param pQuery [in] Query object.
+ * @param pMaxVersion [in] Max Version.
+ */
+XN_C_API XnStatus XN_C_DECL xnNodeQuerySetMaxVersion(XnNodeQuery* pQuery, const XnVersion* pMaxVersion);
+
+/**
+ * Adds a capability that the node must support. Note that for checking if a capability is supported,
+ * the node must be created (if it's not an existing one). This operation might take a bit longer...
+ *
+ * @param pQuery [in] Query object.
+ * @param strNeededCapability [in] A needed capability name.
+ */
+XN_C_API XnStatus XN_C_DECL xnNodeQueryAddSupportedCapability(XnNodeQuery* pQuery, const XnChar* strNeededCapability);
+
+/**
+ * Adds a MapOutputMode that the node must support. Note that for checking if a capability is supported,
+ * the node must be created (if it's not an existing one). This operation might take a bit longer...
+ *
+ * @param pQuery [in] Query object.
+ * @param pMapOutputMode [in] A map output mode. Each field of the mode can be set to (-1), meaning
+ * results will not be filtered by this field.
+ */
+XN_C_API XnStatus XN_C_DECL xnNodeQueryAddSupportedMapOutputMode(XnNodeQuery* pQuery, const XnMapOutputMode* pMapOutputMode);
+
+/**
+ * Sets the minimum required user positions this node supports. Note that for checking if a capability is supported,
+ * the node must be created (if it's not an existing one). This operation might take a bit longer...
+ *
+ * @param pQuery [in] Query object.
+ * @param nCount [in] The number of required positions.
+ */
+XN_C_API XnStatus XN_C_DECL xnNodeQuerySetSupportedMinUserPositions(XnNodeQuery* pQuery, const XnUInt32 nCount);
+
+/**
+ * Filter results so that only existing nodes will be returned.
+ *
+ * @param pQuery [in] Query object.
+ * @param bExistingNode [in] TRUE to return only existing ones, FALSE otherwise.
+ */
+XN_C_API XnStatus XN_C_DECL xnNodeQuerySetExistingNodeOnly(XnNodeQuery* pQuery, XnBool bExistingNode);
+
+/**
+ * Filter results so that only non-existing nodes will be returned.
+ *
+ * @param pQuery [in] Query object.
+ * @param bNonExistingNode [in] TRUE to return only non-existing ones, FALSE otherwise.
+ */
+XN_C_API XnStatus XN_C_DECL xnNodeQuerySetNonExistingNodeOnly(XnNodeQuery* pQuery, XnBool bNonExistingNode);
+
+/**
+ * Adds a needed node.
+ *
+ * @param pQuery [in] Query object.
+ * @param strInstanceName [in] The name of the needed instance.
+ */
+XN_C_API XnStatus XN_C_DECL xnNodeQueryAddNeededNode(XnNodeQuery* pQuery, const XnChar* strInstanceName);
+
+/**
+ * Sets the creation info field of a query object.
+ *
+ * @param pQuery [in] Query object.
+ * @param strCreationInfo [in] The creation info to set in the query.
+ */
+XN_C_API XnStatus XN_C_DECL xnNodeQuerySetCreationInfo(XnNodeQuery* pQuery, const XnChar* strCreationInfo);
+
+/**
+ * Filters a list of nodes according to query. The list will contain only nodes that match all query terms.
+ * Note that some query terms might require creation of a node, and thus may take longer.
+ *
+ * @param pContext [in] OpenNI Context object.
+ * @param pQuery [in] Query object.
+ * @param pList [in] The list to be filtered.
+ */
+XN_C_API XnStatus XN_C_DECL xnNodeQueryFilterList(XnContext* pContext, const XnNodeQuery* pQuery, XnNodeInfoList* pList);
+
+/** @} */
+
+#endif // __XN_QUERIES_H__
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnQueue.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnQueue.h
new file mode 100644
index 00000000..04122ca3
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnQueue.h
@@ -0,0 +1,198 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef _XN_QUEUE_H
+#define _XN_QUEUE_H
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include "XnList.h"
+
+//---------------------------------------------------------------------------
+// Types
+//---------------------------------------------------------------------------
+/**
+* The queue
+*/
+class XnQueue
+{
+public:
+ /**
+ * Constructor. Initialize internal representations
+ */
+ XnQueue() {}
+ /**
+ * Destructor. Destroy internal representations
+ */
+ virtual ~XnQueue() {}
+
+ /**
+ * Initialized the queue. This method should be called before calling any other method.
+ */
+ virtual XnStatus Init()
+ {
+ return (XN_STATUS_OK);
+ }
+
+ /**
+ * Push a new value to the queue
+ *
+ * @param value [in] The value to add to the queue
+ *
+ * @return XN_STATUS_ALLOC_FAILED Failed to add to the queue because no nodes are available.
+ */
+ virtual XnStatus Push(XnValue const& value)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ nRetVal = m_List.AddLast(value);
+ XN_IS_STATUS_OK(nRetVal);
+
+ return (XN_STATUS_OK);
+ }
+ /**
+ * Pop the value at the top of the queue
+ *
+ * @param value [out] The value that was at the top of the queue
+ *
+ * @return XN_STATUS_IS_EMPTY The queue is empty
+ */
+ virtual XnStatus Pop(XnValue& value)
+ {
+ if (IsEmpty())
+ {
+ return XN_STATUS_IS_EMPTY;
+ }
+
+ value = *(m_List.begin());
+ return m_List.Remove(m_List.begin());
+ }
+
+ /**
+ * Get the value at the top of the queue (it is user responsibility to check queue is not empty)
+ *
+ * @return a reference to the object at head of the queue.
+ */
+ XnValue const& Top() const
+ {
+ return *(m_List.begin());
+ }
+
+ /**
+ * Get the value at the top of the queue (it is user responsibility to check queue is not empty)
+ *
+ * @return a reference to the object at head of the queue.
+ */
+ XnValue& Top()
+ {
+ return *(m_List.begin());
+ }
+
+ /**
+ * Check if queue is empty
+ */
+ XnBool IsEmpty() const
+ {
+ return m_List.IsEmpty();
+ }
+
+ /**
+ * Get current size of queue
+ */
+ virtual XnUInt32 Size() const
+ {
+ return m_List.Size();
+ }
+
+private:
+ XN_DISABLE_COPY_AND_ASSIGN(XnQueue);
+
+ /** The internal XnList with which the queue is implemented. */
+ XnList m_List;
+};
+
+/**
+* Declares a queue of type @a Type, named @a ClassName. The class uses @a Translator for translating
+* from @a Type to XnValue. It is declared using the declspec @a decl.
+* It inherits from @a base. Note that @a base must be a derivative of XnQueue.
+*/
+#define XN_DECLARE_QUEUE_WITH_TRANSLATOR_DECL(decl, Type, ClassName, Translator, base) \
+ class decl ClassName : public base \
+ { \
+ public: \
+ ClassName() {} \
+ ~ClassName() \
+ { \
+ /* We do this using Pop() to make sure memory is freed. */ \
+ Type dummy; \
+ while (Size() != 0) \
+ Pop(dummy); \
+ } \
+ XnStatus Push(Type const& value) \
+ { \
+ XnValue val = Translator::CreateValueCopy(value); \
+ XnStatus nRetVal = base::Push(val); \
+ if (nRetVal != XN_STATUS_OK) \
+ { \
+ Translator::FreeValue(val); \
+ return (nRetVal); \
+ } \
+ return XN_STATUS_OK; \
+ } \
+ XnStatus Pop(Type& value) \
+ { \
+ XnValue val; \
+ XnStatus nRetVal = base::Pop(val); \
+ if (nRetVal != XN_STATUS_OK) return (nRetVal); \
+ value = Translator::GetFromValue(val); \
+ Translator::FreeValue(val); \
+ return XN_STATUS_OK; \
+ } \
+ inline Type const& Top() const { return Translator::GetFromValue(base::Top()); }\
+ inline Type& Top() { return Translator::GetFromValue(base::Top()); } \
+ private: \
+ XN_DISABLE_COPY_AND_ASSIGN(ClassName); \
+ };
+
+/**
+* Declares a queue of type @a Type, named @a ClassName. The class uses @a Translator for translating
+* from @a Type to XnValue.
+* It inherits from @a base. Note that @a base must be a derivative of XnQueue.
+*/
+#define XN_DECLARE_QUEUE_WITH_TRANSLATOR(Type, ClassName, Translator, base) \
+ XN_DECLARE_QUEUE_WITH_TRANSLATOR_DECL(, Type, ClassName, Translator, base)
+
+/**
+* Declares a queue of type @a Type, named @a ClassName, that uses the default translator.
+* It is declared using the declspec @a decl.
+*/
+#define XN_DECLARE_QUEUE_DECL(decl, Type, ClassName) \
+ XN_DECLARE_DEFAULT_VALUE_TRANSLATOR_DECL(decl, Type, XN_DEFAULT_TRANSLATOR_NAME(ClassName)) \
+ XN_DECLARE_QUEUE_WITH_TRANSLATOR_DECL(decl, Type, ClassName, XN_DEFAULT_TRANSLATOR_NAME(ClassName), XnQueue)
+
+/**
+* Declares a queue of type @a Type, named @a ClassName, that uses the default translator.
+*/
+#define XN_DECLARE_QUEUE(Type, ClassName) \
+ XN_DECLARE_QUEUE_DECL(, Type, ClassName)
+
+#endif // _XN_QUEUE_H
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnQueueT.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnQueueT.h
new file mode 100644
index 00000000..3320d118
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnQueueT.h
@@ -0,0 +1,63 @@
+#ifndef _XN_QUEUE_T_H_
+#define _XN_QUEUE_T_H_
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include <XnListT.h>
+
+//---------------------------------------------------------------------------
+// Code
+//---------------------------------------------------------------------------
+template<class T, class TAlloc = XnLinkedNodeDefaultAllocatorT<T> >
+class XnQueueT : protected XnListT<T, TAlloc>
+{
+public:
+ typedef XnListT<T, TAlloc> Base;
+
+ XnQueueT() : Base() {}
+
+ XnQueueT(const XnQueueT& other) : Base()
+ {
+ *this = other;
+ }
+
+ XnQueueT& operator=(const XnQueueT& other)
+ {
+ Base::operator=(other);
+ // no other members
+ return *this;
+ }
+
+ ~XnQueueT() {}
+
+ using Base::ConstIterator;
+ using Base::IsEmpty;
+
+ XnStatus Push(T const& value)
+ {
+ return Base::AddLast(value);
+ }
+
+ XnStatus Pop(T& value)
+ {
+ Iterator it = Begin();
+ if (it == End())
+ {
+ return XN_STATUS_IS_EMPTY;
+ }
+ value = *it;
+ return Base::Remove(it);
+ }
+
+ T const& Top() const { return *Begin(); }
+ T& Top() { return *Begin(); }
+
+ using Base::Begin;
+ using Base::End;
+ using Base::Size;
+};
+
+
+
+#endif // _XN_QUEUE_T_H_ \ No newline at end of file
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnScheduler.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnScheduler.h
new file mode 100644
index 00000000..a5a790c4
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnScheduler.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef _XN_SCHEDULER_H_
+#define _XN_SCHEDULER_H_
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include <XnOS.h>
+
+//---------------------------------------------------------------------------
+// Defines
+//---------------------------------------------------------------------------
+#define XN_MASK_SCHEDULER "Scheduler"
+
+//---------------------------------------------------------------------------
+// Types
+//---------------------------------------------------------------------------
+struct XnScheduler; // forward declaration
+typedef struct XnScheduler XnScheduler;
+
+struct XnScheduledTask; // forward declaration
+typedef struct XnScheduledTask XnScheduledTask;
+
+typedef void (XN_CALLBACK_TYPE* XnTaskCallbackFuncPtr)(void* pCallbackArg);
+
+//---------------------------------------------------------------------------
+// Exported Function Declaration
+//---------------------------------------------------------------------------
+
+/**
+* Starts a scheduler thread. Multiple timers can be added to the created scheduler.
+*
+* @param ppScheduler [out] Upon successful return, holds a handle to created scheduler.
+*/
+XN_C_API XnStatus XN_C_DECL xnSchedulerStart(XnScheduler** ppScheduler);
+
+/**
+* Shuts down a scheduler thread. All timers on that scheduler will be stopped.
+*
+* @param ppScheduler [in/out] A pointer to the scheduler to be shut down.
+*/
+XN_C_API XnStatus XN_C_DECL xnSchedulerShutdown(XnScheduler** ppScheduler);
+
+/**
+* Adds a task to the scheduler.
+*
+* @param pScheduler [in] The scheduler to handle this task.
+* @param nInterval [in] The interval, in milliseconds, in which callback should be called.
+* @param pCallback [in] The function to be called when time arrived.
+* @param pCallbackArg [in] The argument that will be passed to the callback method.
+* @param ppTask [out] Upon successful return, holds a handle to the started task.
+*/
+XN_C_API XnStatus XN_C_DECL xnSchedulerAddTask(XnScheduler* pScheduler, XnUInt64 nInterval, XnTaskCallbackFuncPtr pCallback, void* pCallbackArg, XnScheduledTask** ppTask);
+
+/**
+* Removes a task from the scheduler.
+*
+* @param pScheduler [in] The scheduler this task is registered to.
+* @param ppTask [in/out] The task to be removed from the scheduler.
+*/
+XN_C_API XnStatus XN_C_DECL xnSchedulerRemoveTask(XnScheduler* pScheduler, XnScheduledTask** ppTask);
+
+/**
+* Changes scheduling of a specific task.
+*
+* @param pScheduler [in] The scheduler this task is registered to.
+* @param pTask [in] The task to be removed from the scheduler.
+* @param nInterval [in] The new interval to be used.
+*/
+XN_C_API XnStatus XN_C_DECL xnSchedulerRescheduleTask(XnScheduler* pScheduler, XnScheduledTask* pTask, XnUInt64 nInterval);
+
+#endif //_XN_SCHEDULER_H_
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnStack.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnStack.h
new file mode 100644
index 00000000..7231bc7f
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnStack.h
@@ -0,0 +1,151 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef _XN_STACK_H
+#define _XN_STACK_H
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include "XnList.h"
+
+//---------------------------------------------------------------------------
+// Types
+//---------------------------------------------------------------------------
+/**
+* The stack
+*/
+class XnStack
+{
+public:
+ /**
+ * Constructor. Initialize internal representations
+ */
+ XnStack() {}
+ /**
+ * Destructor. Destroy internal representations
+ */
+ ~XnStack() {}
+
+ /**
+ * Push a new value to the stack
+ *
+ * @param value [in] The value to add to the stack
+ *
+ * @return XN_STATUS_ALLOC_FAILED Failed to add to the stack because no nodes are available.
+ */
+ XnStatus Push(XnValue const& value)
+ {
+ return m_List.AddFirst(value);
+ }
+
+ /**
+ * Pop the value at the top of the stack
+ *
+ * @param value [out] The value that was at the top of the stack
+ *
+ * @return XN_STATUS_IS_EMPTY The stack is empty
+ */
+ XnStatus Pop(XnValue& value)
+ {
+ if (IsEmpty())
+ {
+ return XN_STATUS_IS_EMPTY;
+ }
+
+ value = *(m_List.begin());
+ return m_List.Remove(m_List.begin());
+ }
+
+ /**
+ * Get the value at the top of the queue (it is user responsibility to check queue is not empty)
+ *
+ * @return a reference to the object at head of the queue.
+ */
+ XnValue const& Top() const
+ {
+ return *(m_List.begin());
+ }
+
+ /**
+ * Get the value at the top of the queue (it is user responsibility to check queue is not empty)
+ *
+ * @return a reference to the object at head of the queue.
+ */
+ XnValue& Top()
+ {
+ return *(m_List.begin());
+ }
+
+ /**
+ * Check if stack is empty
+ */
+ XnBool IsEmpty() const
+ {
+ return m_List.IsEmpty();
+ }
+
+ /**
+ * Get current size of the stack
+ */
+ XnUInt32 Size() const
+ {
+ return m_List.Size();
+ }
+
+private:
+ XN_DISABLE_COPY_AND_ASSIGN(XnStack);
+
+ /** The internal XnList with which the stack is implemented. */
+ XnList m_List;
+};
+
+/**
+* Declares a stack of type @a Type, named @a ClassName. The class uses @a Translator for translating
+* from @a Type to XnValue. It is declared using the declspec @a decl.
+*/
+#define XN_DECLARE_STACK_WITH_TRANSLATOR_DECL(decl, Type, ClassName, Translator) \
+ /* Note: we use queue declaration, as this is the same interface. */ \
+ XN_DECLARE_QUEUE_WITH_TRANSLATOR_DECL(decl, Type, ClassName, Translator, XnStack)
+
+/**
+* Declares a stack of type @a Type, named @a ClassName. The class uses @a Translator for translating
+* from @a Type to XnValue.
+*/
+#define XN_DECLARE_STACK_WITH_TRANSLATOR(Type, ClassName, Translator) \
+ XN_DECLARE_STACK_WITH_TRANSLATOR_DECL(, ClassName, Translator)
+
+/**
+* Declares a stack of type @a Type, named @a ClassName, that uses the default translator.
+* It is declared using the declspec @a decl.
+*/
+#define XN_DECLARE_STACK_DECL(decl, Type, ClassName) \
+ XN_DECLARE_DEFAULT_VALUE_TRANSLATOR_DECL(decl, Type, XN_DEFAULT_TRANSLATOR_NAME(ClassName)) \
+ XN_DECLARE_STACK_WITH_TRANSLATOR_DECL(decl, Type, ClassName, XN_DEFAULT_TRANSLATOR_NAME(ClassName))
+
+/**
+* Declares a stack of type @a Type, named @a ClassName, that uses the default translator.
+*/
+#define XN_DECLARE_STACK(Type, ClassName) \
+ XN_DECLARE_STACK_DECL(, Type, ClassName)
+
+
+#endif // _XN_STACK_H
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnStackT.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnStackT.h
new file mode 100644
index 00000000..2963a5f8
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnStackT.h
@@ -0,0 +1,58 @@
+#ifndef _XN_STACK_T_H_
+#define _XN_STACK_T_H_
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include "XnListT.h"
+
+//---------------------------------------------------------------------------
+// Code
+//---------------------------------------------------------------------------
+template<class T, class TAlloc = XnLinkedNodeDefaultAllocatorT<T> >
+class XnStackT : protected XnListT<T, TAlloc>
+{
+public:
+ typedef XnListT<T, TAlloc> Base;
+
+ typedef typename Base::ConstIterator ConstIterator;
+
+ XnStackT() : Base() {}
+
+ XnStackT(const XnStackT& other) : Base()
+ {
+ *this = other;
+ }
+
+ XnStackT& operator=(const XnStackT& other)
+ {
+ Base::operator=(other);
+ // no other members
+ return *this;
+ }
+
+ ~XnStackT() {}
+
+ XnBool IsEmpty() const { return Base::IsEmpty(); }
+
+ XnStatus Push(T const& value) { return Base::AddFirst(value); }
+
+ XnStatus Pop(T& value)
+ {
+ ConstIterator it = Begin();
+ if (it == End())
+ {
+ return XN_STATUS_IS_EMPTY;
+ }
+ value = *it;
+ return Base::Remove(it);
+ }
+
+ T const& Top() const { return *Begin(); }
+ T& Top() { return *Begin(); }
+
+ ConstIterator Begin() const { return Base::Begin(); }
+ ConstIterator End() const { return Base::End(); }
+};
+
+#endif // _XN_STACK_T_H_ \ No newline at end of file
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnStatus.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnStatus.h
new file mode 100644
index 00000000..f279a515
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnStatus.h
@@ -0,0 +1,110 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef __XN_OPEN_NI_STATUS_H__
+#define __XN_OPEN_NI_STATUS_H__
+
+#include "XnPlatform.h"
+
+//---------------------------------------------------------------------------
+// Types
+//---------------------------------------------------------------------------
+
+/** Defines the XnStatus type.
+ * The high word represents the group to which this error belongs to.
+ * The low word is a sequential number inside the group. */
+typedef XnUInt32 XnStatus;
+
+/** Definition of the OK error code. */
+#define XN_STATUS_OK ((XnStatus)0)
+
+//---------------------------------------------------------------------------
+// API
+//---------------------------------------------------------------------------
+
+/**
+ * Converts a Xiron Status enumerator into a meaningful error string.
+ *
+ * @param Status [in] The input Xiron Status to be converted to a string.
+ *
+ * @return A string representation of the Xiron status.
+ */
+XN_C_API const XnChar* XN_C_DECL xnGetStatusString(const XnStatus Status);
+
+/**
+* Gets the name of a Xiron Status as a string.
+*
+* @param Status [in] The input Xiron Status.
+*
+* @return A string representation of the Xiron status name.
+*/
+XN_C_API const XnChar* XN_C_DECL xnGetStatusName(const XnStatus Status);
+
+/**
+* Prints a user message with a description of the error.
+*
+* @param Status [in] The input Xiron Status.
+* @param csUserMessage [in] A user message.
+*
+*/
+XN_C_API void XN_C_DECL xnPrintError(const XnStatus Status, const XnChar* csUserMessage);
+
+//---------------------------------------------------------------------------
+// Enums
+//---------------------------------------------------------------------------
+/** A list of modules for Xiron status. */
+typedef enum XnErrorGroup
+{
+ XN_ERROR_GROUP_NI = 1,
+ XN_ERROR_GROUP_OS = 2,
+ XN_ERROR_GROUP_PRIMESENSE = 3,
+} XnErrorGroup;
+
+/** Constructs a status code from a module and an error code. */
+#define XN_STATUS_MAKE(group, code) ((group << 16) | code)
+
+/** Returns the group of the status. */
+#define XN_STATUS_GROUP(status) XnUInt16(status >> 16)
+
+/** Returns the code of the status. */
+#define XN_STATUS_CODE(status) XnUInt16(status & 0x0000FFFF)
+
+/** Marks the beginning of a message map of a specific module. */
+#define XN_STATUS_MESSAGE_MAP_START_FROM(group, first) \
+ enum _##group##first##Errors \
+ { \
+ group##first##_OK = XN_STATUS_MAKE(group, first),
+
+#define XN_STATUS_MESSAGE_MAP_START(group) \
+ XN_STATUS_MESSAGE_MAP_START_FROM(group, 0)
+
+/** Adds an entry to the message map. */
+#define XN_STATUS_MESSAGE(csName, csMessage) \
+ csName,
+
+/** Marks the end of a message map. */
+#define XN_STATUS_MESSAGE_MAP_END_FROM(group, first) \
+ };
+
+#define XN_STATUS_MESSAGE_MAP_END(group) \
+ XN_STATUS_MESSAGE_MAP_END_FROM(group, 0)
+
+#endif // __XN_OPEN_NITE_STATUS_H__
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnStatusCodes.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnStatusCodes.h
new file mode 100644
index 00000000..77337142
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnStatusCodes.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef __XN_STATUS_CODES_H__
+#define __XN_STATUS_CODES_H__
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include "XnStatus.h"
+
+//---------------------------------------------------------------------------
+// Status Messages
+//---------------------------------------------------------------------------
+XN_STATUS_MESSAGE_MAP_START(XN_ERROR_GROUP_NI)
+XN_STATUS_MESSAGE(XN_STATUS_ERROR, "Error!")
+XN_STATUS_MESSAGE(XN_STATUS_NOT_INIT, "Module was not initialized!")
+XN_STATUS_MESSAGE(XN_STATUS_ALREADY_INIT, "Module was already initialized!")
+XN_STATUS_MESSAGE(XN_STATUS_NULL_INPUT_PTR, "Input pointer is null!")
+XN_STATUS_MESSAGE(XN_STATUS_NULL_OUTPUT_PTR, "Output pointer is null!")
+XN_STATUS_MESSAGE(XN_STATUS_INPUT_BUFFER_OVERFLOW, "Input buffer overflow!")
+XN_STATUS_MESSAGE(XN_STATUS_OUTPUT_BUFFER_OVERFLOW, "Output buffer overflow!")
+XN_STATUS_MESSAGE(XN_STATUS_INTERNAL_BUFFER_TOO_SMALL, "Internal buffer is too small!")
+XN_STATUS_MESSAGE(XN_STATUS_INVALID_BUFFER_SIZE, "The buffer is of wrong size!")
+XN_STATUS_MESSAGE(XN_STATUS_NO_MATCH, "No match found")
+XN_STATUS_MESSAGE(XN_STATUS_IS_EMPTY, "No items in data structure")
+XN_STATUS_MESSAGE(XN_STATUS_IS_NOT_EMPTY, "Items in data structure")
+XN_STATUS_MESSAGE(XN_STATUS_ILLEGAL_POSITION, "Can't perform operation at this position in the data structure")
+XN_STATUS_MESSAGE(XN_STATUS_NOT_IMPLEMENTED, "Function was not implemented!")
+XN_STATUS_MESSAGE(XN_STATUS_NO_MODULES_FOUND, "OpenNI library can't find any module!")
+XN_STATUS_MESSAGE(XN_STATUS_INVALID_GENERATOR, "Module generator is not valid!")
+XN_STATUS_MESSAGE(XN_STATUS_UNKNOWN_GENERATOR_TYPE, "Generator type is unknown!")
+XN_STATUS_MESSAGE(XN_STATUS_INVALID_OPERATION, "This operation is invalid!")
+XN_STATUS_MESSAGE(XN_STATUS_MISSING_NEEDED_TREE, "A needed production node is missing!")
+XN_STATUS_MESSAGE(XN_STATUS_CORRUPT_FILE, "The file is corrupted!")
+XN_STATUS_MESSAGE(XN_STATUS_BAD_PARAM, "The value is invalid!")
+XN_STATUS_MESSAGE(XN_STATUS_NODE_IS_LOCKED, "The node is locked for changes!")
+XN_STATUS_MESSAGE(XN_STATUS_WAIT_DATA_TIMEOUT, "A timeout has occurred when waiting for new data!")
+XN_STATUS_MESSAGE(XN_STATUS_BAD_TYPE, "The operation requires an object of a different type!")
+XN_STATUS_MESSAGE(XN_STATUS_UNSUPPORTED_VERSION, "Unsupported version")
+XN_STATUS_MESSAGE(XN_STATUS_PROPERTY_NOT_SET, "The property is not set")
+XN_STATUS_MESSAGE(XN_STATUS_BAD_FILE_EXT, "Bad file extension")
+XN_STATUS_MESSAGE(XN_STATUS_NODE_NOT_LOADED, "No node with the requested description is loaded")
+XN_STATUS_MESSAGE(XN_STATUS_NO_NODE_PRESENT, "Can't create any node of the requested type!")
+XN_STATUS_MESSAGE(XN_STATUS_BAD_NODE_NAME, "No node by the specified name exists")
+XN_STATUS_MESSAGE(XN_STATUS_UNSUPPORTED_CODEC, "Failed to find a matching codec")
+XN_STATUS_MESSAGE(XN_STATUS_EOF, "End of file reached")
+XN_STATUS_MESSAGE(XN_STATUS_MULTIPLE_NODES_ERROR, "More than one node is in error state!")
+XN_STATUS_MESSAGE(XN_STATUS_DEVICE_NOT_CONNECTED, "The device is not connected!")
+XN_STATUS_MESSAGE(XN_STATUS_NO_LICENSE, "No license to use this module!")
+XN_STATUS_MESSAGE(XN_STATUS_NO_SUCH_PROPERTY, "There is no such property")
+XN_STATUS_MESSAGE(XN_STATUS_NODE_ALREADY_RECORDED, "This node is already recorded!")
+XN_STATUS_MESSAGE(XN_STATUS_PROTO_BAD_INTERFACE, "Bad protocol interface")
+XN_STATUS_MESSAGE(XN_STATUS_PROTO_BAD_MSG_TYPE, "Bad protocol message type")
+XN_STATUS_MESSAGE(XN_STATUS_PROTO_BAD_CID, "Bad protocol CID")
+XN_STATUS_MESSAGE(XN_STATUS_PROTO_BAD_NODE_ID, "Bad protocol node ID")
+XN_STATUS_MESSAGE(XN_STATUS_PROTO_BAD_MSG_SIZE, "Bad protocol message size")
+XN_STATUS_MESSAGE(XN_STATUS_NO_SUCH_USER, "User could not be found")
+XN_STATUS_MESSAGE(XN_STATUS_USER_IS_NOT_BEING_TRACKED, "User is not being tracked")
+XN_STATUS_MESSAGE(XN_STATUS_JOINT_IS_NOT_ACTIVE, "Joint is not active")
+XN_STATUS_MESSAGE_MAP_END(XN_ERROR_GROUP_NI)
+
+#endif // __XN_STATUS_CODES_H__
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnStatusRegister.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnStatusRegister.h
new file mode 100644
index 00000000..6c23949a
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnStatusRegister.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef __XN_STATUS_REGISTER_H__
+#define __XN_STATUS_REGISTER_H__
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include "XnStatus.h"
+
+//---------------------------------------------------------------------------
+// Structs
+//---------------------------------------------------------------------------
+typedef struct XnErrorCodeData
+{
+ /** The code of this error. */
+ XnUInt32 nCode;
+ /** The name of this error. */
+ const XnChar* csName;
+ /** A user message describing this error. */
+ const XnChar* csMessage;
+} XnErrorCodeData;
+
+//---------------------------------------------------------------------------
+// Exported Function Declaration
+//---------------------------------------------------------------------------
+/**
+* This function registers error codes to the message map.
+*
+* @param nGroup [in] The group for which these errors belong to.
+* @param nFirst [in] The first value.
+* @param nCount [in] The number of status messages to register.
+* @param pErrorCodeData [in] An array of status messages.
+*/
+XN_C_API XnStatus XN_C_DECL xnRegisterErrorCodeMessages(XnUInt16 nGroup, XnUInt16 nFirst, XnUInt16 nCount, XnErrorCodeData* pErrorCodeData);
+
+//---------------------------------------------------------------------------
+// Macros
+//---------------------------------------------------------------------------
+#undef XN_STATUS_MESSAGE_MAP_START_FROM
+#undef XN_STATUS_MESSAGE
+#undef XN_STATUS_MESSAGE_MAP_END_FROM
+
+#define _XN_ERROR_GROUP_NAME(group, first) _s_##group##first##_errors
+
+#define XN_STATUS_MESSAGE_MAP_START_FROM(group, first) \
+ static XnErrorCodeData _XN_ERROR_GROUP_NAME(group, first)[] = \
+ { \
+ { first, XN_STRINGIFY(group) "_OK", XN_STRINGIFY(group) " OK" },
+
+/** Adds an entry to the message map. */
+#define XN_STATUS_MESSAGE(csName, csMessage) \
+ { 0, XN_STRINGIFY(csName), csMessage },
+
+/** Marks the end of a message map. */
+#define XN_STATUS_MESSAGE_MAP_END_FROM(group, first) \
+ }; \
+ static XnStatus s_##group##first##_result = xnRegisterErrorCodeMessages(group, first, sizeof(_XN_ERROR_GROUP_NAME(group, first)) / sizeof(XnErrorCodeData), _XN_ERROR_GROUP_NAME(group, first));
+
+#define XN_STATUS_REGISTER
+
+#endif //__XN_STATUS_REGISTER_H__
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnStringsHash.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnStringsHash.h
new file mode 100644
index 00000000..ec875133
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnStringsHash.h
@@ -0,0 +1,118 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef _XN_STRINGS_HASH_H
+#define _XN_STRINGS_HASH_H
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include "XnHash.h"
+#include <XnOS.h>
+
+//---------------------------------------------------------------------------
+// Types
+//---------------------------------------------------------------------------
+class XnStringsKeyManager
+{
+public:
+ static XnHashValue Hash(const XnChar* const& key)
+ {
+ XnUInt32 nCRC = 0;
+ xnOSStrCRC32(key, &nCRC);
+
+ // convert from UINT32 to XnHashValue
+ return nCRC % (1 << (sizeof(XnHashValue)*8));
+ }
+
+ static XnInt32 Compare(const XnChar* const& key1, const XnChar* const& key2)
+ {
+ return strcmp(key1, key2);
+ }
+};
+
+class XnStringsKeyTranslator
+{
+public:
+ static XnValue CreateValueCopy(const XnChar* const& orig)
+ {
+ // we should copy string, so we can keep the key
+ XnUInt32 nLen = xnOSStrLen(orig) + 1; // with null termination
+ XnChar* pcKey = (XnChar*)xnOSMalloc(nLen);
+ xnOSStrCopy(pcKey, orig, nLen);
+ return (pcKey);
+ }
+
+ static void FreeValue(XnValue& Value)
+ {
+ XnChar* pcKey = (XnChar*)Value;
+ xnOSFree(pcKey);
+ }
+
+ static XnValue GetAsValue(const XnChar* const& orig)
+ {
+ return (XnValue)orig;
+ }
+
+ static const XnChar* const& GetFromValue(const XnValue& Value)
+ {
+ return (const XnChar* const&)Value;
+ }
+
+ static const XnChar*& GetFromValue(XnValue& Value)
+ {
+ return (const XnChar*&)Value;
+ }
+};
+
+/**
+* Declares a hash table from strings to @a ValueType that's named @a ClassName and uses @a ValueTranslator
+* to translate values. It is declared using the @a decl declspec.
+*/
+#define XN_DECLARE_STRINGS_HASH_WITH_TRANSLATOR_DECL(decl, ValueType, ClassName, ValueTranslator) \
+ XN_DECLARE_HASH_DECL(decl, const XnChar*, ValueType, ClassName, XnStringsKeyTranslator, ValueTranslator, XnStringsKeyManager) \
+
+/**
+* Declares a hash table from strings to @a ValueType that's named @a ClassName and uses @a ValueTranslator
+* to translate values.
+*/
+#define XN_DECLARE_STRINGS_HASH_WITH_TRANSLATOR(ValueType, ClassName, ValueTranslator) \
+ XN_DECLARE_STRINGS_HASH_WITH_TRANSLATOR_DECL(, ValueType, ClassName, ValueTranslator)
+
+/**
+* Declares a hash table from strings to @a ValueType that's named @a ClassName and uses default translator
+* to translate values. It is declared using the @a decl declspec.
+*/
+#define XN_DECLARE_STRINGS_HASH_DECL(decl, ValueType, ClassName) \
+ XN_DECLARE_DEFAULT_VALUE_TRANSLATOR_DECL(decl, ValueType, XN_DEFAULT_TRANSLATOR_NAME(ClassName)) \
+ XN_DECLARE_STRINGS_HASH_WITH_TRANSLATOR_DECL(decl, ValueType, ClassName, XN_DEFAULT_TRANSLATOR_NAME(ClassName)) \
+
+/**
+* Declares a hash table from strings to @a ValueType that's named @a ClassName and uses default translator
+* to translate values.
+*/
+#define XN_DECLARE_STRINGS_HASH(ValueType, ClassName) \
+ XN_DECLARE_STRINGS_HASH_DECL(, ValueType, ClassName)
+
+XN_DECLARE_STRINGS_HASH(XnValue, XnStringsHash)
+
+
+#endif //_XN_STRINGS_HASH_H
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnStringsHashT.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnStringsHashT.h
new file mode 100644
index 00000000..57602211
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnStringsHashT.h
@@ -0,0 +1,90 @@
+#ifndef _XN_STRINGS_HASH_T_H_
+#define _XN_STRINGS_HASH_T_H_
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include "XnHashT.h"
+
+//---------------------------------------------------------------------------
+// Code
+//---------------------------------------------------------------------------
+class XnStringsHashKeyManager
+{
+public:
+ static XnHashCode Hash(const XnChar* const& key)
+ {
+ XnUInt32 nCRC = 0;
+ xnOSStrCRC32(key, &nCRC);
+
+ // convert from UINT32 to XnHashValue
+ return nCRC % (1 << (sizeof(XnHashCode)*8));
+ }
+
+ static XnInt32 Compare(const XnChar* const& key1, const XnChar* const& key2)
+ {
+ return strcmp(key1, key2);
+ }
+};
+
+template<class TValue>
+class XnStringsNodeAllocator
+{
+public:
+ typedef XnKeyValuePair<const XnChar*, TValue> TPair;
+ typedef XnLinkedNodeT<TPair> TLinkedNode;
+
+ static TLinkedNode* Allocate(TPair const& pair)
+ {
+ XnChar* pKeyCopy = xnOSStrDup(pair.Key());
+ if (pKeyCopy == NULL)
+ {
+ return NULL;
+ }
+
+ return XN_NEW(TLinkedNode, TPair(pKeyCopy, pair.Value()));
+ }
+
+ static void Deallocate(TLinkedNode* pNode)
+ {
+ XN_ASSERT(pNode != NULL);
+ XN_ASSERT(pNode->value.Key() != NULL);
+
+ xnOSFree(pNode->value.Key());
+ XN_DELETE(pNode);
+ }
+};
+
+template<class TValue>
+class XnStringsHashT : public XnHashT<const XnChar*, TValue, XnStringsHashKeyManager, XnStringsNodeAllocator<TValue> >
+{
+ typedef XnHashT<const XnChar*, TValue, XnStringsHashKeyManager, XnStringsNodeAllocator<TValue> > Base;
+
+public:
+ XnStringsHashT() : Base() {}
+
+ XnStringsHashT(const XnStringsHashT& other) : Base()
+ {
+ *this = other;
+ }
+
+ XnStringsHashT& operator=(const XnStringsHashT& other)
+ {
+ Base::operator=(other);
+ // no other members
+ return *this;
+ }
+};
+
+class XnStringsSet : public XnStringsHashT<void*>
+{
+ typedef XnStringsHashT<void*> Base;
+
+public:
+ XnStatus Set(const XnChar* key)
+ {
+ return Base::Set(key, NULL);
+ }
+};
+
+#endif // _XN_STRINGS_HASH_T_H_ \ No newline at end of file
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnThreadSafeQueue.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnThreadSafeQueue.h
new file mode 100644
index 00000000..a9ede311
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnThreadSafeQueue.h
@@ -0,0 +1,156 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef __XN_THREAD_SAFE_QUEUE_H__
+#define __XN_THREAD_SAFE_QUEUE_H__
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include <XnQueue.h>
+#include <XnOS.h>
+
+//---------------------------------------------------------------------------
+// Types
+//---------------------------------------------------------------------------
+/**
+* A thread safe queue.
+*/
+class XnThreadSafeQueue : public XnQueue
+{
+public:
+ XnThreadSafeQueue() : m_hLock(NULL) {}
+
+ ~XnThreadSafeQueue()
+ {
+ xnOSCloseCriticalSection(&m_hLock);
+ }
+
+ XnStatus Init()
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ nRetVal = xnOSCreateCriticalSection(&m_hLock);
+ XN_IS_STATUS_OK(nRetVal);
+
+ return (XN_STATUS_OK);
+ }
+
+ XnStatus Push(XnValue const& value)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ nRetVal = xnOSEnterCriticalSection(&m_hLock);
+ XN_IS_STATUS_OK(nRetVal);
+
+ nRetVal = XnQueue::Push(value);
+ xnOSLeaveCriticalSection(&m_hLock);
+
+ return nRetVal;
+ }
+
+ XnStatus Pop(XnValue& value)
+ {
+ XnStatus nRetVal = XN_STATUS_OK;
+
+ nRetVal = xnOSEnterCriticalSection(&m_hLock);
+ XN_IS_STATUS_OK(nRetVal);
+
+ nRetVal = XnQueue::Pop(value);
+ xnOSLeaveCriticalSection(&m_hLock);
+
+ return nRetVal;
+ }
+
+ XnUInt32 Size() const
+ {
+ xnOSEnterCriticalSection(&m_hLock);
+ XnUInt32 nSize = XnQueue::Size();
+ xnOSLeaveCriticalSection(&m_hLock);
+ return (nSize);
+ }
+
+private:
+ // NOTE: we declare the lock as mutable, as it may change on const methods.
+ mutable XN_CRITICAL_SECTION_HANDLE m_hLock;
+};
+
+/**
+* Declares a thread safe queue of type @a Type, named @a ClassName. The class uses @a Translator for translating
+* from @a Type to XnValue. It is declared using the declspec @a decl.
+* It inherits from @a base. Note that @a base must be a derivative of XnQueue.
+*/
+#define XN_DECLARE_THREAD_SAFE_QUEUE_WITH_TRANSLATOR_DECL(decl, Type, ClassName, Translator) \
+ class decl ClassName : public XnThreadSafeQueue \
+ { \
+ public: \
+ ~ClassName() \
+ { \
+ /* We do this using Pop() to make sure memory is freed. */ \
+ Type dummy; \
+ while (Size() != 0) \
+ Pop(dummy); \
+ } \
+ XnStatus Push(Type const& value) \
+ { \
+ XnValue val = Translator::CreateValueCopy(value); \
+ XnStatus nRetVal = XnThreadSafeQueue::Push(val); \
+ if (nRetVal != XN_STATUS_OK) \
+ { \
+ Translator::FreeValue(val); \
+ return (nRetVal); \
+ } \
+ return XN_STATUS_OK; \
+ } \
+ XnStatus Pop(Type& value) \
+ { \
+ XnValue val; \
+ XnStatus nRetVal = XnThreadSafeQueue::Pop(val); \
+ if (nRetVal != XN_STATUS_OK) return (nRetVal); \
+ value = Translator::GetFromValue(val); \
+ Translator::FreeValue(val); \
+ return XN_STATUS_OK; \
+ } \
+ };
+
+/**
+* Declares a thread safe queue of type @a Type, named @a ClassName. The class uses @a Translator for translating
+* from @a Type to XnValue.
+* It inherits from @a base. Note that @a base must be a derivative of XnQueue.
+*/
+#define XN_DECLARE_THREAD_SAFE_QUEUE_WITH_TRANSLATOR(Type, ClassName, Translator) \
+ XN_DECLARE_THREAD_SAFE_QUEUE_WITH_TRANSLATOR_DECL(, Type, ClassName, Translator)
+
+/**
+* Declares a thread safe queue of type @a Type, named @a ClassName, that uses the default translator.
+* It is declared using the declspec @a decl.
+*/
+#define XN_DECLARE_THREAD_SAFE_QUEUE_DECL(decl, Type, ClassName) \
+ XN_DECLARE_DEFAULT_VALUE_TRANSLATOR_DECL(decl, Type, XN_DEFAULT_TRANSLATOR_NAME(ClassName)) \
+ XN_DECLARE_THREAD_SAFE_QUEUE_WITH_TRANSLATOR_DECL(decl, Type, ClassName, XN_DEFAULT_TRANSLATOR_NAME(ClassName))
+
+/**
+* Declares a thread safe queue of type @a Type, named @a ClassName, that uses the default translator.
+*/
+#define XN_DECLARE_THREAD_SAFE_QUEUE(Type, ClassName) \
+ XN_DECLARE_THREAD_SAFE_QUEUE_DECL(, Type, ClassName)
+
+#endif //__XN_THREAD_SAFE_QUEUE_H__
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnTypes.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnTypes.h
new file mode 100644
index 00000000..40eb04e6
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnTypes.h
@@ -0,0 +1,1188 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef __XN_TYPES_H__
+#define __XN_TYPES_H__
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include <XnStatus.h>
+#include <XnOS.h>
+
+//---------------------------------------------------------------------------
+// Defines
+//---------------------------------------------------------------------------
+/** The maximum length of names of objects in OpenNI **/
+#define XN_MAX_NAME_LENGTH 80
+
+/** The maximum length of a creation info string **/
+#define XN_MAX_CREATION_INFO_LENGTH 255
+
+/** The maxumim length of a license key **/
+#define XN_MAX_LICENSE_LENGTH 255
+
+/** The maximum time to wait for node new data with the xnWaitXXXUpdateXXX functions **/
+#define XN_NODE_WAIT_FOR_DATA_TIMEOUT 2000
+
+/** OpenNI vendor ID, used by nodes supplied by OpenNI itself. **/
+#define XN_VENDOR_OPEN_NI "OpenNI"
+
+/** The name of the OpenNI recording format. **/
+#define XN_FORMAT_NAME_ONI "oni"
+
+/** The name of the OpenNI XML script format. **/
+#define XN_SCRIPT_FORMAT_XML "xml"
+
+/** represents playback speed which does not consider file timestamps. **/
+#define XN_PLAYBACK_SPEED_FASTEST 0.0
+
+/** represents a value for automatic control for nodes supporting it, as part of the @ref general_int. **/
+#define XN_AUTO_CONTROL XN_MIN_INT32
+
+//---------------------------------------------------------------------------
+// Forward Declarations
+//---------------------------------------------------------------------------
+struct XnInternalNodeData;
+
+//---------------------------------------------------------------------------
+// Types
+//---------------------------------------------------------------------------
+
+#if XN_PLATFORM != XN_PLATFORM_ARC
+#pragma pack (push, 1)
+#endif
+
+/**
+ * The context of an OpenNI library.
+ */
+typedef struct XnContext XnContext;
+
+/**
+ * A handle to a production node in the OpenNI context. A value of NULL represents an invalid handle.
+ */
+typedef struct XnInternalNodeData* XnNodeHandle;
+
+/**
+ * A handle to a lock. A value of NULL represents an invalid handle.
+ */
+typedef XnUInt32 XnLockHandle;
+
+/**
+ * Type of the production node.
+ */
+typedef XnInt32 XnProductionNodeType;
+
+/**
+ * Predefined types of production nodes.
+ */
+typedef enum XnPredefinedProductionNodeType
+{
+ /** An invalid node type **/
+ XN_NODE_TYPE_INVALID = -1,
+
+ /** A device node **/
+ XN_NODE_TYPE_DEVICE = 1,
+
+ /** A depth generator **/
+ XN_NODE_TYPE_DEPTH = 2,
+
+ /** An image generator **/
+ XN_NODE_TYPE_IMAGE = 3,
+
+ /** An audio generator **/
+ XN_NODE_TYPE_AUDIO = 4,
+
+ /** An IR generator **/
+ XN_NODE_TYPE_IR = 5,
+
+ /** A user generator **/
+ XN_NODE_TYPE_USER = 6,
+
+ /** A recorder **/
+ XN_NODE_TYPE_RECORDER = 7,
+
+ /** A player **/
+ XN_NODE_TYPE_PLAYER = 8,
+
+ /** A gesture generator **/
+ XN_NODE_TYPE_GESTURE = 9,
+
+ /** A scene analyzer **/
+ XN_NODE_TYPE_SCENE = 10,
+
+ /** A hands generator **/
+ XN_NODE_TYPE_HANDS = 11,
+
+ /** A Codec **/
+ XN_NODE_TYPE_CODEC = 12,
+
+ /** Abstract types **/
+ XN_NODE_TYPE_PRODUCTION_NODE = 13,
+ XN_NODE_TYPE_GENERATOR = 14,
+ XN_NODE_TYPE_MAP_GENERATOR = 15,
+ XN_NODE_TYPE_SCRIPT = 16,
+
+ XN_NODE_TYPE_FIRST_EXTENSION,
+
+} XnPredefinedProductionNodeType;
+
+/**
+ * A Version.
+ */
+typedef struct XnVersion
+{
+ XnUInt8 nMajor;
+ XnUInt8 nMinor;
+ XnUInt16 nMaintenance;
+ XnUInt32 nBuild;
+} XnVersion;
+
+/**
+ * An exported generator description.
+ */
+typedef struct XnProductionNodeDescription
+{
+ /** Type of the production node. */
+ XnProductionNodeType Type;
+ /** Vendor name */
+ XnChar strVendor[XN_MAX_NAME_LENGTH];
+ /** Generator name. Should be unique under Type and Vendor. */
+ XnChar strName[XN_MAX_NAME_LENGTH];
+ /** Current version */
+ XnVersion Version;
+} XnProductionNodeDescription;
+
+/**
+ * Information about a single production node.
+ */
+typedef struct XnNodeInfo XnNodeInfo;
+
+/**
+ * A single node in a node info list.
+ */
+typedef struct XnNodeInfoListNode XnNodeInfoListNode;
+
+/**
+ * A (linked) list of production node info objects.
+ */
+typedef struct XnNodeInfoList XnNodeInfoList;
+
+/**
+ * An iterator in a linked list of production node info objects.
+ */
+typedef struct XnNodeInfoListIterator
+{
+ XnNodeInfoListNode* pCurrent;
+} XnNodeInfoListIterator;
+
+typedef struct XnNodeQuery XnNodeQuery;
+
+/**
+ * A license key.
+ */
+typedef struct XnLicense
+{
+ /** Vendor name **/
+ XnChar strVendor[XN_MAX_NAME_LENGTH];
+ /** License key **/
+ XnChar strKey[XN_MAX_LICENSE_LENGTH];
+} XnLicense;
+
+/**
+ * @ingroup enum_errors
+ * An object that holds errors during an enumeration process.
+ */
+typedef struct XnEnumerationErrors XnEnumerationErrors;
+
+/**
+ * A handle to an instance of a generator.
+ **/
+typedef void* XnModuleNodeHandle;
+
+/**
+ * Prototype for state change callback function.
+ *
+ * @param hNode [in] A handle to the node that raised the event.
+ * @param pCookie [in] A user-provided cookie that was given when registering to the event.
+ **/
+typedef void (XN_CALLBACK_TYPE* XnStateChangedHandler)(XnNodeHandle hNode, void* pCookie);
+
+/**
+ * Prototype for error state change callback function.
+ *
+ * @param errorState [in] The new error state. A value of XN_STATUS_OK means there is no longer an error.
+ * @param pCookie [in] A user-provided cookie that was given when registering to the event.
+ **/
+typedef void (XN_CALLBACK_TYPE* XnErrorStateChangedHandler)(XnStatus errorState, void* pCookie);
+
+/**
+ * Prototype for freeing data callbacks.
+ *
+ * @param pData [in] The data to be freed.
+ **/
+typedef void (XN_CALLBACK_TYPE* XnFreeHandler)(const void* pData);
+
+typedef void (XN_CALLBACK_TYPE* XnContextShuttingDownHandler)(XnContext* pContext, void* pCookie);
+
+/**
+* Prototype for the 'Node Creation' event handler.
+*
+* @param [in] pContext The context raising the event.
+* @param [in] hCreatedNode A handle to the newly created node.
+* @param [in] pCookie A user-provided cookie that was given when registering to the event.
+*
+* @remark The passed handle (@c hCreatedNode) is not referenced. If your handler keeps this handle for later use,
+* it must call @ref xnProductionNodeAddRef().
+*/
+typedef void (XN_CALLBACK_TYPE* XnNodeCreationHandler)(XnContext* pContext, XnNodeHandle hCreatedNode, void* pCookie);
+
+/**
+* Prototype for the 'Node Destruction' event handler.
+*
+* @param [in] pContext The context raising the event.
+* @param [in] strDestroyedNodeName The name of the destroyed node.
+* @param [in] pCookie A user-provided cookie that was given when registering to the event.
+*/
+typedef void (XN_CALLBACK_TYPE* XnNodeDestructionHandler)(XnContext* pContext, const XnChar* strDestroyedNodeName, void* pCookie);
+
+/** Handle to a registered callback function. **/
+typedef void* XnCallbackHandle;
+
+typedef struct XnModuleExportedProductionNodeInterface XnModuleExportedProductionNodeInterface; // Forward Declaration
+
+//---------------------------------------------------------------------------
+// 3D Vision Types
+//---------------------------------------------------------------------------
+/** Defines the depth values type (16-bit values). **/
+typedef XnUInt16 XnDepthPixel;
+
+/** Defines the value of a no-sample depth pixel. */
+#define XN_DEPTH_NO_SAMPLE_VALUE ((XnDepthPixel)0)
+
+/** Defines the image RGB24 pixel type. **/
+typedef struct XnRGB24Pixel
+{
+ XnUInt8 nRed;
+ XnUInt8 nGreen;
+ XnUInt8 nBlue;
+} XnRGB24Pixel;
+
+/** Defines the image YUV422 double-pixel type. **/
+typedef struct XnYUV422DoublePixel
+{
+ XnUInt8 nU;
+ XnUInt8 nY1;
+ XnUInt8 nV;
+ XnUInt8 nY2;
+} XnYUV422DoublePixel;
+
+/** Defines the image Grayscale8 pixel type. **/
+typedef XnUInt8 XnGrayscale8Pixel;
+
+/** Defines the image Grayscale16 pixel type. **/
+typedef XnUInt16 XnGrayscale16Pixel;
+
+/** Defines the IR values type (16-bit grayscale). **/
+typedef XnGrayscale16Pixel XnIRPixel;
+
+/** Defines the label type */
+typedef XnUInt16 XnLabel;
+
+//---------------------------------------------------------------------------
+// Generators Capabilities
+//---------------------------------------------------------------------------
+#define XN_CAPABILITY_EXTENDED_SERIALIZATION "ExtendedSerialization"
+#define XN_CAPABILITY_MIRROR "Mirror"
+#define XN_CAPABILITY_ALTERNATIVE_VIEW_POINT "AlternativeViewPoint"
+#define XN_CAPABILITY_CROPPING "Cropping"
+#define XN_CAPABILITY_USER_POSITION "UserPosition"
+#define XN_CAPABILITY_SKELETON "User::Skeleton"
+#define XN_CAPABILITY_POSE_DETECTION "User::PoseDetection"
+#define XN_CAPABILITY_LOCK_AWARE "LockAware"
+#define XN_CAPABILITY_ERROR_STATE "ErrorState"
+#define XN_CAPABILITY_FRAME_SYNC "FrameSync"
+#define XN_CAPABILITY_DEVICE_IDENTIFICATION "DeviceIdentification"
+#define XN_CAPABILITY_BRIGHTNESS "Brightness"
+#define XN_CAPABILITY_CONTRAST "Contrast"
+#define XN_CAPABILITY_HUE "Hue"
+#define XN_CAPABILITY_SATURATION "Saturation"
+#define XN_CAPABILITY_SHARPNESS "Sharpness"
+#define XN_CAPABILITY_GAMMA "Gamma"
+#define XN_CAPABILITY_COLOR_TEMPERATURE "ColorTemperature"
+#define XN_CAPABILITY_BACKLIGHT_COMPENSATION "BacklightCompensation"
+#define XN_CAPABILITY_GAIN "Gain"
+#define XN_CAPABILITY_PAN "Pan"
+#define XN_CAPABILITY_TILT "Tilt"
+#define XN_CAPABILITY_ROLL "Roll"
+#define XN_CAPABILITY_ZOOM "Zoom"
+#define XN_CAPABILITY_EXPOSURE "Exposure"
+#define XN_CAPABILITY_IRIS "Iris"
+#define XN_CAPABILITY_FOCUS "Focus"
+#define XN_CAPABILITY_LOW_LIGHT_COMPENSATION "LowLightCompensation"
+#define XN_CAPABILITY_ANTI_FLICKER "AntiFlicker"
+#define XN_CAPABILITY_HAND_TOUCHING_FOV_EDGE "Hands::HandTouchingFOVEdge"
+
+// Backwards compatibility - typo was fixed
+#define XN_CAPABILITY_ANTI_FILCKER XN_CAPABILITY_ANTI_FLICKER
+
+// deprecated pragma is only supported in Visual Studio
+#if (XN_PLATFORM == XN_PLATFORM_WIN32)
+#pragma deprecated("XN_CAPABILITY_ANTI_FILCKER")
+#endif
+
+//---------------------------------------------------------------------------
+// Generators API Structs
+//---------------------------------------------------------------------------
+
+#define XN_QQVGA_X_RES 160
+#define XN_QQVGA_Y_RES 120
+
+#define XN_CGA_X_RES 320
+#define XN_CGA_Y_RES 200
+
+#define XN_QVGA_X_RES 320
+#define XN_QVGA_Y_RES 240
+
+#define XN_VGA_X_RES 640
+#define XN_VGA_Y_RES 480
+
+#define XN_SVGA_X_RES 800
+#define XN_SVGA_Y_RES 600
+
+#define XN_XGA_X_RES 1024
+#define XN_XGA_Y_RES 768
+
+#define XN_720P_X_RES 1280
+#define XN_720P_Y_RES 720
+
+#define XN_SXGA_X_RES 1280
+#define XN_SXGA_Y_RES 1024
+
+#define XN_UXGA_X_RES 1600
+#define XN_UXGA_Y_RES 1200
+
+#define XN_1080P_X_RES 1920
+#define XN_1080P_Y_RES 1080
+
+#define XN_QCIF_X_RES 176
+#define XN_QCIF_Y_RES 144
+
+#define XN_240P_X_RES 423
+#define XN_240P_Y_RES 240
+
+#define XN_CIF_X_RES 352
+#define XN_CIF_Y_RES 288
+
+#define XN_WVGA_X_RES 640
+#define XN_WVGA_Y_RES 360
+
+#define XN_480P_X_RES 864
+#define XN_480P_Y_RES 480
+
+#define XN_576P_X_RES 1024
+#define XN_576P_Y_RES 576
+
+#define XN_DV_X_RES 960
+#define XN_DV_Y_RES 720
+
+typedef enum XnResolution
+{
+ XN_RES_CUSTOM = 0,
+ XN_RES_QQVGA = 1,
+ XN_RES_CGA = 2,
+ XN_RES_QVGA = 3,
+ XN_RES_VGA = 4,
+ XN_RES_SVGA = 5,
+ XN_RES_XGA = 6,
+ XN_RES_720P = 7,
+ XN_RES_SXGA = 8,
+ XN_RES_UXGA = 9,
+ XN_RES_1080P = 10,
+ XN_RES_QCIF = 11,
+ XN_RES_240P = 12,
+ XN_RES_CIF = 13,
+ XN_RES_WVGA = 14,
+ XN_RES_480P = 15,
+ XN_RES_576P = 16,
+ XN_RES_DV = 17,
+} XnResolution;
+
+/**
+ * The output mode of a map generator.
+ */
+typedef struct XnMapOutputMode
+{
+ /** Number of elements in the X-axis. */
+ XnUInt32 nXRes;
+ /** Number of elements in the Y-axis. */
+ XnUInt32 nYRes;
+ /** Number of frames per second. */
+ XnUInt32 nFPS;
+} XnMapOutputMode;
+
+typedef enum XnSampleRate
+{
+ XN_SAMPLE_RATE_8K = 8000,
+ XN_SAMPLE_RATE_11K = 11025,
+ XN_SAMPLE_RATE_12K = 12000,
+ XN_SAMPLE_RATE_16K = 16000,
+ XN_SAMPLE_RATE_22K = 22050,
+ XN_SAMPLE_RATE_24K = 24000,
+ XN_SAMPLE_RATE_32K = 32000,
+ XN_SAMPLE_RATE_44K = 44100,
+ XN_SAMPLE_RATE_48K = 48000,
+} XnSampleRate;
+
+typedef struct XnWaveOutputMode
+{
+ XnUInt32 nSampleRate;
+ XnUInt16 nBitsPerSample;
+ XnUInt8 nChannels;
+} XnWaveOutputMode;
+
+/**
+ * Representation of a vector in 3D space
+ */
+typedef struct XnVector3D
+{
+ XnFloat X;
+ XnFloat Y;
+ XnFloat Z;
+} XnVector3D;
+
+typedef XnVector3D XnPoint3D;
+
+/**
+ * Representation of an axis-aligned box in 3D space
+ */
+typedef struct XnBoundingBox3D
+{
+ XnPoint3D LeftBottomNear;
+ XnPoint3D RightTopFar;
+} XnBoundingBox3D;
+
+/**
+ * Cropping configuration
+ */
+typedef struct XnCropping
+{
+ /** TRUE if cropping is turned on, FALSE otherwise. */
+ XnBool bEnabled;
+ /** Offset in the X-axis, in pixels. */
+ XnUInt16 nXOffset;
+ /** Offset in the Y-axis, in pixels. */
+ XnUInt16 nYOffset;
+ /** Number of pixels in the X-axis. */
+ XnUInt16 nXSize;
+ /** Number of pixels in the Y-axis. */
+ XnUInt16 nYSize;
+} XnCropping;
+
+/**
+ * Field-Of-View
+ */
+typedef struct XnFieldOfView
+{
+ /** Horizontal Field Of View, in radians. */
+ XnDouble fHFOV;
+ /** Vertical Field Of View, in radians. */
+ XnDouble fVFOV;
+} XnFieldOfView;
+
+typedef enum XnPixelFormat
+{
+ XN_PIXEL_FORMAT_RGB24 = 1,
+ XN_PIXEL_FORMAT_YUV422 = 2,
+ XN_PIXEL_FORMAT_GRAYSCALE_8_BIT = 3,
+ XN_PIXEL_FORMAT_GRAYSCALE_16_BIT = 4,
+ XN_PIXEL_FORMAT_MJPEG = 5,
+} XnPixelFormat;
+
+typedef struct XnSupportedPixelFormats
+{
+ XnBool m_bRGB24 : 1;
+ XnBool m_bYUV422 : 1;
+ XnBool m_bGrayscale8Bit : 1;
+ XnBool m_bGrayscale16Bit : 1;
+ XnBool m_bMJPEG : 1;
+ XnUInt m_nPadding : 3;
+ XnUInt m_nReserved : 24;
+} XnSupportedPixelFormats;
+
+typedef enum XnPlayerSeekOrigin
+{
+ XN_PLAYER_SEEK_SET = 0,
+ XN_PLAYER_SEEK_CUR = 1,
+ XN_PLAYER_SEEK_END = 2,
+} XnPlayerSeekOrigin;
+
+typedef enum XnPowerLineFrequency
+{
+ XN_POWER_LINE_FREQUENCY_OFF = 0,
+ XN_POWER_LINE_FREQUENCY_50_HZ = 50,
+ XN_POWER_LINE_FREQUENCY_60_HZ = 60,
+} XnPowerLineFrequency;
+
+// User
+typedef XnUInt32 XnUserID;
+typedef XnFloat XnConfidence;
+
+/** A 3x3 matrix of floating point values **/
+typedef struct XnMatrix3X3
+{
+ /** The elements of the matrix. **/
+ XnFloat elements[9];
+} XnMatrix3X3;
+
+/**
+* A representation of a 3D plane.
+* A plane is described by a point on it and a normal
+*/
+typedef struct XnPlane3D
+{
+ /** The normal of the plane. **/
+ XnVector3D vNormal;
+
+ /** A point on the plane. **/
+ XnPoint3D ptPoint;
+} XnPlane3D;
+
+/**
+* Position of a specific joint. A joint position is described by its actual position
+* and the confidence we have in that position.
+*/
+typedef struct XnSkeletonJointPosition
+{
+ /** The actual position in real world coordinations */
+ XnVector3D position;
+
+ /** The confidence in the position */
+ XnConfidence fConfidence;
+} XnSkeletonJointPosition;
+
+/**
+ * Orientation of a specific joint. A joint orientation is described by its actual rotation
+ * and the confidence we have in that rotation
+ * The first column is the X orientation, where the value increases from left to right.
+ * The second column is the Y orientation, where the value increases from bottom to top.
+ * The third column is the Z orientation, where the value increases from near to far.
+ */
+typedef struct XnSkeletonJointOrientation
+{
+ /** The actual orientation */
+ XnMatrix3X3 orientation;
+ /** The confidence in the orientation */
+ XnConfidence fConfidence;
+} XnSkeletonJointOrientation;
+
+/**
+* Transformation of a specific joint is its full description: both its position and orientation.
+*/
+typedef struct XnSkeletonJointTransformation
+{
+ /** The position of the joint */
+ XnSkeletonJointPosition position;
+ /** The orientation of the joint */
+ XnSkeletonJointOrientation orientation;
+} XnSkeletonJointTransformation;
+
+/**
+* A full list of available joints.
+*/
+typedef enum XnSkeletonJoint
+{
+ XN_SKEL_HEAD = 1,
+ XN_SKEL_NECK = 2,
+ XN_SKEL_TORSO = 3,
+ XN_SKEL_WAIST = 4,
+
+ XN_SKEL_LEFT_COLLAR = 5,
+ XN_SKEL_LEFT_SHOULDER = 6,
+ XN_SKEL_LEFT_ELBOW = 7,
+ XN_SKEL_LEFT_WRIST = 8,
+ XN_SKEL_LEFT_HAND = 9,
+ XN_SKEL_LEFT_FINGERTIP =10,
+
+ XN_SKEL_RIGHT_COLLAR =11,
+ XN_SKEL_RIGHT_SHOULDER =12,
+ XN_SKEL_RIGHT_ELBOW =13,
+ XN_SKEL_RIGHT_WRIST =14,
+ XN_SKEL_RIGHT_HAND =15,
+ XN_SKEL_RIGHT_FINGERTIP =16,
+
+ XN_SKEL_LEFT_HIP =17,
+ XN_SKEL_LEFT_KNEE =18,
+ XN_SKEL_LEFT_ANKLE =19,
+ XN_SKEL_LEFT_FOOT =20,
+
+ XN_SKEL_RIGHT_HIP =21,
+ XN_SKEL_RIGHT_KNEE =22,
+ XN_SKEL_RIGHT_ANKLE =23,
+ XN_SKEL_RIGHT_FOOT =24
+} XnSkeletonJoint;
+
+/** A configuration of joints to be used by skeleton (see @ref xnSetSkeletonProfile) **/
+typedef enum XnSkeletonProfile
+{
+ /** No joints at all **/
+ XN_SKEL_PROFILE_NONE = 1,
+
+ /** All joints **/
+ XN_SKEL_PROFILE_ALL = 2,
+
+ /** All the joints in the upper body (torso and upwards) **/
+ XN_SKEL_PROFILE_UPPER = 3,
+
+ /** All the joints in the lower body (torso and downwards) **/
+ XN_SKEL_PROFILE_LOWER = 4,
+
+ /** The head and the hands **/
+ XN_SKEL_PROFILE_HEAD_HANDS = 5,
+} XnSkeletonProfile;
+
+/** Possible statuses for pose detection */
+typedef enum XnPoseDetectionStatus
+{
+ XN_POSE_DETECTION_STATUS_OK = 0,
+ XN_POSE_DETECTION_STATUS_NO_USER = 1,
+ XN_POSE_DETECTION_STATUS_TOP_FOV = 2,
+ XN_POSE_DETECTION_STATUS_SIDE_FOV = 3,
+ XN_POSE_DETECTION_STATUS_ERROR = 4,
+ XN_POSE_DETECTION_STATUS_NO_TRACKING = 5
+} XnPoseDetectionStatus;
+
+
+/** Possible pose detection states */
+typedef enum XnPoseDetectionState
+{
+ XN_POSE_DETECTION_STATE_IN_POSE =0,
+ XN_POSE_DETECTION_STATE_OUT_OF_POSE =1,
+ XN_POSE_DETECTION_STATE_UNDEFINED =2
+} XnPoseDetectionState;
+/** Possible statuses for calibration */
+typedef enum XnCalibrationStatus
+{
+ XN_CALIBRATION_STATUS_OK = 0,
+ XN_CALIBRATION_STATUS_NO_USER = 1,
+ XN_CALIBRATION_STATUS_ARM = 2,
+ XN_CALIBRATION_STATUS_LEG = 3,
+ XN_CALIBRATION_STATUS_HEAD = 4,
+ XN_CALIBRATION_STATUS_TORSO = 5,
+ XN_CALIBRATION_STATUS_TOP_FOV = 6,
+ XN_CALIBRATION_STATUS_SIDE_FOV = 7,
+ XN_CALIBRATION_STATUS_POSE = 8,
+ XN_CALIBRATION_STATUS_MANUAL_ABORT = 9,
+ XN_CALIBRATION_STATUS_MANUAL_RESET = 10,
+ XN_CALIBRATION_STATUS_TIMEOUT_FAIL = 11
+} XnCalibrationStatus;
+
+typedef enum XnDirection
+{
+ XN_DIRECTION_ILLEGAL = 0,
+ XN_DIRECTION_LEFT = 1,
+ XN_DIRECTION_RIGHT = 2,
+ XN_DIRECTION_UP = 3,
+ XN_DIRECTION_DOWN = 4,
+ XN_DIRECTION_FORWARD = 5,
+ XN_DIRECTION_BACKWARD = 6,
+} XnDirection;
+
+// User
+/**
+ * Callback for a general user-related event. It is used for either creation or destruction of users.
+ *
+ * @param hNode [in] A handle to the user generator that raised this event.
+ * @param user [in] The id of the user that is relevant to this event.
+ * @param pCookie [in] A user-provided cookie that was given when registering to this event.
+ */
+typedef void (XN_CALLBACK_TYPE* XnUserHandler)(XnNodeHandle hNode, XnUserID user, void* pCookie);
+
+// Hands
+/**
+ * Callback for the creation of a new hand.
+ *
+ * @param hNode [in] A handle to the hands generator that raised this event.
+ * @param user [in] The id of the new hand.
+ * @param pPosition [in] The position in which the hand was created.
+ * @param fTime [in] Timestamp, in seconds.
+ * @param pCookie [in] A user-provided cookie that was given when registering to this event.
+ */
+typedef void (XN_CALLBACK_TYPE* XnHandCreate)(XnNodeHandle hNode, XnUserID user, const XnPoint3D* pPosition, XnFloat fTime, void* pCookie);
+
+/**
+ * Callback for a new position of an already-existing hand.
+ *
+ * @param hNode [in] A handle to the hands generator that raised this event.
+ * @param user [in] The id of the hand that moved.
+ * @param pPosition [in] The new position of the relevant hand.
+ * @param fTime [in] Timestamp, in seconds.
+ * @param pCookie [in] A user-provided cookie that was given when registering to this event.
+ */
+typedef void (XN_CALLBACK_TYPE* XnHandUpdate)(XnNodeHandle hNode, XnUserID user, const XnPoint3D* pPosition, XnFloat fTime, void* pCookie);
+
+/**
+ * Callback for the disappearance of a hand.
+ *
+ * @param hNode [in] A handle to the hands generator that raised this event.
+ * @param user [in] The id of the hand that disappeared.
+ * @param fTime [in] Timestamp, in seconds.
+ * @param pCookie [in] A user-provided cookie that was given when registering to this event.
+ */
+typedef void (XN_CALLBACK_TYPE* XnHandDestroy)(XnNodeHandle hNode, XnUserID user, XnFloat fTime, void* pCookie);
+
+/**
+ * Callback for when a hand reaches the edge of the FOV
+ *
+ * @param hNode [in] A handle to the hand generator that raised this event.
+ * @param user [in] The id of the hand that reached FOV
+ * @param pPosition [in] The current position of the hand
+ * @param fTime [in] Timestamp, in seconds
+ * @param eDir [in] The direction of the edge that is being reached
+ * @param pCookie [in] A user-provided cookie that was given when reigstering to this event
+ */
+typedef void (XN_CALLBACK_TYPE* XnHandTouchingFOVEdge)(XnNodeHandle hNode, XnUserID user, const XnPoint3D* pPosition, XnFloat fTime, XnDirection eDir, void* pCookie);
+// Gesture Module
+/**
+ * Callback for the recognition of a gesture
+ *
+ * @param hNode [in] A handle to the gesture generator that raised this event.
+ * @param strGesture [in] The gesture that was recognized.
+ * @param pIDPosition [in] The position in which the gesture was identified.
+ * @param pEndPosition [in] The position of the hand that performed the gesture at the end of the gesture.
+ * @param pCookie [in] A user-provided cookie that was given when registering to this event.
+ */
+typedef void (XN_CALLBACK_TYPE* XnGestureRecognized)(XnNodeHandle hNode, const XnChar* strGesture, const XnPoint3D* pIDPosition, const XnPoint3D* pEndPosition, void* pCookie);
+/**
+ * Callback for indication that a certain gesture is in progress
+ *
+ * @param hNode [in] A handle to the gesture generator that raised this event.
+ * @param strGesture [in] The gesture that is on its way to being recognized.
+ * @param pPosition [in] The current position of the hand that is performing the gesture.
+ * @param fProgress [in] The percentage of the gesture that was already performed.
+ * @param pCookie [in] A user-provided cookie that was given when registering to this event.
+ */
+typedef void (XN_CALLBACK_TYPE* XnGestureProgress)(XnNodeHandle hNode, const XnChar* strGesture, const XnPoint3D* pPosition, XnFloat fProgress, void* pCookie);
+
+typedef void (XN_CALLBACK_TYPE* XnGestureIntermediateStageCompleted)(XnNodeHandle hNode, const XnChar* strGesture, const XnPoint3D* pPosition, void* pCookie);
+typedef void (XN_CALLBACK_TYPE* XnGestureReadyForNextIntermediateStage)(XnNodeHandle hNode, const XnChar* strGesture, const XnPoint3D* pPosition, void* pCookie);
+
+// Skeleton
+/**
+ * Callback for indication that a specific user's skeleton is now starting the calibration process
+ *
+ * @param hNode [in] A handle to the skeleton capability that raised this event.
+ * @param user [in] The id of the user that's being calibrated.
+ * @param pCookie [in] A user-provided cookie that was given when registering to this event.
+ */
+typedef void (XN_CALLBACK_TYPE* XnCalibrationStart)(XnNodeHandle hNode, XnUserID user, void* pCookie);
+/**
+ * Callback for indication that a specific user's skeleton has now completed the calibration process
+ *
+ * @param hNode [in] A handle to the skeleton capability that raised this event.
+ * @param user [in] The id of the user for which calibration was attempted.
+ * @param bSuccess [in] An indication of whether or not the calibration attempt succeeded.
+ * @param pCookie [in] A user-provided cookie that was given when registering to this event.
+ */
+typedef void (XN_CALLBACK_TYPE* XnCalibrationEnd)(XnNodeHandle hNode, XnUserID user, XnBool bSuccess, void* pCookie);
+
+typedef void (XN_CALLBACK_TYPE* XnCalibrationInProgress)(XnNodeHandle hNode, XnUserID user, XnCalibrationStatus calibrationError, void* pCookie);
+typedef void (XN_CALLBACK_TYPE* XnCalibrationComplete)(XnNodeHandle hNode, XnUserID user, XnCalibrationStatus calibrationError, void* pCookie);
+
+// Pose Detection
+/**
+ * Callback for indication that a specific user has entered a pose, or left it.
+ *
+ * @param hNode [in] A handle to the pose capability that raised this event.
+ * @param strPose [in] The pose that is relevant to the callback.
+ * @param user [in] The id of the user that entered the pose or left it.
+ * @param pCookie [in] A user-provided cookie that was given when registering to this event.
+ */
+typedef void (XN_CALLBACK_TYPE* XnPoseDetectionCallback)(XnNodeHandle hNode, const XnChar* strPose, XnUserID user, void* pCookie);
+
+typedef void (XN_CALLBACK_TYPE* XnPoseDetectionInProgress)(XnNodeHandle hNode, const XnChar* strPose, XnUserID user, XnPoseDetectionStatus poseDetectionError, void* pCookie);
+
+//---------------------------------------------------------------------------
+// Recorder Types
+//---------------------------------------------------------------------------
+
+/**
+ * @ingroup recorder
+ */
+
+/** Defines the type of medium used for recording. See @ref xnAddNodeToRecording. */
+typedef enum XnRecordMedium
+{
+ /** Recording medium is a file **/
+ XN_RECORD_MEDIUM_FILE = 0,
+} XnRecordMedium;
+
+/** An ID of a codec. See @ref xnCreateCodec. **/
+typedef XnUInt32 XnCodecID;
+
+/** Define a Codec ID by 4 characters, e.g. XN_CODEC_ID('J','P','E','G') **/
+#define XN_CODEC_ID(c1, c2, c3, c4) (XnCodecID)((c4 << 24) | (c3 << 16) | (c2 << 8) | c1)
+
+/**
+ * An interface used for communication between OpenNI and a recorder module. This interface is used by a recorder
+ * module to send recorded data to OpenNI, which then knows how to store them according to one of the values of
+ * @ref XnRecordMedium.
+ **/
+typedef struct XnRecorderOutputStreamInterface
+{
+ /**
+ * Opens the stream for writing.
+ *
+ * @param pCookie [in] A token that was received with this interface.
+ */
+ XnStatus (XN_CALLBACK_TYPE* Open)(void* pCookie);
+
+ /**
+ * Writes data to the stream
+ *
+ * @param pCookie [in] A token that was received with this interface.
+ * @param strNodeName [in] Optional. Specifies the node that initiated the write action.
+ * @param pData [in] A pointer to the data to write.
+ * @param nSize [in] Number of bytes to be written.
+ */
+ XnStatus (XN_CALLBACK_TYPE* Write)(void* pCookie, const XnChar* strNodeName,
+ const void* pData, XnUInt32 nSize);
+
+ /**
+ * Sets the stream's pointer to the specified position.
+ *
+ * @param pCookie [in] A cookie that was received with this interface.
+ * @param seekType [in] Specifies how to seek - according to current position, end or beginning.
+ * @param nOffset [in] Specifies how many bytes to move
+ */
+ XnStatus (XN_CALLBACK_TYPE* Seek)(void* pCookie, XnOSSeekType seekType, const XnInt32 nOffset);
+
+ /**
+ * Tells the current position in the stream.
+ *
+ * @param pCookie [in] A cookie that was received with this interface.
+ * @param pPos [out] The position of the stream.
+ *
+ * @returns (XnUInt32)-1 on error.
+ */
+ XnUInt32 (XN_CALLBACK_TYPE* Tell)(void* pCookie);
+
+ /**
+ * Closes the stream.
+ *
+ * @param pCookie [in] A token that was received with this interface.
+ */
+ void (XN_CALLBACK_TYPE* Close)(void* pCookie);
+
+ /**
+ * Sets the stream's pointer to the specified position. (64bit version, for large files)
+ *
+ * @param pCookie [in] A cookie that was received with this interface.
+ * @param seekType [in] Specifies how to seek - according to current position, end or beginning.
+ * @param nOffset [in] Specifies how many bytes to move
+ */
+ XnStatus (XN_CALLBACK_TYPE* Seek64)(void* pCookie, XnOSSeekType seekType, const XnInt64 nOffset);
+
+ /**
+ * Tells the current position in the stream. (64bit version, for large files)
+ *
+ * @param pCookie [in] A cookie that was received with this interface.
+ * @param pPos [out] The position of the stream.
+ *
+ * @returns (XnUInt64)-1 on error.
+ */
+ XnUInt64 (XN_CALLBACK_TYPE* Tell64)(void* pCookie);
+
+} XnRecorderOutputStreamInterface;
+
+/**
+ * An interface used for communication between OpenNI and a player module. This interface is used by a player
+ * module to receive recorded data from OpenNI, which knows where to get them according to one of the values of
+ * @ref XnRecordMedium.
+ **/
+typedef struct XnPlayerInputStreamInterface
+{
+ /**
+ * Opens the stream for reading.
+ *
+ * @param pCookie [in] A cookie that was received with this interface.
+ */
+ XnStatus (XN_CALLBACK_TYPE* Open)(void* pCookie);
+
+ /**
+ * Reads data from the stream. May read less data than asked, if the stream is near its end. This is not
+ * considered an error.
+ *
+ * @param pCookie [in] A cookie that was received with this interface.
+ * @param pBuffer [out] A pointer to the buffer to read into.
+ * @param nSize [in] Number of bytes to read.
+ * @param pnBytesRead [out] Optional. Number of bytes actually read.
+ */
+ XnStatus (XN_CALLBACK_TYPE* Read)(void* pCookie, void* pBuffer, XnUInt32 nSize, XnUInt32* pnBytesRead);
+
+ /**
+ * Sets the stream's pointer to the specified position.
+ *
+ * @param pCookie [in] A cookie that was received with this interface.
+ * @param seekType [in] Specifies how to seek - according to current position, end or beginning.
+ * @param nOffset [in] Specifies how many bytes to move
+ */
+ XnStatus (XN_CALLBACK_TYPE* Seek)(void* pCookie, XnOSSeekType seekType, const XnInt32 nOffset);
+
+ /**
+ * Tells the current stream position
+ *
+ * @param pCookie [in] A cookie that was received with this interface.
+ *
+ * @returns (XnUInt32)-1 if there was an error in the stream.
+ */
+ XnUInt32 (XN_CALLBACK_TYPE* Tell)(void* pCookie);
+
+ /**
+ * Closes the stream.
+ *
+ * @param pCookie [in] A cookie that was received with this interface.
+ */
+ void (XN_CALLBACK_TYPE* Close)(void* pCookie);
+
+ /**
+ * Sets the stream's pointer to the specified position. (64bit version, for large files)
+ *
+ * @param pCookie [in] A cookie that was received with this interface.
+ * @param seekType [in] Specifies how to seek - according to current position, end or beginning.
+ * @param nOffset [in] Specifies how many bytes to move
+ */
+ XnStatus (XN_CALLBACK_TYPE* Seek64)(void* pCookie, XnOSSeekType seekType, const XnInt64 nOffset);
+
+ /**
+ * Tells the current position in the stream. (64bit version, for large files)
+ *
+ * @param pCookie [in] A cookie that was received with this interface.
+ * @param pPos [out] The position of the stream.
+ *
+ * @returns (XnUInt64)-1 on error.
+ */
+ XnUInt64 (XN_CALLBACK_TYPE* Tell64)(void* pCookie);
+
+} XnPlayerInputStreamInterface;
+
+/**
+ * An interface that is used for notifications about node events.
+ **/
+typedef struct XnNodeNotifications
+{
+ /**
+ * Notifies the object that a production node was added
+ *
+ * @param pCookie [in] A cookie that was received with this interface.
+ * @param strNodeName [in] The instance name of the added node.
+ */
+ XnStatus (XN_CALLBACK_TYPE* OnNodeAdded)
+ (void* pCookie, const XnChar* strNodeName, XnProductionNodeType type,
+ XnCodecID compression);
+
+ /**
+ * Notifies the object that a production node has been removed
+ *
+ * @param pCookie [in] A cookie that was received with this interface.
+ * @param strNodeName [in] The instance name of the removed node.
+ */
+ XnStatus (XN_CALLBACK_TYPE* OnNodeRemoved)
+ (void* pCookie, const XnChar* strNodeName);
+
+ /**
+ * Notifies the object that an integer type property has changed.
+ *
+ * @param pCookie [in] A cookie that was received with this interface.
+ * @param strNodeName [in] The name of the node whose property changed.
+ * @param strPropName [in] The name of the property that changed.
+ * @param nValue [in] The new value of the property.
+ */
+ XnStatus (XN_CALLBACK_TYPE* OnNodeIntPropChanged)
+ (void* pCookie, const XnChar* strNodeName,
+ const XnChar* strPropName, XnUInt64 nValue);
+
+ /**
+ * Notifies the object that a real type property has changed.
+ *
+ * @param pCookie [in] A cookie that was received with this interface.
+ * @param strNodeName [in] The name of the node whose property changed.
+ * @param strPropName [in] The name of the property that changed.
+ * @param dValue [in] The new value of the property.
+ */
+ XnStatus (XN_CALLBACK_TYPE* OnNodeRealPropChanged)
+ (void* pCookie, const XnChar* strNodeName,
+ const XnChar* strPropName, XnDouble dValue);
+
+ /**
+ * Notifies the object that a string type property has changed.
+ *
+ * @param pCookie [in] A cookie that was received with this interface.
+ * @param strNodeName [in] The name of the node whose property changed.
+ * @param strPropName [in] The name of the property that changed.
+ * @param strValue [in] The new value of the property.
+ */
+ XnStatus (XN_CALLBACK_TYPE* OnNodeStringPropChanged)
+ (void* pCookie, const XnChar* strNodeName,
+ const XnChar* strPropName, const XnChar* strValue);
+
+ /**
+ * Notifies the object that a general type property has changed.
+ *
+ * @param pCookie [in] A cookie that was received with this interface.
+ * @param strNodeName [in] The name of the node whose property changed.
+ * @param strPropName [in] The name of the property that changed.
+ * @param nBufferSize [in] The size of the buffer that holds the new value.
+ * @param pBuffer [in] The buffer that holds the new value of the property.
+ */
+ XnStatus (XN_CALLBACK_TYPE* OnNodeGeneralPropChanged)
+ (void* pCookie, const XnChar* strNodeName,
+ const XnChar* strPropName, XnUInt32 nBufferSize, const void* pBuffer);
+
+ /**
+ * Notifies the object that a node has finished sending all the initial 'property changed' notifications.
+ *
+ * @param pCookie [in] A cookie that was received with this interface.
+ * @param strNodeName [in] The name of the node whose state is ready.
+ */
+ XnStatus (XN_CALLBACK_TYPE* OnNodeStateReady)
+ (void* pCookie, const XnChar* strNodeName);
+
+ /**
+ * Notifies the object that it has received new data.
+ *
+ * @param pCookie [in] A cookie that was received with this interface.
+ * @param strNodeName [in] The name of the node whose property changed.
+ * @param strName [in] The name of the property that changed.
+ * @param nBufferSize [in] The size of the buffer that holds the new value.
+ * @param pBuffer [in] The buffer that holds the new value of the property.
+ */
+ XnStatus (XN_CALLBACK_TYPE* OnNodeNewData)
+ (void* pCookie, const XnChar* strNodeName,
+ XnUInt64 nTimeStamp, XnUInt32 nFrame, const void* pData, XnUInt32 nSize);
+
+} XnNodeNotifications;
+
+/** A pair of 32-bit unsigned values. **/
+typedef struct XnUInt32XYPair
+{
+ XnUInt32 X;
+ XnUInt32 Y;
+} XnUInt32XYPair;
+
+/** Holds information about a general frame of data. **/
+typedef struct XnOutputMetaData
+{
+ /** Represents the time in which the data was received. **/
+ XnUInt64 nTimestamp;
+
+ /** The frame ID, or frame number, of this frame. **/
+ XnUInt32 nFrameID;
+
+ /** The size of the data. **/
+ XnUInt32 nDataSize;
+
+ /** Specifies whether the generator updated this data on the last call to one of the XnWaitXXXUpdateXXX() functions. **/
+ XnBool bIsNew;
+
+} XnOutputMetaData;
+
+/** Holds information about a frame of data that has a map format. **/
+typedef struct XnMapMetaData
+{
+ /** A pointer to general information about this frame. **/
+ XnOutputMetaData* pOutput;
+
+ /** The resolution of this frame, including any cropping that was set. **/
+ XnUInt32XYPair Res;
+
+ /** The offset of the cropped region within this frame. Set to (0,0) if no cropping was done. **/
+ XnUInt32XYPair Offset;
+
+ /** The full resolution of this frame, disregarding cropping. **/
+ XnUInt32XYPair FullRes;
+
+ /** The pixel format of this frame. **/
+ XnPixelFormat PixelFormat;
+
+ /** The number of frames per second that was set when this frame was received. **/
+ XnUInt32 nFPS;
+} XnMapMetaData;
+
+/** Holds information about a frame of depth. **/
+typedef struct XnDepthMetaData
+{
+ /** A pointer to the map meta data of this frame. **/
+ XnMapMetaData* pMap;
+
+ /** A pointer to the depth data of this frame. **/
+ const XnDepthPixel* pData;
+
+ /** The value of the Z resolution of this frame - the maximum depth a pixel can have. **/
+ XnDepthPixel nZRes;
+} XnDepthMetaData;
+
+/** Holds information about an image frame. **/
+typedef struct XnImageMetaData
+{
+ /** A pointer to the map meta data of this frame **/
+ XnMapMetaData* pMap;
+
+ /** A pointer to the image data of this frame **/
+ const XnUInt8* pData;
+} XnImageMetaData;
+
+/** Holds information about an IR frame. **/
+typedef struct XnIRMetaData
+{
+ /** A pointer to the map meta data of this frame **/
+ XnMapMetaData* pMap;
+
+ /** A pointer to the IR data of this frame **/
+ const XnIRPixel* pData;
+} XnIRMetaData;
+
+typedef struct XnAudioMetaData
+{
+ /** A pointer to general information about this chunk of audio. **/
+ XnOutputMetaData* pOutput;
+
+ /** The wave output mode of this cunk of audio. **/
+ XnWaveOutputMode Wave;
+
+ /** A pointer to audio data of this cunk. **/
+ const XnUInt8* pData;
+} XnAudioMetaData;
+
+typedef struct XnSceneMetaData
+{
+ /** A pointer to the map meta data of this frame. **/
+ XnMapMetaData* pMap;
+
+ /** A pointer to the scene data of this frame. **/
+ const XnLabel* pData;
+} XnSceneMetaData;
+
+#if XN_PLATFORM != XN_PLATFORM_ARC
+#pragma pack (pop)
+#endif
+
+#endif //__XN_TYPES_H__
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnUSB.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnUSB.h
new file mode 100644
index 00000000..f7d09805
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnUSB.h
@@ -0,0 +1,128 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef _XN_USB_H_
+#define _XN_USB_H_
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include "XnOS.h"
+
+//---------------------------------------------------------------------------
+// Structures & Enums
+//---------------------------------------------------------------------------
+typedef enum {
+ XN_USB_DEVICE_LOW_SPEED = 0,
+ XN_USB_DEVICE_FULL_SPEED,
+ XN_USB_DEVICE_HIGH_SPEED,
+} XnUSBDeviceSpeed;
+
+typedef enum {
+ XN_USB_EP_BULK = 0,
+ XN_USB_EP_ISOCHRONOUS,
+ XN_USB_EP_INTERRUPT,
+} XnUSBEndPointType;
+
+typedef enum {
+ XN_USB_DIRECTION_IN = 0,
+ XN_USB_DIRECTION_OUT,
+} XnUSBDirectionType;
+
+typedef enum {
+ XN_USB_CONTROL_TYPE_STANDARD = 0,
+ XN_USB_CONTROL_TYPE_CLASS,
+ XN_USB_CONTROL_TYPE_VENDOR,
+} XnUSBControlType;
+
+typedef enum {
+ XN_USB_EVENT_DEVICE_CONNECT = 0,
+ XN_USB_EVENT_DEVICE_DISCONNECT,
+} XnUSBEventType;
+
+struct XnUSBDeviceHandle;
+struct XnUSBEndPointHandle;
+
+typedef XnChar XnUSBConnectionString[XN_FILE_MAX_PATH];
+
+typedef XnUSBDeviceHandle* XN_USB_DEV_HANDLE;
+typedef XnUSBEndPointHandle* XN_USB_EP_HANDLE;
+
+typedef XnBool (XN_CALLBACK_TYPE* XnUSBReadCallbackFunctionPtr)(XnUChar* pBuffer, XnUInt32 nBufferSize, void* pCallbackData);
+typedef XnBool (XN_CALLBACK_TYPE* XnUSBEventCallbackFunctionPtr)(XnUSBEventType USBEventType, XnChar* cpDevPath, void* pCallbackData);
+
+typedef struct XnUSBEventArgs
+{
+ const XnChar* strDevicePath;
+ XnUSBEventType eventType;
+} XnUSBEventArgs;
+
+typedef void (XN_CALLBACK_TYPE* XnUSBDeviceCallbackFunctionPtr)(XnUSBEventArgs* pArgs, void* pCookie);
+
+//---------------------------------------------------------------------------
+// Exported Function Declaration
+//---------------------------------------------------------------------------
+XN_C_API XnStatus XN_C_DECL xnUSBInit();
+XN_C_API XnStatus XN_C_DECL xnUSBShutdown();
+
+XN_C_API XnStatus XN_API_DEPRECATED("Use xnUSBEnumerateDevices() instead") XN_C_DECL xnUSBIsDevicePresent(XnUInt16 nVendorID, XnUInt16 nProductID, void* pExtraParam, XnBool* pbDevicePresent);
+
+XN_C_API XnStatus XN_C_DECL xnUSBEnumerateDevices(XnUInt16 nVendorID, XnUInt16 nProductID, const XnUSBConnectionString** pastrDevicePaths, XnUInt32* pnCount);
+XN_C_API void XN_C_DECL xnUSBFreeDevicesList(const XnUSBConnectionString* astrDevicePaths);
+
+XN_C_API XnStatus XN_API_DEPRECATED("Use xnUSBOpenDeviceByPath() instead") XN_C_DECL xnUSBOpenDevice(XnUInt16 nVendorID, XnUInt16 nProductID, void* pExtraParam, void* pExtraParam2, XN_USB_DEV_HANDLE* pDevHandlePtr);
+XN_C_API XnStatus XN_C_DECL xnUSBOpenDeviceByPath(const XnUSBConnectionString strDevicePath, XN_USB_DEV_HANDLE* pDevHandlePtr);
+XN_C_API XnStatus XN_C_DECL xnUSBCloseDevice(XN_USB_DEV_HANDLE pDevHandle);
+
+XN_C_API XnStatus XN_C_DECL xnUSBGetDeviceSpeed(XN_USB_DEV_HANDLE pDevHandle, XnUSBDeviceSpeed* pDevSpeed);
+
+XN_C_API XnStatus XN_C_DECL xnUSBSetConfig(XN_USB_DEV_HANDLE pDevHandle, XnUInt8 nConfig);
+XN_C_API XnStatus XN_C_DECL xnUSBGetConfig(XN_USB_DEV_HANDLE pDevHandle, XnUInt8* pnConfig);
+
+XN_C_API XnStatus XN_C_DECL xnUSBSetInterface(XN_USB_DEV_HANDLE pDevHandle, XnUInt8 nInterface, XnUInt8 nAltInterface);
+XN_C_API XnStatus XN_C_DECL xnUSBGetInterface(XN_USB_DEV_HANDLE pDevHandle, XnUInt8* pnInterface, XnUInt8* pnAltInterface);
+
+XN_C_API XnStatus XN_C_DECL xnUSBOpenEndPoint(XN_USB_DEV_HANDLE pDevHandle, XnUInt16 nEndPointID, XnUSBEndPointType nEPType, XnUSBDirectionType nDirType, XN_USB_EP_HANDLE* pEPHandlePtr);
+XN_C_API XnStatus XN_C_DECL xnUSBCloseEndPoint(XN_USB_EP_HANDLE pEPHandle);
+XN_C_API XnStatus XN_C_DECL xnUSBGetEndPointMaxPacketSize(XN_USB_EP_HANDLE pEPHandle, XnUInt32* pnMaxPacketSize);
+
+XN_C_API XnStatus XN_C_DECL xnUSBAbortEndPoint(XN_USB_EP_HANDLE pEPHandle);
+XN_C_API XnStatus XN_C_DECL xnUSBFlushEndPoint(XN_USB_EP_HANDLE pEPHandle);
+XN_C_API XnStatus XN_C_DECL xnUSBResetEndPoint(XN_USB_EP_HANDLE pEPHandle);
+
+XN_C_API XnStatus XN_C_DECL xnUSBSendControl(XN_USB_DEV_HANDLE pDevHandle, XnUSBControlType nType, XnUInt8 nRequest, XnUInt16 nValue, XnUInt16 nIndex, XnUChar* pBuffer, XnUInt32 nBufferSize, XnUInt32 nTimeOut);
+XN_C_API XnStatus XN_C_DECL xnUSBReceiveControl(XN_USB_DEV_HANDLE pDevHandle, XnUSBControlType nType, XnUInt8 nRequest, XnUInt16 nValue, XnUInt16 nIndex, XnUChar* pBuffer, XnUInt32 nBufferSize, XnUInt32* pnBytesReceived, XnUInt32 nTimeOut);
+
+XN_C_API XnStatus XN_C_DECL xnUSBReadEndPoint(XN_USB_EP_HANDLE pEPHandle, XnUChar* pBuffer, XnUInt32 nBufferSize, XnUInt32* pnBytesReceived, XnUInt32 nTimeOut);
+XN_C_API XnStatus XN_C_DECL xnUSBWriteEndPoint(XN_USB_EP_HANDLE pEPHandle, XnUChar* pBuffer, XnUInt32 nBufferSize, XnUInt32 nTimeOut);
+
+XN_C_API XnStatus XN_C_DECL xnUSBQueueReadEndPoint(XN_USB_EP_HANDLE pEPHandle, XnUChar* pBuffer, XnUInt32 nBufferSize, XnUInt32 nTimeOut);
+XN_C_API XnStatus XN_C_DECL xnUSBFinishReadEndPoint(XN_USB_EP_HANDLE pEPHandle, XnUInt32* pnBytesReceived, XnUInt32 nTimeOut);
+
+XN_C_API XnStatus XN_C_DECL xnUSBInitReadThread(XN_USB_EP_HANDLE pEPHandle, XnUInt32 nBufferSize, XnUInt32 nNumBuffers, XnUInt32 nTimeOut, XnUSBReadCallbackFunctionPtr pCallbackFunction, void* pCallbackData);
+XN_C_API XnStatus XN_C_DECL xnUSBShutdownReadThread(XN_USB_EP_HANDLE pEPHandle);
+
+XN_C_API XnStatus XN_API_DEPRECATED("Use xnUSBRegisterToConnectivityEvents() instead") XN_C_DECL xnUSBSetCallbackHandler(XnUInt16 nVendorID, XnUInt16 nProductID, void* pExtraParam, XnUSBEventCallbackFunctionPtr pCallbackFunction, void* pCallbackData);
+
+XN_C_API XnStatus XN_C_DECL xnUSBRegisterToConnectivityEvents(XnUInt16 nVendorID, XnUInt16 nProductID, XnUSBDeviceCallbackFunctionPtr pFunc, void* pCookie, XnRegistrationHandle* phRegistration);
+XN_C_API void XN_C_DECL xnUSBUnregisterFromConnectivityEvents(XnRegistrationHandle hRegistration);
+
+#endif //_XN_USB_H_
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnUSBDevice.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnUSBDevice.h
new file mode 100644
index 00000000..4113d248
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnUSBDevice.h
@@ -0,0 +1,117 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef _XN_USB_DEVICE_H_
+#define _XN_USB_DEVICE_H_
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include "XnPlatform.h"
+#include "XnStatus.h"
+
+#if (XN_PLATFORM == XN_PLATFORM_WIN32)
+
+ #include <Win32/usb100.h>
+ typedef USB_ENDPOINT_DESCRIPTOR XnUSBEndpointDescriptor;
+ typedef USB_INTERFACE_DESCRIPTOR XnUSBInterfaceDescriptor;
+ typedef USB_CONFIGURATION_DESCRIPTOR XnUSBConfigDescriptor;
+ typedef USB_DEVICE_DESCRIPTOR XnUSBDeviceDescriptor;
+
+ #define USB_DT_CONFIG_SIZE 0
+ #define USB_DT_CONFIG 0
+ #define USB_CONFIG_ATT_ONE 0
+ #define USB_DT_ENDPOINT_SIZE 0
+ #define USB_DT_ENDPOINT 0
+ #define USB_ENDPOINT_XFER_BULK 0
+ #define USB_DT_INTERFACE_SIZE 0
+ #define USB_DT_INTERFACE 0
+ #define USB_CLASS_VENDOR_SPEC 0
+ #define USB_DT_DEVICE_SIZE 0
+ #define USB_DT_DEVICE 0
+
+#elif (XN_PLATFORM == XN_PLATFORM_LINUX_X86 || XN_PLATFORM == XN_PLATFORM_LINUX_ARM)
+ #include <linux/usb/ch9.h>
+ typedef struct usb_endpoint_descriptor XnUSBEndpointDescriptor;
+ typedef struct usb_interface_descriptor XnUSBInterfaceDescriptor;
+ typedef struct usb_config_descriptor XnUSBConfigDescriptor;
+ typedef struct usb_device_descriptor XnUSBDeviceDescriptor;
+#else
+ #error "Unsupported Platform!"
+#endif
+
+//---------------------------------------------------------------------------
+// Structures & Enums
+//---------------------------------------------------------------------------
+typedef enum XnUSBDeviceConnectionState
+{
+ XN_USB_DEVICE_DISCONNECTED,
+ XN_USB_DEVICE_CONNECTED,
+ XN_USB_DEVICE_SUSPENDED,
+} XnUSBDeviceConnectionState;
+
+typedef struct XnUSBStringDescriptor
+{
+ XnUInt8 nID;
+ const XnChar* strString;
+} XnUSBStringDescriptor;
+
+typedef struct XnUSBInterfaceDescriptorHolder
+{
+ XnUSBInterfaceDescriptor descriptor;
+ XnUSBEndpointDescriptor** aEndpoints;
+} XnUSBInterfaceDescriptorHolder;
+
+typedef struct XnUSBConfigDescriptorHolder
+{
+ XnUSBConfigDescriptor descriptor;
+ XnUSBInterfaceDescriptorHolder** aInterfaces;
+} XnUSBConfigDescriptorHolder;
+
+typedef struct XnUSBDeviceDescriptorHolder
+{
+ XnUSBDeviceDescriptor descriptor;
+ XnUSBConfigDescriptorHolder** aConfigurations;
+ XnUSBStringDescriptor* aStrings;
+ XnUInt8 nStrings;
+} XnUSBDeviceDescriptorHolder;
+
+struct XnUSBDevice;
+typedef struct XnUSBDevice XnUSBDevice;
+
+typedef void (*XnUSBDeviceNewControlRequestCallback)(XnUSBDevice* pDevice, void* pCookie);
+typedef void (*XnUSBDeviceConnectivityChangedCallback)(XnUSBDevice* pDevice, XnUSBDeviceConnectionState state, void* pCookie);
+
+//---------------------------------------------------------------------------
+// API
+//---------------------------------------------------------------------------
+XN_C_API XnStatus XN_C_DECL xnUSBDeviceInit(const XnUSBDeviceDescriptorHolder* pDeviceDescriptor, XnUInt32 nControlMessageMaxSize, XnUSBDevice** ppDevice);
+XN_C_API void XN_C_DECL xnUSBDeviceShutdown(XnUSBDevice* pDevice);
+XN_C_API XnBool XN_C_DECL xnUSBDeviceIsControlRequestPending(XnUSBDevice* pDevice);
+
+//pnRequestSize is max size on input, actual size on output
+XN_C_API XnStatus XN_C_DECL xnUSBDeviceReceiveControlRequest(XnUSBDevice* pDevice, XnUChar* pBuffer, XnUInt32* pnRequestSize);
+XN_C_API XnStatus XN_C_DECL xnUSBDeviceSendControlReply(XnUSBDevice* pDevice, const XnUChar* pBuffer, XnUInt32 nReplySize);
+XN_C_API XnStatus XN_C_DECL xnUSBDeviceSetNewControlRequestCallback(XnUSBDevice* pDevice, XnUSBDeviceNewControlRequestCallback pFunc, void* pCookie);
+XN_C_API XnStatus XN_C_DECL xnUSBDeviceSetConnectivityChangedCallback(XnUSBDevice* pDevice, XnUSBDeviceConnectivityChangedCallback pFunc, void* pCookie);
+XN_C_API XnStatus XN_C_DECL xnUSBDeviceWriteEndpoint(XnUSBDevice* pDevice, XnUInt8 nAddress, const XnUChar* pData, XnUInt32 nDataSize);
+
+#endif
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnUtils.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnUtils.h
new file mode 100644
index 00000000..00b1222b
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnUtils.h
@@ -0,0 +1,427 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef __XN_UTILS_H__
+#define __XN_UTILS_H__
+
+/**
+ * @ingroup cref
+ * @defgroup utils Utilities
+ * This page details some utility functions.
+ * @{
+ */
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include <XnTypes.h>
+#include <XnModuleInterface.h>
+
+//---------------------------------------------------------------------------
+// Functions
+//---------------------------------------------------------------------------
+
+/**
+ * @name General
+ * @{
+ */
+
+/**
+ * Gets current OpenNI version
+ *
+ * @param pVersion [out] Current DLL version
+ */
+XN_C_API XnStatus XN_C_DECL xnGetVersion(XnVersion* pVersion);
+
+/// @}
+
+/**
+ * @name ProductionNodeType Utils
+ * @{
+ */
+
+/**
+ * Gets a string representation of the production node type.
+ *
+ * @param Type [in] The type of the production node.
+ */
+XN_C_API const XnChar* XN_C_DECL xnProductionNodeTypeToString(XnProductionNodeType Type);
+
+/**
+ * Gets a type from its string representation.
+ *
+ * @param strType [in] The string representation of the type.
+ * @param pType [out] The type of the production node.
+ */
+XN_C_API XnStatus XN_C_DECL xnProductionNodeTypeFromString(const XnChar* strType, XnProductionNodeType* pType);
+
+/**
+ * @brief Checks if a certain production node type is a generator or not
+ *
+ * @param type [in] The type to check
+ */
+XN_C_API XnBool XN_C_DECL xnIsTypeGenerator(XnProductionNodeType type);
+
+/**
+ * @brief Checks if a certain production node type is a derived of another type
+ *
+ * @param type [in] The type to check
+ * @param base [in] The base type to check against
+ */
+XN_C_API XnBool XN_C_DECL xnIsTypeDerivedFrom(XnProductionNodeType type, XnProductionNodeType base);
+
+/// @}
+
+/**
+ * @name PixelFormat Utils
+ * @{
+ */
+
+/**
+ * Get the name of the pixel format.
+ *
+ * @param format [in] Pixel Format
+ */
+XN_C_API const XnChar* XN_C_DECL xnPixelFormatToString(XnPixelFormat format);
+
+/**
+ * Gets pixel format by its name.
+ *
+ * @param strName [in] Name of the pixel format.
+ * @param pFormat [out] Pixel format.
+ */
+XN_C_API XnStatus XN_C_DECL xnPixelFormatFromString(const XnChar* strName, XnPixelFormat* pFormat);
+
+/**
+ * Gets the bytes per pixel of a pixel format.
+ *
+ * @param format [in] The pixel format.
+ */
+XN_C_API XnUInt32 XN_C_DECL xnGetBytesPerPixelForPixelFormat(XnPixelFormat format);
+
+/// @}
+
+/**
+ * @name Resolution Utilities
+ * @{
+ */
+
+/**
+ * Gets the number of pixels in a row for given resolution.
+ *
+ * @param resolution [in] The resolution to translate.
+ */
+XN_C_API XnUInt32 XN_C_DECL xnResolutionGetXRes(XnResolution resolution);
+
+/**
+ * Gets the number of pixels in a column for given resolution.
+ *
+ * @param resolution [in] The resolution to translate.
+ */
+XN_C_API XnUInt32 XN_C_DECL xnResolutionGetYRes(XnResolution resolution);
+
+/**
+ * Gets the resolution from the number of pixels in every row and column.
+ *
+ * @param xRes [in] Number of pixels in a row.
+ * @param yRes [in] Number of pixels in a column.
+ */
+XN_C_API XnResolution XN_C_DECL xnResolutionGetFromXYRes(XnUInt32 xRes, XnUInt32 yRes);
+
+/**
+ * Gets resolution by its name. If resolution is unknown, XN_RESOLUTION_CUSTOM is returned.
+ *
+ * @param strName [in] Name of the resolution.
+ */
+XN_C_API XnResolution XN_C_DECL xnResolutionGetFromName(const XnChar* strName);
+
+/**
+ * Get the name of the resolution.
+ *
+ * @param resolution [in] Resolution.
+ */
+XN_C_API const XnChar* XN_C_DECL xnResolutionGetName(XnResolution resolution);
+
+/// @}
+
+/**
+ * @name XnVersion Utilities
+ * @{
+ */
+
+/**
+ * Compares two versions.
+ *
+ * @param pVersion1 [in] First version.
+ * @param pVersion2 [in] Second version.
+ *
+ * @returns <0 if first is smaller than second, 0 if same, >0 if first is greater than second.
+ */
+XN_C_API XnInt32 XN_C_DECL xnVersionCompare(const XnVersion* pVersion1, const XnVersion* pVersion2);
+
+XN_C_API XnStatus XN_C_DECL xnVersionToString(const XnVersion* pVersion, XnChar* csResult, XnUInt32 nSize);
+
+/// @}
+
+/**
+ * @name XnProductionNodeDescription Utilities
+ * @{
+ */
+
+XN_C_API XnStatus XN_C_DECL xnProductionNodeDescriptionToString(const XnProductionNodeDescription* pDescription, XnChar* csResult, XnUInt32 nSize);
+
+/// @}
+
+/**
+ * @name C Style Constructors
+ * @{
+ */
+
+XN_C_API XnPoint3D XN_C_DECL xnCreatePoint3D(XnFloat x, XnFloat y, XnFloat z);
+XN_C_API XnPlane3D XN_C_DECL xnCreatePlane3D(XnPoint3D ptPoint, XnVector3D vNormal);
+
+/// @}
+
+/**
+ * @name Modules Registry Management
+ * @{
+ */
+
+XN_C_API XnStatus XN_C_DECL xnRegisterModule(const XnChar* strModule, const XnChar* strConfigDir);
+XN_C_API XnStatus XN_C_DECL xnUnregisterModule(const XnChar* strModule);
+XN_C_API XnStatus XN_C_DECL xnPrintRegisteredModules();
+
+/// @}
+
+/**
+ * @name Global Licenses Registry Management
+ * @{
+ */
+
+XN_C_API XnStatus XN_C_DECL xnRegisterGlobalLicense(XnLicense* pLicense);
+XN_C_API XnStatus XN_C_DECL xnUnregisterGlobalLicense(XnLicense* pLicense);
+XN_C_API XnStatus XN_C_DECL xnPrintRegisteredLicenses();
+
+/// @}
+
+/**
+ * @name MetaData Objects Management
+ * @{
+ */
+
+/**
+ * Allocates and returns an @ref XnOutputMetaData object. When no longer needed, this object should be freed
+ * by calling @ref xnFreeOutputMetaData().
+ * @returns NULL if allocation failed.
+ */
+XN_C_API XnOutputMetaData* XN_C_DECL xnAllocateOutputMetaData();
+/**
+ * Frees a previously allocated @ref XnOutputMetaData object.
+ *
+ * @param pMetaData [in] object to be freed.
+ */
+XN_C_API void XN_C_DECL xnFreeOutputMetaData(const XnOutputMetaData* pMetaData);
+/**
+ * @brief Shallow-Copies an Output Meta Data object.
+ *
+ * @param pDestination [in] Destination object.
+ * @param pSource [in] Source object.
+ */
+XN_C_API XnStatus XN_C_DECL xnCopyOutputMetaData(XnOutputMetaData* pDestination, const XnOutputMetaData* pSource);
+
+/**
+ * Allocates and returns an @ref XnMapMetaData object. When no longer needed, this object should be freed
+ * by calling @ref xnFreeMapMetaData().
+ * @returns NULL if allocation failed.
+ */
+XN_C_API XnMapMetaData* XN_C_DECL xnAllocateMapMetaData();
+/**
+ * Frees a previously allocated @ref XnMapMetaData object.
+ *
+ * @param pMetaData [in] object to be freed.
+ */
+XN_C_API void XN_C_DECL xnFreeMapMetaData(const XnMapMetaData* pMetaData);
+/**
+ * @brief Shallow-Copies a Map Meta Data object.
+ *
+ * @param pDestination [in] Destination object.
+ * @param pSource [in] Source object.
+ */
+XN_C_API XnStatus XN_C_DECL xnCopyMapMetaData(XnMapMetaData* pDestination, const XnMapMetaData* pSource);
+
+/**
+ * Allocates and returns an @ref XnDepthMetaData object. When no longer needed, this object should be freed
+ * by calling @ref xnFreeDepthMetaData().
+ * @returns NULL if allocation failed.
+ */
+XN_C_API XnDepthMetaData* XN_C_DECL xnAllocateDepthMetaData();
+/**
+ * Frees a previously allocated @ref XnDepthMetaData object.
+ *
+ * @param pMetaData [in] object to be freed.
+ */
+XN_C_API void XN_C_DECL xnFreeDepthMetaData(const XnDepthMetaData* pMetaData);
+/**
+ * @brief Shallow-Copies a Depth Meta Data object. Note that the data buffer is not copied, and that both
+ * object will point to the same buffer.
+ *
+ * @param pDestination [in] Destination object.
+ * @param pSource [in] Source object.
+ */
+XN_C_API XnStatus XN_C_DECL xnCopyDepthMetaData(XnDepthMetaData* pDestination, const XnDepthMetaData* pSource);
+
+/**
+ * Allocates and returns an @ref XnImageMetaData object. When no longer needed, this object should be freed
+ * by calling @ref xnFreeImageMetaData().
+ * @returns NULL if allocation failed.
+ */
+XN_C_API XnImageMetaData* XN_C_DECL xnAllocateImageMetaData();
+/**
+ * Frees a previously allocated @ref XnImageMetaData object.
+ *
+ * @param pMetaData [in] object to be freed.
+ */
+XN_C_API void XN_C_DECL xnFreeImageMetaData(const XnImageMetaData* pMetaData);
+/**
+ * @brief Shallow-Copies an Image Meta Data object. Note that the data buffer is not copied, and that both
+ * object will point to the same buffer.
+ *
+ * @param pDestination [in] Destination object.
+ * @param pSource [in] Source object.
+ */
+XN_C_API XnStatus XN_C_DECL xnCopyImageMetaData(XnImageMetaData* pDestination, const XnImageMetaData* pSource);
+
+/**
+ * Allocates and returns an @ref XnIRMetaData object. When no longer needed, this object should be freed
+ * by calling @ref xnFreeIRMetaData().
+ * @returns NULL if allocation failed.
+ */
+XN_C_API XnIRMetaData* XN_C_DECL xnAllocateIRMetaData();
+/**
+ * Frees a previously allocated @ref XnIRMetaData object.
+ *
+ * @param pMetaData [in] object to be freed.
+ */
+XN_C_API void XN_C_DECL xnFreeIRMetaData(const XnIRMetaData* pMetaData);
+/**
+ * @brief Shallow-Copies an IR Meta Data object. Note that the data buffer is not copied, and that both
+ * object will point to the same buffer.
+ *
+ * @param pDestination [in] Destination object.
+ * @param pSource [in] Source object.
+ */
+XN_C_API XnStatus XN_C_DECL xnCopyIRMetaData(XnIRMetaData* pDestination, const XnIRMetaData* pSource);
+
+/**
+ * Allocates and returns an @ref XnAudioMetaData object. When no longer needed, this object should be freed
+ * by calling @ref xnFreeAudioMetaData().
+ * @returns NULL if allocation failed.
+ */
+XN_C_API XnAudioMetaData* XN_C_DECL xnAllocateAudioMetaData();
+/**
+ * Frees a previously allocated @ref XnAudioMetaData object.
+ *
+ * @param pMetaData [in] object to be freed.
+ */
+XN_C_API void XN_C_DECL xnFreeAudioMetaData(const XnAudioMetaData* pMetaData);
+/**
+ * @brief Shallow-Copies an Audio Meta Data object. Note that the data buffer is not copied, and that both
+ * object will point to the same buffer.
+ *
+ * @param pDestination [in] Destination object.
+ * @param pSource [in] Source object.
+ */
+XN_C_API XnStatus XN_C_DECL xnCopyAudioMetaData(XnAudioMetaData* pDestination, const XnAudioMetaData* pSource);
+
+/**
+ * Allocates and returns an @ref XnSceneMetaData object. When no longer needed, this object should be freed
+ * by calling @ref xnFreeSceneMetaData().
+ * @returns NULL if allocation failed.
+ */
+XN_C_API XnSceneMetaData* XN_C_DECL xnAllocateSceneMetaData();
+/**
+ * Frees a previously allocated @ref XnSceneMetaData object.
+ *
+ * @param pMetaData [in] object to be freed.
+ */
+XN_C_API void XN_C_DECL xnFreeSceneMetaData(const XnSceneMetaData* pMetaData);
+/**
+ * @brief Shallow-Copies a Scene Meta Data object. Note that the data buffer is not copied, and that both
+ * object will point to the same buffer.
+ *
+ * @param pDestination [in] Destination object.
+ * @param pSource [in] Source object.
+ */
+XN_C_API XnStatus XN_C_DECL xnCopySceneMetaData(XnSceneMetaData* pDestination, const XnSceneMetaData* pSource);
+
+/// @}
+
+/**
+ * @name Functions for Modules Implementors
+ * @{
+ */
+
+/**
+ * A helper function for production nodes implementers. Enumerates needed child nodes (assuming there
+ * is only one needed input), and populates a list with production trees over that input.
+ *
+ * @param pContext [in] OpenNI Context.
+ * @param pList [in] The list to be populated.
+ * @param pDescription [in] The description of the enumerated node.
+ * @param strCreationInfo [in] [Optional] Additional creation info.
+ * @param InputType [in] The type of the input required by this production node.
+ * @param pErrors [in] The errors object passed to Enumerate method.
+ * @param pQuery [in] [Optional] A filter to be used for finding the appropriate input.
+ */
+XN_C_API XnStatus XN_C_DECL xnAutoEnumerateOverSingleInput(XnContext* pContext, XnNodeInfoList* pList, XnProductionNodeDescription* pDescription, const XnChar* strCreationInfo, XnProductionNodeType InputType, XnEnumerationErrors* pErrors, XnNodeQuery* pQuery);
+
+/**
+ * Registers an extension node with OpenNI. An extension node is a node of type not defined by OpenNI.
+ *
+ * @param strTypeName [in] Name of this new node type.
+ * @param baseType [in] Type of the direct base for this extension.
+ * @param pTypeID [out] The new ID registered with OpenNI.
+ */
+XN_C_API XnStatus XN_C_DECL xnRegisterExtensionNode(const XnChar* strTypeName, XnProductionNodeType baseType, XnProductionNodeType* pTypeID);
+
+/**
+ * Gets the module node handle of a node. This is useful for extension implementors.
+ *
+ * @param hNode [in] The node to get its module node handle.
+ */
+XN_C_API XnModuleNodeHandle XN_C_DECL xnGetModuleNodeHandle(XnNodeHandle hNode);
+
+#if !XN_PLATFORM_SUPPORTS_DYNAMIC_LIBS
+/**
+ * Registers a module to OpenNI in environments where dynamic library loading is not supported.
+ *
+ * @param pInterface [in] The module interface.
+ * @param strConfigDir [in] The module configuration directory.
+ * @param strName [in] Name of this module.
+ */
+XN_C_API XnStatus XN_C_DECL xnRegisterModuleWithOpenNI(XnOpenNIModuleInterface* pInterface, const XnChar* strConfigDir, const XnChar* strName);
+#endif
+
+/// @}
+
+/** @} */
+
+#endif // __XN_UTILS_H__
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnVersion.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnVersion.h
new file mode 100644
index 00000000..1e7f903c
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/XnVersion.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef _XN_VERSION_H_
+#define _XN_VERSION_H_
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include "XnPlatform.h"
+
+//---------------------------------------------------------------------------
+// Defines
+//---------------------------------------------------------------------------
+/** OpenNI major version. */
+#define XN_MAJOR_VERSION 1
+/** OpenNI minor version. */
+#define XN_MINOR_VERSION 5
+/** OpenNI maintenance version. */
+#define XN_MAINTENANCE_VERSION 4
+/** OpenNI build version. */
+#define XN_BUILD_VERSION 0
+
+/** OpenNI version (in brief string format): "Major.Minor.Maintenance (Build)" */
+#define XN_BRIEF_VERSION_STRING \
+ XN_STRINGIFY(XN_MAJOR_VERSION) "." \
+ XN_STRINGIFY(XN_MINOR_VERSION) "." \
+ XN_STRINGIFY(XN_MAINTENANCE_VERSION) \
+ " (Build " XN_STRINGIFY(XN_BUILD_VERSION) ")"
+
+/** OpenNI version (in numeric format): (OpenNI major version * 100000000 + OpenNI minor version * 1000000 + OpenNI maintenance version * 10000 + OpenNI build version). */
+#define XN_VERSION (XN_MAJOR_VERSION*100000000 + XN_MINOR_VERSION*1000000 + XN_MAINTENANCE_VERSION*10000 + XN_BUILD_VERSION)
+
+/** OpenNI version (in string format): "Major.Minor.Maintenance.Build-Platform (MMM DD YYYY HH:MM:SS)". */
+#define XN_VERSION_STRING \
+ XN_BRIEF_VERSION_STRING "-" \
+ XN_PLATFORM_STRING " (" XN_TIMESTAMP ")"
+
+#endif //_XN_VERSION_H_
+
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/mingw-win32/XnOSLinux-x86.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/mingw-win32/XnOSLinux-x86.h
new file mode 100644
index 00000000..0cbd12fc
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/mingw-win32/XnOSLinux-x86.h
@@ -0,0 +1,165 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef _XN_OSLINUX_X86_H_
+#define _XN_OSLINUX_X86_H_
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include <sys/types.h>
+#include <stdarg.h>
+#include <time.h>
+#include <pthread.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+//---------------------------------------------------------------------------
+// Files
+//---------------------------------------------------------------------------
+/** A generic handle type. */
+typedef void* XN_HANDLE;
+
+/** A file handle type. */
+typedef XnInt XN_FILE_HANDLE;
+
+/** The value of an invalid file handle. */
+#define XN_INVALID_FILE_HANDLE -1
+
+/** A string that specifies the current directory. */
+#define XN_FILE_LOCAL_DIR "./"
+
+/** The file directory separator. */
+#define XN_FILE_DIR_SEP "/"
+
+/** The file extension separator. */
+#define XN_FILE_EXT_SEP "."
+
+/** The file "all" wildcard. */
+#define XN_FILE_ALL_WILDCARD "*"
+
+/** The newline separation string. */
+#define XN_NEW_LINE_SEP "\n"
+
+//---------------------------------------------------------------------------
+// INI Files
+//---------------------------------------------------------------------------
+/** A string that specifies the extension of INI files. */
+#define XN_INI_FILE_EXT "ini"
+
+/** The maximum allowed INI string length (in bytes). */
+// Note: This must always be big enough to contain a 32-bit number!
+#define XN_INI_MAX_LEN 256
+
+//---------------------------------------------------------------------------
+// Shared Libraries
+//---------------------------------------------------------------------------
+/** A shared library handle type. */
+typedef void* XN_LIB_HANDLE;
+
+/** A string that specifies the prefix of shared library files. */
+#define XN_SHARED_LIBRARY_PREFIX "lib"
+
+/** A string that specifies the postfix of shared library files. */
+#define XN_SHARED_LIBRARY_POSTFIX ".so"
+
+//---------------------------------------------------------------------------
+// Threads
+//---------------------------------------------------------------------------
+/** A Xiron thread type. */
+typedef pthread_t* XN_THREAD_HANDLE;
+
+/** A Xiron thread ID. */
+typedef pthread_t XN_THREAD_ID;
+
+/** A Xiron process ID. */
+typedef pid_t XN_PROCESS_ID;
+
+/** The thread entry point function prototype. */
+typedef void* (*XN_THREAD_PROC_PROTO)(void* arg);
+
+/** The thread entry point function definition. */
+#define XN_THREAD_PROC void*
+
+/** The thread return function. */
+#define XN_THREAD_PROC_RETURN(ret) return((void*)ret)
+
+/** The thread passable data pointer type. */
+typedef void* XN_THREAD_PARAM;
+
+//---------------------------------------------------------------------------
+// Time Outs
+//---------------------------------------------------------------------------
+/** The mutex lock infinite timeout. */
+#define XN_WAIT_INFINITE 0xFFFFFFFF
+
+//---------------------------------------------------------------------------
+// Mutex
+//---------------------------------------------------------------------------
+/** A Xiron mutex type. */
+struct XnMutex;
+typedef struct XnMutex* XN_MUTEX_HANDLE;
+
+//---------------------------------------------------------------------------
+// Critical Sections
+//---------------------------------------------------------------------------
+/** A Xiron critical sections type. */
+typedef XN_MUTEX_HANDLE XN_CRITICAL_SECTION_HANDLE;
+
+//---------------------------------------------------------------------------
+// Events
+//---------------------------------------------------------------------------
+/** A Xiron event type. */
+struct _XnEvent;
+typedef struct _XnEvent _XnEvent, *XN_EVENT_HANDLE ;
+
+//---------------------------------------------------------------------------
+// Semaphores
+//---------------------------------------------------------------------------
+/** A Xiron event type. */
+struct _XnSemaphore;
+typedef struct _XnSemaphore *XN_SEMAPHORE_HANDLE;
+
+//---------------------------------------------------------------------------
+// Timer
+//---------------------------------------------------------------------------
+/** The Xiron OS timer structure. */
+typedef struct XnOSTimer
+{
+ struct timespec tStartTime;
+ XnBool bHighRes;
+} XnOSTimer;
+
+//---------------------------------------------------------------------------
+// Network
+//---------------------------------------------------------------------------
+/** The network host name and port separator. */
+#define XN_NETWORK_HOST_PORT_SEP ":"
+
+//---------------------------------------------------------------------------
+// Swaps
+//---------------------------------------------------------------------------
+#define XN_PREPARE_VAR16_IN_BUFFER(var) (var)
+#define XN_PREPARE_VAR32_IN_BUFFER(var) (var)
+#define XN_PREPARE_VAR64_IN_BUFFER(var) (var)
+#define XN_PREPARE_VAR_FLOAT_IN_BUFFER(var) (var)
+
+#endif //_XN_OSLINUX_X86_H_
diff --git a/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/mingw-win32/XnPlatformLinux-x86.h b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/mingw-win32/XnPlatformLinux-x86.h
new file mode 100644
index 00000000..250e74c2
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/OpenNI/Include/mingw-win32/XnPlatformLinux-x86.h
@@ -0,0 +1,196 @@
+/****************************************************************************
+* *
+* OpenNI 1.x Alpha *
+* Copyright (C) 2011 PrimeSense Ltd. *
+* *
+* This file is part of OpenNI. *
+* *
+* OpenNI is free software: you can redistribute it and/or modify *
+* it under the terms of the GNU Lesser General Public License as published *
+* by the Free Software Foundation, either version 3 of the License, or *
+* (at your option) any later version. *
+* *
+* OpenNI is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU Lesser General Public License for more details. *
+* *
+* You should have received a copy of the GNU Lesser General Public License *
+* along with OpenNI. If not, see <http://www.gnu.org/licenses/>. *
+* *
+****************************************************************************/
+#ifndef _XN_PLATFORM_LINUX_X86_H_
+#define _XN_PLATFORM_LINUX_X86_H_
+
+//---------------------------------------------------------------------------
+// Prerequisites
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// Includes
+//---------------------------------------------------------------------------
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <limits.h>
+
+//---------------------------------------------------------------------------
+// Platform Basic Definition
+//---------------------------------------------------------------------------
+#define XN_PLATFORM XN_PLATFORM_LINUX_X86
+#define XN_PLATFORM_STRING "Linux-x86"
+
+//---------------------------------------------------------------------------
+// Platform Capabilities
+//---------------------------------------------------------------------------
+#define XN_PLATFORM_ENDIAN_TYPE XN_PLATFORM_IS_LITTLE_ENDIAN
+#define XN_PLATFORM_VAARGS_TYPE XN_PLATFORM_USE_GCC_VAARGS_STYLE
+#define XN_PLATFORM_SUPPORTS_DYNAMIC_LIBS 1
+
+//---------------------------------------------------------------------------
+// Basic Types
+//---------------------------------------------------------------------------
+/** Boolean TRUE/FALSE type. */
+typedef unsigned int XnBool;
+
+/** Signed character for strings. */
+typedef char XnChar;
+/** Unsigned character for strings. */
+typedef unsigned char XnUChar;
+
+/** Signed wide character for strings. */
+typedef wchar_t XnWChar;
+
+/** 8-bit signed integer. */
+typedef signed char XnInt8;
+/** 8-bit unsigned integer. */
+typedef unsigned char XnUInt8;
+
+/** 16-bit signed integer. */
+typedef short XnInt16;
+/** 16-bit unsigned integer. */
+typedef unsigned short XnUInt16;
+
+/** 32-bit signed integer. */
+typedef int XnInt32;
+/** 32-bit unsigned integer. */
+typedef unsigned int XnUInt32;
+
+/** 64-bit signed integer. */
+typedef long long XnInt64;
+/** 64-bit unsigned integer. */
+typedef unsigned long long XnUInt64;
+
+/** natural signed integer. */
+typedef int XnInt;
+/** natural unsigned integer. */
+typedef unsigned int XnUInt;
+
+/** Float (32bit) */
+typedef float XnFloat;
+/** Double (64bit) */
+typedef double XnDouble;
+
+/** Far procedures type (for shared libraries functions). */
+typedef void (*XnFarProc)(void *);
+
+/** Size type. */
+typedef size_t XnSizeT;
+
+/** Max unsigned 8-bit value */
+#define XN_MAX_UINT8 UCHAR_MAX
+/** Max unsigned 16-bit value */
+#define XN_MAX_UINT16 USHRT_MAX
+/** Max unsigned 32-bit value */
+#define XN_MAX_UINT32 UINT_MAX
+/** Max unsigned 64-bit value */
+#define XN_MAX_UINT64 ULLONG_MAX
+
+/** Min signed 8-bit value */
+#define XN_MIN_INT8 SCHAR_MIN
+/** Min signed 16-bit value */
+#define XN_MIN_INT16 SHRT_MIN
+/** Min signed 32-bit value */
+#define XN_MIN_INT32 INT_MIN
+/** Min signed 64-bit value */
+#define XN_MIN_INT64 LLONG_MIN
+
+/** Max signed 8-bit value */
+#define XN_MAX_INT8 SCHAR_MAX
+/** Max signed 16-bit value */
+#define XN_MAX_INT16 SHRT_MAX
+/** Max signed 32-bit value */
+#define XN_MAX_INT32 INT_MAX
+/** Max signed 64-bit value */
+#define XN_MAX_INT64 LLONG_MAX
+
+//---------------------------------------------------------------------------
+// Memory
+//---------------------------------------------------------------------------
+/** The default memory alignment. */
+#define XN_DEFAULT_MEM_ALIGN 16
+
+/** The thread static declarator (using TLS). */
+#define XN_THREAD_STATIC __thread
+
+//---------------------------------------------------------------------------
+// Files
+//---------------------------------------------------------------------------
+/** The maximum allowed file path size (in bytes). */
+#define XN_FILE_MAX_PATH 256
+
+//---------------------------------------------------------------------------
+// Call back
+//---------------------------------------------------------------------------
+/** The std call type. */
+#define XN_STDCALL __stdcall
+
+/** The call back calling convention. */
+// DAN - Changed callback type for gcc-windows (mingw) compiles to include the stdcall decoration:
+#define XN_CALLBACK_TYPE XN_STDCALL
+
+/** The C and C++ calling convension. */
+#define XN_C_DECL
+
+//---------------------------------------------------------------------------
+// Macros
+//---------------------------------------------------------------------------
+/** Returns the date and time at compile time. */
+#define XN_TIMESTAMP __DATE__ " " __TIME__
+
+/** Converts n into a pre-processor string. */
+#define XN_STRINGIFY(n) XN_STRINGIFY_HELPER(n)
+#define XN_STRINGIFY_HELPER(n) #n
+
+/** Asserts an expression, only on Debug build. */
+#define XN_ASSERT(x)
+
+//---------------------------------------------------------------------------
+// API Export/Import Macros
+//---------------------------------------------------------------------------
+/** Indicates an exported shared library function. */
+#define XN_API_EXPORT __attribute__ ((visibility("default")))
+
+/** Indicates an imported shared library function. */
+#define XN_API_IMPORT
+
+/** Indicates a deprecated function */
+#define XN_API_DEPRECATED(msg) __attribute__((warning("This function is deprecated: " msg)))
+
+#define XN_DEPRECATED_WARNING_IDS
+#define XN_HIDES_PARENT_METHOD_WARNING_ID
+#define XN_CONDITION_IS_CONST_WARNING_ID
+#define XN_INHERITS_VIA_DOMINANCE_WARNING_ID
+#define XN_UNALIGNED_ADDRESS_WARNING_ID
+#define XN_STRUCT_PADDED_WARNING_ID
+
+#define XN_PRAGMA_START_DISABLED_WARNING_SECTION(warnings)
+#define XN_PRAGMA_STOP_DISABLED_WARNING_SECTION
+
+/** Declares a global shared library export function. */
+#define XN_API_EXPORT_INIT()
+
+#endif //_XN_PLATFORM_LINUX_X86_H_
+
diff --git a/tests/kinectsurface/QtKinectWrapper/QKinectWrapper.cpp b/tests/kinectsurface/QtKinectWrapper/QKinectWrapper.cpp
new file mode 100644
index 00000000..3ebe930d
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/QKinectWrapper.cpp
@@ -0,0 +1,283 @@
+/*
+ QtKinectWrapper - Qt Kinect Wrapper Class
+ Copyright (C) 2011-2013:
+ Daniel Roggen, droggen@gmail.com
+
+ All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+ 2. 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.
+
+THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDERS ``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 FREEBSD PROJECT 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.
+*/
+
+#include "QKinectWrapper.h"
+#include <qmath.h>
+#include <QDebug>
+
+#if defined(_MSC_VER)
+#define isnan(x) _isnan(x)
+#endif
+
+namespace QKinect
+{
+
+/******************************************************************************
+*******************************************************************************
+* QKinectWrapper QKinectWrapper QKinectWrapper QKinectWrapper QKinectWrapper
+*******************************************************************************
+******************************************************************************/
+
+
+/******************************************************************************
+* PUBLIC PUBLIC PUBLIC PUBLIC PUBLIC PUBLIC PUBLIC PUBLIC PUBLIC
+******************************************************************************/
+
+
+/**
+ \brief Constructor - does nothing with the kinect driver but inits some internal vars
+**/
+QKinectWrapper::QKinectWrapper()
+{
+ // Register types used in signal/slot mechanism
+ qRegisterMetaType<QKinect::KinectStatus>( "QKinect::KinectStatus" );
+
+ status = QKinect::Idle;
+}
+
+/**
+ \brief Destructor - calls stop - which terminates the kinect-dedicated reading thread - blocks until terminated.
+**/
+QKinectWrapper::~QKinectWrapper()
+{
+ stop();
+}
+void QKinectWrapper::start()
+{
+ t_requeststop = false;
+ status = QKinect::Idle;
+ QThread::start();
+}
+
+/**
+ \brief Request the the kinect-dedicated reading thread to terminate, and thus
+ release all kinect handles.
+ Sets requeststop, which makes the main reading loop terminate (thread ended) at
+ some later time. Blocks until terminated.
+**/
+void QKinectWrapper::stop()
+{
+ t_requeststop=true;
+
+ wait();
+}
+
+/**
+ \brief Return the latest depth image
+ Call this afer a dataNotification signal
+**/
+QImage QKinectWrapper::getDepth()
+{
+ QMutexLocker locker(&mutex);
+ return imageDepth;
+}
+
+/**
+ \brief Returns if running
+ Runing comprises initializing and reading data (i.e. not running is idle or error)
+ We query the thread state to get this.
+**/
+bool QKinectWrapper::isRunning()
+{
+ if (QThread::isRunning())
+ return true;
+ return false;
+
+}
+
+/**
+ \brief Returns if stopped
+ Runing comprises initializing and reading data (i.e. not running is idle or error)
+ We query the thread state to get this.
+**/
+bool QKinectWrapper::isStopped()
+{
+ if (QThread::isRunning())
+ return false;
+ return true;
+
+}
+
+/******************************************************************************
+* PRIVATE/PROTECTED PRIVATE/PROTECTED PRIVATE/PROTECTED PRIVATE/PROTECTED
+******************************************************************************/
+
+
+/**
+ \brief Starts the kinect-dedicated reading thread.
+ Does the following:
+ 1. Notify the start of the initialization and initialize
+ 2. Notify the initialization outcomes (error, or running if initialization was successful)
+ 3. If successful, does a continous:
+ 3.1. Wait/update kinect data
+ 3.2. Protected by a mutex, generate the images and data structures, made available to the user
+ 3.3. Check if a stop has been requested
+ 4. Stop the kinect reading and release resources, notify.
+
+ The variable accessed outside of this thread are protected by mutexes. This includes:
+ - The status
+ - The QImages for depth, camera
+ - The bodies
+ - etc.
+**/
+void QKinectWrapper::run()
+{
+ mutex.lock();
+ status = QKinect::Initializing;
+ emit statusNotification(status);
+ mutex.unlock();
+
+ bool ok = initialize();
+
+ if (!ok) {
+ mutex.lock();
+ status = QKinect::ErrorStop;
+ emit statusNotification(status);
+ mutex.unlock();
+ return;
+ }
+
+ mutex.lock();
+ status = QKinect::OkRun;
+ emit statusNotification(status);
+ mutex.unlock();
+
+ while (!t_requeststop) {
+ (void)g_Context.WaitAndUpdateAll();
+ // Prepare the data to export outside of the thread
+ mutex.lock();
+ xn::DepthMetaData depthMD;
+ g_DepthGenerator.GetMetaData(depthMD);
+ imageDepth = createDepthImage();
+ emit dataNotification();
+ mutex.unlock();
+ }
+ g_Context.Release();
+
+ mutex.lock();
+ status = QKinect::Idle;
+ emit statusNotification(status);
+ mutex.unlock();
+}
+
+/**
+ \brief Setups and initializes the kinect/openni
+ Returns false if any step fails.
+**/
+bool QKinectWrapper::initialize()
+{
+ XnStatus nRetVal = XN_STATUS_OK;
+ XnMapOutputMode outputMode;
+
+ // Initialize the context
+ nRetVal = g_Context.Init();
+ if (nRetVal != XN_STATUS_OK) {
+ mutex.lock();
+ qCritical() << QString("Context creation failed: %1").arg(xnGetStatusString(nRetVal));
+ mutex.unlock();
+ return false;
+ }
+
+ // Create a depth generator
+ nRetVal = g_DepthGenerator.Create(g_Context);
+ if (nRetVal != XN_STATUS_OK) {
+ mutex.lock();
+ qCritical() << QString("Depth generator creation failed: %1").arg(xnGetStatusString(nRetVal));
+ mutex.unlock();
+ return false;
+ }
+
+// XnUInt32 nCount = g_DepthGenerator.GetSupportedMapOutputModesCount();
+// qDebug() << nCount;
+// XnMapOutputMode *aModes = new XnMapOutputMode[nCount];
+// g_DepthGenerator.GetSupportedMapOutputModes(aModes, nCount);
+
+// for (int i = 0; i < nCount; i++)
+// qDebug() << aModes[i].nFPS << aModes[i].nXRes << aModes[i].nYRes;
+
+ outputMode.nXRes = 640;
+ outputMode.nYRes = 480;
+ outputMode.nFPS = 30;
+ nRetVal = g_DepthGenerator.SetMapOutputMode(outputMode);
+ if (nRetVal != XN_STATUS_OK) {
+ mutex.lock();
+ qCritical() << QString("Depth generator SetMapOutputMode failed: %1").arg(xnGetStatusString(nRetVal));
+ mutex.unlock();
+ return false;
+ }
+
+ // Start producting data
+ nRetVal = g_Context.StartGeneratingAll();
+
+ return true;
+}
+
+/**
+ \brief Creates a QImage comprising the depth map
+**/
+QImage QKinectWrapper::createDepthImage()
+{
+ // Here must mutex / run also access the data
+ xn::SceneMetaData smd;
+ xn::DepthMetaData dmd;
+ g_DepthGenerator.GetMetaData(dmd);
+
+ XnUInt16 g_nXRes = dmd.XRes();
+ XnUInt16 g_nYRes = dmd.YRes();
+
+ QImage image(g_nXRes, g_nYRes, QImage::Format_RGB32);
+
+ const XnDepthPixel* pDepth = dmd.Data();
+ const XnLabel* pLabels = smd.Data();
+
+ for (unsigned nY = 0; nY < g_nYRes; nY++) {
+ uchar *imageptr = image.scanLine(nY);
+
+ for (unsigned nX = 0; nX < g_nXRes; nX++) {
+ unsigned depth = *pDepth;
+
+ if (depth > m_maxDist)
+ depth = m_maxDist;
+ if (depth)
+ depth = ((m_maxDist - depth) * m_depthComp / m_maxDist);
+
+ // depth: 255: closest
+ // depth: 0: furtherst (m_maxDist distance)
+ imageptr[0] = depth;
+ imageptr[1] = depth;
+ imageptr[2] = depth;
+ imageptr[3] = 0xff;
+ pDepth++;
+ imageptr += 4;
+ pLabels++;
+ }
+ }
+
+ return image;
+}
+
+// Adjust depth distance
+void QKinectWrapper::setMaxDist(unsigned int dist)
+{
+ m_maxDist = dist;
+ m_depthComp = 255;
+ if (m_maxDist < 10000)
+ m_depthComp = 255.0 * qSqrt(qSqrt(qSqrt(10000.0 / qreal(m_maxDist)))); // compensate for the adjusted depth scale
+}
+} // End namespace
+
+
+
+
diff --git a/tests/kinectsurface/QtKinectWrapper/QKinectWrapper.h b/tests/kinectsurface/QtKinectWrapper/QKinectWrapper.h
new file mode 100644
index 00000000..69a40a46
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/QKinectWrapper.h
@@ -0,0 +1,117 @@
+/*
+ QtKinectWrapper - Qt Kinect Wrapper Class
+ Copyright (C) 2011-2013:
+ Daniel Roggen, droggen@gmail.com
+
+ All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+ 2. 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.
+
+THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDERS ``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 FREEBSD PROJECT 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.
+*/
+
+
+/*
+ Requirements:
+
+ The QKinectWrapper class requires the following to be installed (versions are those tested and known to work):
+ Windows:
+ OpenNI-Win32-1.5.4.0-Dev.msi
+ SensorKinect093-Bin-Win32-v5.1.2.1.msi (Note: this is PrimeSense Sensor KinectMod 5.1.2.1)
+ NITE-Win32-1.5.2.21-Dev.msi
+
+ Other: not checked
+
+ Basics:
+ QKinectWrapper provides Qt-friendly wrapper to get body skeleton, as well as camera image and depth map from a Kinect.
+ It provides around the logic to 1) initialize the kinect, 2) continuously read the Kinect sensor, including depth map, image frame, and skeleton, 3) perform the necessary calibration, 4) shutdown.
+ In principle up to 15 bodies are supported (limited by the Kinect driver)
+ QKinectWrapper creates a dedicated thread to read the data of the Kinect. The application is shielded from any thread nastiness:
+ - Safe functions are available to get the data from the kinect (taking care of mutexing as required). This includes functions to read image, depth map, and get the body skeleton.
+ - Signals are used to indicate to the application a change of state in QKinectWrapper (e.g. initialize, running, error, stop), and the availability of new data (i.e. a new frame/depth/skeleton from the camera)
+
+ Howto:
+ 1) Instanciate QKinectWrapper
+ 2) Connect the 'dataNotification' and 'statusNotification' signals to your application
+ 3) Optionally, set some visualization parameters (e.g. setPen)
+ 4) Call 'start'
+ 5) In the data notification slot, get the data from the kinect with methods getImage, getDepth, getJoints
+ 6) When done, call stop
+ Use the statusNotification to get notified of initialization error or change of status of the kinect reader thread
+*/
+
+#ifndef __QKINECTWRAPPER_H
+#define __QKINECTWRAPPER_H
+
+#include <QWidget>
+#include <QPainter>
+#include <QThread>
+#include <QMutex>
+#include <XnOpenNI.h>
+
+#ifndef Q_MOC_RUN // Fixes a MOC issue with Qt5 (Qt4.x ok) that fails to properly expand some macros. We skip the include in the MOC pass.
+#include <XnCppWrapper.h>
+#endif // Q_MOC_RUN
+
+namespace QKinect
+{
+/**
+ \brief Status of the body tracking
+ **/
+enum KinectStatus
+{
+ Idle = 0,
+ Initializing = 1,
+ OkRun = 2,
+ ErrorStop = 3
+};
+
+class QKinectWrapper : public QThread
+{
+ Q_OBJECT
+public:
+ QKinectWrapper();
+ virtual ~QKinectWrapper();
+ void run();
+
+ void start();
+ void stop();
+
+ bool isRunning();
+ bool isStopped();
+
+ QImage getDepth();
+
+ void setMaxDist(unsigned int dist);
+
+private:
+ // <-- Data to export outside of the thread
+ QImage imageDepth;
+ // --> End data to export outside of the thread
+
+ unsigned int m_maxDist;
+ qreal m_depthComp;
+ bool t_requeststop;
+ QMutex mutex;
+ volatile KinectStatus status; // 0: pre-init. 1: init. 2: ok-run. 3:error-stop
+ xn::Context g_Context;
+ xn::DepthGenerator g_DepthGenerator;
+
+ QImage createDepthImage();
+
+ bool initialize();
+
+signals:
+ void dataNotification();
+ void statusNotification(QKinect::KinectStatus);
+};
+
+} // End namespace
+
+// Register types used in signal/slot mechanism
+Q_DECLARE_METATYPE(QKinect::KinectStatus);
+
+#endif // __QKINECTWRAPPER_H
diff --git a/tests/kinectsurface/QtKinectWrapper/config.pro b/tests/kinectsurface/QtKinectWrapper/config.pro
new file mode 100644
index 00000000..99ef60c1
--- /dev/null
+++ b/tests/kinectsurface/QtKinectWrapper/config.pro
@@ -0,0 +1,60 @@
+# Include the configuration file below in the Qt .pro file, and modify the path accordingly.
+
+# <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+# <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+# QtKinectWrapper QtKinectWrapper QtKinectWrapper QtKinectWrapper
+# ##############################################################################
+# ##############################################################################
+# Kinect: START OF CONFIGURATION BELOW ->
+#
+# Copy these lines at the end of your the project file of your application (.pro )
+# Check the lines indicated "Modify below" and adapt the path to:
+# 1) QtKinectWrapper sources (i.e. where the QKinectWrapper.* files lie),
+# 2) OpenNI path
+# 3) Make sure the OpenNI, PrimeSense NITE, PrimeSense Kinect Sensor are all in your path
+#
+# -------------------------------- Modify below --------------------------------
+
+# Set QTKINECTWRAPPER_SOURCE_PATH to point to the directory containing the QtKinectWrapper classes
+QTKINECTWRAPPER_SOURCE_PATH = ../../QtKinectWrapper
+
+# Set OPENNI_LIBRARY_PATH to point to the directory where openNI is installed. Assumption: the import libraries are in $$OPENNI_LIBRARY_PATH/lib
+# Multiple path can be specified (e.g. to handle x86 / x64 differences)
+# Quotation marks with spaces
+win32 {
+OPENNI_LIBRARY_PATH = "C:/Program Files (x86)/OpenNI"
+OPENNI_LIBRARY_PATH += "C:/Program Files/OpenNI"
+}
+
+# ------------------------------ Copy as-is below ------------------------------
+# ##############################################################################
+# ##############################################################################
+# QtKinectWrapper QtKinectWrapper QtKinectWrapper QtKinectWrapper
+# ##############################################################################
+# Do not modify: default settings
+# ##############################################################################
+# Path for Qt wrapper
+INCLUDEPATH += $$QTKINECTWRAPPER_SOURCE_PATH
+# Sources for Qt wrapper
+SOURCES += $$QTKINECTWRAPPER_SOURCE_PATH/QKinectWrapper.cpp
+HEADERS += $$QTKINECTWRAPPER_SOURCE_PATH/QKinectWrapper.h
+
+
+
+win32 {
+ # Set the path to the patched openni/include
+ INCLUDEPATH += $$QTKINECTWRAPPER_SOURCE_PATH/OpenNI/Include
+ # Set the path to the Qt wrapper
+ INCLUDEPATH += $$QTKINECTWRAPPER_SOURCE_PATH
+
+ # Iterate through
+ for(l, OPENNI_LIBRARY_PATH):LIBS+=-L$$l/lib
+ #LIBS += -L$$OPENNI_LIBRARY_PATH/lib
+ LIBS += -lopenNI
+}
+
+# ##############################################################################
+# ##############################################################################
+# QtKinectWrapper QtKinectWrapper QtKinectWrapper QtKinectWrapper
+# >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+# >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
diff --git a/tests/kinectsurface/kinectsurface.pro b/tests/kinectsurface/kinectsurface.pro
new file mode 100644
index 00000000..c66ae901
--- /dev/null
+++ b/tests/kinectsurface/kinectsurface.pro
@@ -0,0 +1,71 @@
+!include( ../tests.pri ) {
+ error( "Couldn't find the tests.pri file!" )
+}
+
+SOURCES += main.cpp \
+ surfacedata.cpp
+HEADERS += \
+ surfacedata.h
+
+QT += widgets
+
+INSTALLS += target
+
+# <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+# <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+# QtKinectWrapper QtKinectWrapper QtKinectWrapper QtKinectWrapper
+# ##############################################################################
+# ##############################################################################
+# Kinect: START OF CONFIGURATION BELOW ->
+#
+# Copy these lines at the end of your the project file of your application (.pro )
+# Check the lines indicated "Modify below" and adapt the path to:
+# 1) QtKinectWrapper sources (i.e. where the QKinectWrapper.* files lie),
+# 2) OpenNI path
+# 3) Make sure the OpenNI, PrimeSense NITE, PrimeSense Kinect Sensor are all in your path
+#
+# -------------------------------- Modify below --------------------------------
+
+# Set QTKINECTWRAPPER_SOURCE_PATH to point to the directory containing the QtKinectWrapper classes
+QTKINECTWRAPPER_SOURCE_PATH = QtKinectWrapper
+
+# Set OPENNI_LIBRARY_PATH to point to the directory where openNI is installed. Assumption: the import libraries are in $$OPENNI_LIBRARY_PATH/lib
+# Multiple path can be specified (e.g. to handle x86 / x64 differences)
+# Quotation marks with spaces
+win32 {
+OPENNI_LIBRARY_PATH = "C:/Program Files (x86)/OpenNI"
+OPENNI_LIBRARY_PATH += "C:/Program Files/OpenNI"
+}
+
+# ------------------------------ Copy as-is below ------------------------------
+# ##############################################################################
+# ##############################################################################
+# QtKinectWrapper QtKinectWrapper QtKinectWrapper QtKinectWrapper
+# ##############################################################################
+# Do not modify: default settings
+# ##############################################################################
+# Path for Qt wrapper
+INCLUDEPATH += $$QTKINECTWRAPPER_SOURCE_PATH
+# Sources for Qt wrapper
+SOURCES += $$QTKINECTWRAPPER_SOURCE_PATH/QKinectWrapper.cpp
+HEADERS += $$QTKINECTWRAPPER_SOURCE_PATH/QKinectWrapper.h
+
+
+
+win32 {
+ # Set the path to the patched openni/include
+ INCLUDEPATH += $$QTKINECTWRAPPER_SOURCE_PATH/OpenNI/Include
+ # Set the path to the Qt wrapper
+ INCLUDEPATH += $$QTKINECTWRAPPER_SOURCE_PATH
+
+ # Iterate through
+ for(l, OPENNI_LIBRARY_PATH):LIBS+=-L$$l/lib
+ #LIBS += -L$$OPENNI_LIBRARY_PATH/lib
+ LIBS += -lopenNI
+}
+
+# ##############################################################################
+# ##############################################################################
+# QtKinectWrapper QtKinectWrapper QtKinectWrapper QtKinectWrapper
+# >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+# >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
diff --git a/tests/kinectsurface/main.cpp b/tests/kinectsurface/main.cpp
new file mode 100644
index 00000000..04bfc207
--- /dev/null
+++ b/tests/kinectsurface/main.cpp
@@ -0,0 +1,167 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 "surfacedata.h"
+
+#include <QApplication>
+#include <QWidget>
+#include <QHBoxLayout>
+#include <QVBoxLayout>
+#include <QPushButton>
+#include <QLabel>
+#include <QComboBox>
+#include <QSlider>
+#include <QTextEdit>
+#include <QScreen>
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+
+ QWidget *widget = new QWidget;
+ QHBoxLayout *hLayout = new QHBoxLayout(widget);
+ QVBoxLayout *vLayout = new QVBoxLayout();
+
+ Q3DSurface *surface = new Q3DSurface();
+ Q3DScatter *scatter = new Q3DScatter();
+ Q3DBars *bars = new Q3DBars();
+
+ QSize screenSize = surface->screen()->size();
+
+ QWidget *containerSurface = QWidget::createWindowContainer(surface);
+ containerSurface->setMinimumSize(QSize(screenSize.width() / 2, screenSize.height() / 2));
+ containerSurface->setMaximumSize(screenSize);
+ containerSurface->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ containerSurface->setFocusPolicy(Qt::StrongFocus);
+
+ QWidget *containerScatter = QWidget::createWindowContainer(scatter);
+ containerScatter->setMinimumSize(QSize(screenSize.width() / 2, screenSize.height() / 2));
+ containerScatter->setMaximumSize(screenSize);
+ containerScatter->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ containerScatter->setFocusPolicy(Qt::StrongFocus);
+ containerScatter->setVisible(false);
+
+ QWidget *containerBars = QWidget::createWindowContainer(bars);
+ containerBars->setMinimumSize(QSize(screenSize.width() / 2, screenSize.height() / 2));
+ containerBars->setMaximumSize(screenSize);
+ containerBars->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ containerBars->setFocusPolicy(Qt::StrongFocus);
+ containerBars->setVisible(false);
+
+ widget->setWindowTitle(QStringLiteral("Visualization from Kinect depth data"));
+
+ hLayout->addWidget(containerSurface, 1);
+ hLayout->addWidget(containerScatter, 1);
+ hLayout->addWidget(containerBars, 1);
+ hLayout->addLayout(vLayout);
+
+ QPushButton *startButton = new QPushButton(widget);
+ startButton->setText(QStringLiteral("Start Kinect"));
+
+ QPushButton *stopButton = new QPushButton(widget);
+ stopButton->setText(QStringLiteral("Stop Kinect"));
+
+ QComboBox *resolutionBox = new QComboBox(widget);
+ resolutionBox->addItem(QStringLiteral("Low"));
+ resolutionBox->addItem(QStringLiteral("Medium"));
+ resolutionBox->addItem(QStringLiteral("High"));
+ resolutionBox->addItem(QStringLiteral("Max")); // Comment this out if demo machine is low-perf
+ resolutionBox->setCurrentIndex(0);
+
+ QComboBox *modeBox = new QComboBox(widget);
+ modeBox->addItem(QStringLiteral("Surface Plot"));
+ modeBox->addItem(QStringLiteral("Scatter Chart"));
+ modeBox->addItem(QStringLiteral("Bar Chart"));
+ modeBox->setCurrentIndex(0);
+
+ QSlider *distanceSlider = new QSlider(Qt::Horizontal, widget);
+ distanceSlider->setTickInterval(10);
+ distanceSlider->setTickPosition(QSlider::TicksBelow);
+ distanceSlider->setMinimum(10);
+ distanceSlider->setValue(50);
+ distanceSlider->setMaximum(200);
+
+ QLinearGradient gradientOne(0, 0, 200, 1);
+ gradientOne.setColorAt(0.0, Qt::black);
+ gradientOne.setColorAt(0.33, Qt::blue);
+ gradientOne.setColorAt(0.67, Qt::red);
+ gradientOne.setColorAt(1.0, Qt::yellow);
+
+ QPixmap pm(200, 24);
+ QPainter pmp(&pm);
+ pmp.setBrush(QBrush(gradientOne));
+ pmp.setPen(Qt::NoPen);
+ pmp.drawRect(0, 0, 200, 24);
+
+ QPushButton *gradientOneButton = new QPushButton(widget);
+ gradientOneButton->setIcon(QIcon(pm));
+ gradientOneButton->setIconSize(QSize(200, 24));
+ gradientOneButton->setToolTip(QStringLiteral("Colors: Thermal Imitation"));
+
+ QLinearGradient gradientTwo(0, 0, 200, 1);
+ gradientTwo.setColorAt(0.0, Qt::white);
+ gradientTwo.setColorAt(0.8, Qt::red);
+ gradientTwo.setColorAt(1.0, Qt::green);
+
+ pmp.setBrush(QBrush(gradientTwo));
+ pmp.setPen(Qt::NoPen);
+ pmp.drawRect(0, 0, 200, 24);
+
+ QPushButton *gradientTwoButton = new QPushButton(widget);
+ gradientTwoButton->setIcon(QIcon(pm));
+ gradientTwoButton->setIconSize(QSize(200, 24));
+ gradientTwoButton->setToolTip(QStringLiteral("Colors: Highlight Foreground"));
+
+ QTextEdit *status = new QTextEdit(QStringLiteral("<b>Ready</b><br>"), widget);
+ status->setReadOnly(true);
+
+ vLayout->addWidget(startButton);
+ vLayout->addWidget(stopButton);
+ vLayout->addWidget(new QLabel(QStringLiteral("Change resolution")));
+ vLayout->addWidget(resolutionBox);
+ vLayout->addWidget(new QLabel(QStringLiteral("Change visualization type")));
+ vLayout->addWidget(modeBox);
+ vLayout->addWidget(new QLabel(QStringLiteral("Adjust far distance")));
+ vLayout->addWidget(distanceSlider);
+ vLayout->addWidget(new QLabel(QStringLiteral("Change color scheme")));
+ vLayout->addWidget(gradientOneButton);
+ vLayout->addWidget(gradientTwoButton);
+ vLayout->addWidget(status, 1, Qt::AlignBottom);
+
+ widget->show();
+
+ SurfaceData datagen(surface, scatter, bars, status);
+ ContainerChanger changer(containerSurface, containerScatter, containerBars,
+ gradientOneButton, gradientTwoButton);
+
+ QObject::connect(startButton, &QPushButton::clicked, &datagen, &SurfaceData::start);
+ QObject::connect(stopButton, &QPushButton::clicked, &datagen, &SurfaceData::stop);
+ QObject::connect(distanceSlider, &QSlider::valueChanged, &datagen, &SurfaceData::setDistance);
+ QObject::connect(resolutionBox, SIGNAL(activated(int)), &datagen, SLOT(setResolution(int)));
+ QObject::connect(modeBox, SIGNAL(activated(int)), &changer, SLOT(changeContainer(int)));
+ QObject::connect(modeBox, SIGNAL(activated(int)), &datagen, SLOT(changeMode(int)));
+ QObject::connect(status, &QTextEdit::textChanged, &datagen, &SurfaceData::scrollDown);
+ QObject::connect(gradientOneButton, &QPushButton::clicked, &datagen,
+ &SurfaceData::useGradientOne);
+ QObject::connect(gradientTwoButton, &QPushButton::clicked, &datagen,
+ &SurfaceData::useGradientTwo);
+
+ datagen.setDistance(distanceSlider->value());
+
+ return app.exec();
+}
diff --git a/tests/kinectsurface/surfacedata.cpp b/tests/kinectsurface/surfacedata.cpp
new file mode 100644
index 00000000..b11be8d5
--- /dev/null
+++ b/tests/kinectsurface/surfacedata.cpp
@@ -0,0 +1,357 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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
+**
+****************************************************************************/
+
+#define NOMINMAX
+
+#include "surfacedata.h"
+#include "QKinectWrapper.h"
+#include <QtDataVisualization/Q3DValueAxis>
+#include <QScrollBar>
+#include <QSize>
+#include <QImage>
+
+QT_DATAVISUALIZATION_USE_NAMESPACE
+
+SurfaceData::SurfaceData(Q3DSurface *surface, Q3DScatter *scatter, Q3DBars *bars,
+ QTextEdit *statusArea) :
+ m_surface(surface),
+ m_scatter(scatter),
+ m_bars(bars),
+ m_statusArea(statusArea),
+ m_resize(true),
+ m_resolution(QSize(320, 240)),
+ m_resolutionLevel(0),
+ m_mode(Surface)
+{
+ // Initialize surface
+ m_surface->setTheme(QDataVis::ThemeIsabelle);
+ QLinearGradient gradient;
+ gradient.setColorAt(0.0, Qt::black);
+ gradient.setColorAt(0.33, Qt::blue);
+ gradient.setColorAt(0.67, Qt::red);
+ gradient.setColorAt(1.0, Qt::yellow);
+ m_surface->setSelectionMode(QDataVis::SelectionModeNone);
+ m_surface->setGridVisible(false);
+ m_surface->setGradient(gradient);
+ m_surface->axisY()->setMax(255);
+ m_surface->setSurfaceGridEnabled(false);
+ m_surface->setBackgroundVisible(false);
+ m_surface->setSmoothSurfaceEnabled(false);
+ m_surface->setActiveDataProxy(new QHeightMapSurfaceDataProxy());
+ m_surface->setCameraPosition(0.0, 90.0, 105);
+
+ // Initialize scatter
+ m_scatter->setTheme(QDataVis::ThemeStoneMoss);
+ m_scatter->setSelectionMode(QDataVis::SelectionModeNone);
+ m_scatter->setGridVisible(false);
+ m_scatter->setObjectType(QDataVis::MeshStyleDots, false);
+ m_scatter->setShadowQuality(QDataVis::ShadowQualitySoftLow);
+ m_scatter->setCameraPosition(0.0, 85.0, 110);
+ m_scatter->axisY()->setMin(-128);
+ m_scatter->axisY()->setMax(128);
+ m_scatter->axisX()->setMin(-m_resolution.width() / 2);
+ m_scatter->axisX()->setMax(m_resolution.width() / 2);
+ m_scatter->axisZ()->setMin(-m_resolution.height() / 2);
+ m_scatter->axisZ()->setMax(m_resolution.height() / 2);
+
+ // Initialize bars
+ m_bars->setTheme(QDataVis::ThemeQt);
+ m_bars->setSelectionMode(QDataVis::SelectionModeNone);
+ m_bars->setGridVisible(false);
+ m_bars->setBarType(QDataVis::MeshStyleBars, true);
+#if 1
+ m_bars->setShadowQuality(QDataVis::ShadowQualityLow);
+#else
+ m_bars->setBarSpacing(QSizeF(0.0, 0.0));
+#endif
+ m_bars->setCameraPosition(0.0, 75.0);
+ m_bars->valueAxis()->setMax(255);
+
+ // Hide scroll bar
+ m_statusArea->verticalScrollBar()->setVisible(false);
+
+ // Connect Kinect signals
+ connect(&m_kinect, &QKinect::QKinectWrapper::dataNotification, this, &SurfaceData::updateData);
+ connect(&m_kinect, &QKinect::QKinectWrapper::statusNotification, this,
+ &SurfaceData::updateStatus);
+}
+
+SurfaceData::~SurfaceData()
+{ // HACK: The current context needs to be destroyed last
+ // TODO: Fix properly in datavis code somehow
+ if (m_mode == Surface) {
+ delete m_scatter;
+ delete m_bars;
+ delete m_surface;
+ } else if (m_mode == MeshStyleBars) {
+ delete m_scatter;
+ delete m_surface;
+ delete m_bars;
+ } else {
+ delete m_bars;
+ delete m_surface;
+ delete m_scatter;
+ }
+}
+
+void SurfaceData::updateData()
+{
+ QImage depthMap = m_kinect.getDepth();
+ if (m_resize) // Resize for better performance
+ depthMap = depthMap.scaled(m_resolution);
+ if (m_mode != Surface)
+ setData(depthMap);
+ else
+ static_cast<QHeightMapSurfaceDataProxy *>(m_surface->activeDataProxy())->setHeightMap(
+ depthMap);
+}
+
+void SurfaceData::updateStatus(QKinect::KinectStatus status)
+{
+ switch (status) {
+ case QKinect::Idle: {
+ m_statusArea->append(QStringLiteral("<b>Kinect:</b> Stopped"));
+ m_statusArea->append(QStringLiteral("<br><b>Ready</b><br>"));
+ break;
+ }
+ case QKinect::Initializing: {
+ m_statusArea->append(QStringLiteral("<b>Kinect:</b> Initializing"));
+ break;
+ }
+ case QKinect::OkRun: {
+ m_statusArea->append(QStringLiteral("<b>Kinect:</b> Running"));
+ m_statusArea->append(QString(QStringLiteral("<i> - resolution: %1 x %2</i>")).arg(
+ m_resolution.width()).arg(m_resolution.height()));
+ break;
+ }
+ default: {
+ m_statusArea->append(QStringLiteral("<b>Kinect:</b> Error"));
+ break;
+ }
+ };
+}
+
+void SurfaceData::start()
+{
+ if (m_kinect.isStopped())
+ m_kinect.start();
+ else
+ m_statusArea->append(QStringLiteral("<b>Kinect:</b> Already running"));
+}
+
+void SurfaceData::stop()
+{
+ if (m_kinect.isRunning())
+ m_kinect.stop();
+ else
+ m_statusArea->append(QStringLiteral("<b>Kinect:</b> Already stopped"));
+}
+
+void SurfaceData::setDistance(int distance)
+{
+ m_kinect.setMaxDist(unsigned int(distance * 100));
+}
+
+void SurfaceData::setResolution(int selection)
+{
+ m_resolutionLevel = selection;
+ switch (selection) {
+ case 0: {
+ m_resize = true;
+ m_resolution = QSize(320, 240);
+ break;
+ }
+ case 1: {
+ m_resize = true;
+ m_resolution = QSize(384, 288);
+ break;
+ }
+ case 2: {
+ m_resize = true;
+ m_resolution = QSize(512, 384);
+ break;
+ }
+ case 3: {
+ m_resize = false;
+ m_resolution = QSize(640, 480);
+ break;
+ }
+ };
+ if (m_mode == Scatter) {
+ m_resize = true;
+ m_resolution /= 4;
+ m_scatter->axisX()->setMin(-m_resolution.width() / 2);
+ m_scatter->axisX()->setMax(m_resolution.width() / 2);
+ m_scatter->axisZ()->setMin(-m_resolution.height() / 2);
+ m_scatter->axisZ()->setMax(m_resolution.height() / 2);
+ m_scatterDataArray = new QScatterDataArray;
+ m_scatterDataArray->resize(m_resolution.width() * m_resolution.height());
+ } else if (m_mode == MeshStyleBars) {
+ m_resize = true;
+ m_resolution /= 4;
+ m_barDataArray = new QBarDataArray;
+ m_barDataArray->reserve(m_resolution.height());
+ for (int i = 0; i < m_resolution.height(); i++) {
+ QBarDataRow *newProxyRow = new QBarDataRow(m_resolution.width());
+ m_barDataArray->append(newProxyRow);
+ }
+ }
+
+ m_statusArea->append(QString(QStringLiteral("<b>Resolution:</b> %1 x %2")).arg(
+ m_resolution.width()).arg(m_resolution.height()));
+ if (m_kinect.isStopped())
+ m_statusArea->append(QStringLiteral("<i> - change takes effect once Kinect is running</i>"));
+}
+
+void SurfaceData::scrollDown()
+{
+ QScrollBar *scrollbar = m_statusArea->verticalScrollBar();
+ scrollbar->setValue(scrollbar->maximum());
+}
+
+void SurfaceData::useGradientOne()
+{
+ m_surface->setTheme(QDataVis::ThemeIsabelle);
+ QLinearGradient gradient;
+ gradient.setColorAt(0.0, Qt::black);
+ gradient.setColorAt(0.33, Qt::blue);
+ gradient.setColorAt(0.67, Qt::red);
+ gradient.setColorAt(1.0, Qt::yellow);
+ m_surface->setGradient(gradient);
+ m_statusArea->append(QStringLiteral("<b>Colors:</b> Thermal image imitation"));
+}
+
+void SurfaceData::useGradientTwo()
+{
+ m_surface->setTheme(QDataVis::ThemeQt);
+ QLinearGradient gradient;
+ gradient.setColorAt(0.0, Qt::white);
+ gradient.setColorAt(0.8, Qt::red);
+ gradient.setColorAt(1.0, Qt::green);
+ m_surface->setGradient(gradient);
+ m_statusArea->append(QStringLiteral("<b>Colors:</b> Highlight foreground"));
+}
+
+void SurfaceData::setData(const QImage &image)
+{
+ QImage heightImage = image;
+
+ uchar *bits = heightImage.bits();
+
+ int imageHeight = heightImage.height();
+ int imageWidth = heightImage.width();
+ int bitCount = imageWidth * 4 * (imageHeight - 1);
+ int widthBits = imageWidth * 4;
+
+ if (m_mode == Scatter) {
+ QScatterDataItem *ptrToDataArray = &m_scatterDataArray->first();
+
+ int limitsX = imageWidth / 2;
+ int limitsZ = imageHeight / 2;
+ qreal height = 0;
+ int count = 0;
+
+ for (int i = -limitsZ; i < limitsZ; i++, bitCount -= widthBits) {
+ for (int j = -limitsX; j < limitsX; j++) {
+ height = qreal(bits[bitCount + ((j + limitsX) * 4)]) - 128.0;
+ if (height > -128) {
+ ptrToDataArray->setPosition(QVector3D(qreal(j), height, qreal(i)));
+ ptrToDataArray++;
+ count++;
+ }
+ }
+ }
+
+ QScatterDataArray *dataArray = new QScatterDataArray(m_scatterDataArray->mid(0, count));
+ static_cast<QScatterDataProxy *>(m_scatter->activeDataProxy())->resetArray(dataArray);
+ } else {
+ QBarDataArray *dataArray = m_barDataArray;
+ for (int i = 0; i < imageHeight; i++, bitCount -= widthBits) {
+ QBarDataRow &newRow = *dataArray->at(i);
+ for (int j = 0; j < imageWidth; j++)
+ newRow[j] = qreal(bits[bitCount + (j * 4)]);
+ }
+
+ static_cast<QBarDataProxy *>(m_bars->activeDataProxy())->resetArray(dataArray);
+ }
+}
+
+void SurfaceData::changeMode(int mode)
+{
+ m_mode = VisualizationMode(mode);
+ switch (m_mode) {
+ case Surface: {
+ m_statusArea->append(QStringLiteral("<b>Visualization Type:</b> Surface"));
+ break;
+ }
+ case Scatter: {
+ m_statusArea->append(QStringLiteral("<b>Visualization Type:</b> Scatter"));
+ break;
+ }
+ default: {
+ m_statusArea->append(QStringLiteral("<b>Visualization Type:</b> Bars"));
+ break;
+ }
+ }
+ // Reset resolution after mode change
+ setResolution(m_resolutionLevel);
+}
+
+ContainerChanger::ContainerChanger(QWidget *surface, QWidget *scatter, QWidget *bars,
+ QWidget *buttonOne, QWidget *buttonTwo)
+ : m_surface(surface),
+ m_scatter(scatter),
+ m_bars(bars),
+ m_button1(buttonOne),
+ m_button2(buttonTwo)
+{
+}
+
+ContainerChanger::~ContainerChanger()
+{
+}
+
+void ContainerChanger::changeContainer(int container)
+{
+ switch (container) {
+ case 0: {
+ m_scatter->setVisible(false);
+ m_bars->setVisible(false);
+ m_surface->setVisible(true);
+ m_button1->setEnabled(true);
+ m_button2->setEnabled(true);
+ break;
+ }
+ case 1: {
+ m_surface->setVisible(false);
+ m_bars->setVisible(false);
+ m_scatter->setVisible(true);
+ m_button1->setEnabled(false);
+ m_button2->setEnabled(false);
+ break;
+ }
+ case 2: {
+ m_surface->setVisible(false);
+ m_scatter->setVisible(false);
+ m_bars->setVisible(true);
+ m_button1->setEnabled(false);
+ m_button2->setEnabled(false);
+ break;
+ }
+ }
+}
diff --git a/tests/kinectsurface/surfacedata.h b/tests/kinectsurface/surfacedata.h
new file mode 100644
index 00000000..0bf753cd
--- /dev/null
+++ b/tests/kinectsurface/surfacedata.h
@@ -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 QtDataVisualization 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 SURFACEDATA_H
+#define SURFACEDATA_H
+
+#include "QKinectWrapper.h"
+#include <QtDataVisualization/Q3DScatter>
+#include <QtDataVisualization/Q3DBars>
+#include <QtDataVisualization/Q3DSurface>
+#include <QtDataVisualization/QScatterDataProxy>
+#include <QtDataVisualization/QBarDataProxy>
+#include <QtDataVisualization/QHeightMapSurfaceDataProxy>
+#include <QTextEdit>
+
+using namespace QtDataVisualization;
+
+class SurfaceData : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit SurfaceData(Q3DSurface *surface, Q3DScatter *scatter, Q3DBars *bars,
+ QTextEdit *statusLabel);
+ ~SurfaceData();
+
+ void start();
+ void stop();
+
+ void updateData();
+ void updateStatus(QKinect::KinectStatus status);
+
+ void setDistance(int distance);
+ void scrollDown();
+ void setData(const QImage &image);
+ void useGradientOne();
+ void useGradientTwo();
+
+public:
+ enum VisualizationMode {
+ Surface = 0,
+ Scatter,
+ MeshStyleBars
+ };
+
+public slots:
+ void setResolution(int selection);
+ void changeMode(int mode);
+
+private:
+ Q3DSurface *m_surface;
+ Q3DScatter *m_scatter;
+ Q3DBars *m_bars;
+ QTextEdit *m_statusArea;
+ bool m_resize;
+ QSize m_resolution;
+ int m_resolutionLevel;
+ VisualizationMode m_mode;
+ QScatterDataArray *m_scatterDataArray;
+ QBarDataArray *m_barDataArray;
+ QKinect::QKinectWrapper m_kinect;
+};
+
+class ContainerChanger : public QObject
+{
+ Q_OBJECT
+
+public:
+ explicit ContainerChanger(QWidget *surface, QWidget *scatter, QWidget *bars,
+ QWidget *buttonOne, QWidget *buttonTwo);
+ ~ContainerChanger();
+
+public slots:
+ void changeContainer(int container);
+
+private:
+ QWidget *m_surface;
+ QWidget *m_scatter;
+ QWidget *m_bars;
+ QWidget *m_button1;
+ QWidget *m_button2;
+};
+
+#endif
diff --git a/examples/qmlmaps/main.cpp b/tests/qmlcamera/main.cpp
index b58e66f8..90d81eab 100644
--- a/examples/qmlmaps/main.cpp
+++ b/tests/qmlcamera/main.cpp
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -18,11 +18,6 @@
#include <QtGui/QGuiApplication>
#include "qtquick2applicationviewer.h"
-#ifdef Q_OS_ANDROID
-#include <QDir>
-#include <QQmlEngine>
-#endif
-#include <QDebug>
int main(int argc, char *argv[])
{
@@ -37,9 +32,9 @@ int main(int argc, char *argv[])
viewer.addImportPath(QString::fromLatin1("%1/%2").arg(QCoreApplication::applicationDirPath(),
QString::fromLatin1("qml")));
#endif
- viewer.setSource(QUrl("qrc:/qml/main.qml"));
+ viewer.setMainQmlFile(QStringLiteral("qml/qmlcamera/main.qml"));
viewer.setResizeMode(QQuickView::SizeRootObjectToView);
- viewer.show();
+ viewer.showExpanded();
return app.exec();
}
diff --git a/tests/qmlcamera/qml/qmlcamera/Axes.qml b/tests/qmlcamera/qml/qmlcamera/Axes.qml
new file mode 100644
index 00000000..b0ba3eb2
--- /dev/null
+++ b/tests/qmlcamera/qml/qmlcamera/Axes.qml
@@ -0,0 +1,50 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 com.digia.QtDataVisualization 1.0
+
+Item {
+ property alias column: columnAxis
+ property alias expenses: expensesAxis
+ property alias income: incomeAxis
+
+ // For row labels we can use row labels from data proxy, so default axis
+ // suffices for rows.
+
+ // Custom labels for columns, since the data contains abbreviated month names.
+ CategoryAxis3D {
+ id: columnAxis
+ categoryLabels: ["January", "February", "March", "April", "May", "June",
+ "July", "August", "September", "October", "November", "December"]
+ }
+ ValueAxis3D {
+ id: incomeAxis
+ min: 0
+ max: 35
+ labelFormat: "%.2f M\u20AC"
+ title: "Monthly income"
+ }
+ ValueAxis3D {
+ id: expensesAxis
+ min: 0
+ max: 35
+ labelFormat: "-%.2f M\u20AC"
+ title: "Monthly expenses"
+ }
+}
diff --git a/tests/qmlcamera/qml/qmlcamera/ControlSurface.qml b/tests/qmlcamera/qml/qmlcamera/ControlSurface.qml
new file mode 100644
index 00000000..c655e016
--- /dev/null
+++ b/tests/qmlcamera/qml/qmlcamera/ControlSurface.qml
@@ -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 QtDataVisualization 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.0
+
+Rectangle {
+ id: controlRect
+ color: "#000000"
+ property real xValue : 0
+ property real yValue : 0
+ property real minXValue : 0
+ property real minYValue : 0
+ property real maxXValue : 0
+ property real maxYValue : 0
+
+ property real halfWidth: width / 2.0;
+ property real halfHeight: height / 2.0;
+
+ Rectangle {
+ id: pointer
+ color: "#FFFFFF"
+ width: 5
+ height: 5
+ }
+
+ MouseArea {
+ id: inputArea
+ anchors.fill: parent
+ onPositionChanged: {
+ pointer.x = Math.min(Math.max(0, mouse.x), controlRect.width - pointer.width );
+ pointer.y = Math.min(Math.max(0, mouse.y), controlRect.height - pointer.height);
+ var mixX = (mouse.x / controlRect.width);
+ var mixY = (mouse.y / controlRect.width);
+ controlRect.xValue = minXValue*(1-mixX) + maxXValue*mixX;
+ controlRect.yValue = minYValue*(1-mixY) + maxYValue*mixY;
+ }
+ }
+}
diff --git a/tests/qmlcamera/qml/qmlcamera/Data.qml b/tests/qmlcamera/qml/qmlcamera/Data.qml
new file mode 100644
index 00000000..fff568cc
--- /dev/null
+++ b/tests/qmlcamera/qml/qmlcamera/Data.qml
@@ -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 QtDataVisualization 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 com.digia.QtDataVisualization 1.0
+
+Item {
+ property alias mapping: valueMapping
+ property alias model: dataModel
+ property alias proxy: modelProxy
+
+ BarDataMapping {
+ id: valueMapping
+ rowRole: "year"
+ columnRole: "month"
+ valueRole: "expenses"
+ }
+
+ ItemModelBarDataProxy {
+ id: modelProxy
+ activeMapping: valueMapping
+ itemModel: dataModel
+ }
+
+ ListModel {
+ id: dataModel
+ ListElement{ year: "2006"; month: "Jan"; expenses: "4"; income: "5" }
+ ListElement{ year: "2006"; month: "Feb"; expenses: "5"; income: "6" }
+ ListElement{ year: "2006"; month: "Mar"; expenses: "7"; income: "4" }
+ ListElement{ year: "2006"; month: "Apr"; expenses: "3"; income: "2" }
+ ListElement{ year: "2006"; month: "May"; expenses: "4"; income: "1" }
+ ListElement{ year: "2006"; month: "Jun"; expenses: "2"; income: "2" }
+ ListElement{ year: "2006"; month: "Jul"; expenses: "1"; income: "3" }
+ ListElement{ year: "2006"; month: "Aug"; expenses: "5"; income: "1" }
+ ListElement{ year: "2006"; month: "Sep"; expenses: "2"; income: "3" }
+ ListElement{ year: "2006"; month: "Oct"; expenses: "5"; income: "2" }
+ ListElement{ year: "2006"; month: "Nov"; expenses: "8"; income: "5" }
+ ListElement{ year: "2006"; month: "Dec"; expenses: "3"; income: "3" }
+
+ ListElement{ year: "2007"; month: "Jan"; expenses: "3"; income: "1" }
+ ListElement{ year: "2007"; month: "Feb"; expenses: "4"; income: "2" }
+ ListElement{ year: "2007"; month: "Mar"; expenses: "12"; income: "4" }
+ ListElement{ year: "2007"; month: "Apr"; expenses: "13"; income: "6" }
+ ListElement{ year: "2007"; month: "May"; expenses: "14"; income: "11" }
+ ListElement{ year: "2007"; month: "Jun"; expenses: "7"; income: "7" }
+ ListElement{ year: "2007"; month: "Jul"; expenses: "6"; income: "4" }
+ ListElement{ year: "2007"; month: "Aug"; expenses: "4"; income: "15" }
+ ListElement{ year: "2007"; month: "Sep"; expenses: "2"; income: "18" }
+ ListElement{ year: "2007"; month: "Oct"; expenses: "29"; income: "25" }
+ ListElement{ year: "2007"; month: "Nov"; expenses: "23"; income: "29" }
+ ListElement{ year: "2007"; month: "Dec"; expenses: "5"; income: "9" }
+
+ ListElement{ year: "2008"; month: "Jan"; expenses: "3"; income: "8" }
+ ListElement{ year: "2008"; month: "Feb"; expenses: "8"; income: "14" }
+ ListElement{ year: "2008"; month: "Mar"; expenses: "10"; income: "20" }
+ ListElement{ year: "2008"; month: "Apr"; expenses: "12"; income: "24" }
+ ListElement{ year: "2008"; month: "May"; expenses: "10"; income: "19" }
+ ListElement{ year: "2008"; month: "Jun"; expenses: "5"; income: "8" }
+ ListElement{ year: "2008"; month: "Jul"; expenses: "1"; income: "4" }
+ ListElement{ year: "2008"; month: "Aug"; expenses: "7"; income: "12" }
+ ListElement{ year: "2008"; month: "Sep"; expenses: "4"; income: "16" }
+ ListElement{ year: "2008"; month: "Oct"; expenses: "22"; income: "33" }
+ ListElement{ year: "2008"; month: "Nov"; expenses: "16"; income: "25" }
+ ListElement{ year: "2008"; month: "Dec"; expenses: "2"; income: "7" }
+
+ ListElement{ year: "2009"; month: "Jan"; expenses: "4"; income: "5" }
+ ListElement{ year: "2009"; month: "Feb"; expenses: "4"; income: "7" }
+ ListElement{ year: "2009"; month: "Mar"; expenses: "11"; income: "14" }
+ ListElement{ year: "2009"; month: "Apr"; expenses: "16"; income: "22" }
+ ListElement{ year: "2009"; month: "May"; expenses: "3"; income: "5" }
+ ListElement{ year: "2009"; month: "Jun"; expenses: "4"; income: "8" }
+ ListElement{ year: "2009"; month: "Jul"; expenses: "7"; income: "9" }
+ ListElement{ year: "2009"; month: "Aug"; expenses: "9"; income: "13" }
+ ListElement{ year: "2009"; month: "Sep"; expenses: "1"; income: "6" }
+ ListElement{ year: "2009"; month: "Oct"; expenses: "14"; income: "25" }
+ ListElement{ year: "2009"; month: "Nov"; expenses: "19"; income: "29" }
+ ListElement{ year: "2009"; month: "Dec"; expenses: "5"; income: "7" }
+
+ ListElement{ year: "2010"; month: "Jan"; expenses: "14"; income: "22" }
+ ListElement{ year: "2010"; month: "Feb"; expenses: "5"; income: "7" }
+ ListElement{ year: "2010"; month: "Mar"; expenses: "1"; income: "9" }
+ ListElement{ year: "2010"; month: "Apr"; expenses: "1"; income: "12" }
+ ListElement{ year: "2010"; month: "May"; expenses: "5"; income: "9" }
+ ListElement{ year: "2010"; month: "Jun"; expenses: "5"; income: "8" }
+ ListElement{ year: "2010"; month: "Jul"; expenses: "3"; income: "7" }
+ ListElement{ year: "2010"; month: "Aug"; expenses: "1"; income: "5" }
+ ListElement{ year: "2010"; month: "Sep"; expenses: "2"; income: "4" }
+ ListElement{ year: "2010"; month: "Oct"; expenses: "10"; income: "13" }
+ ListElement{ year: "2010"; month: "Nov"; expenses: "12"; income: "17" }
+ ListElement{ year: "2010"; month: "Dec"; expenses: "6"; income: "9" }
+
+ ListElement{ year: "2011"; month: "Jan"; expenses: "2"; income: "6" }
+ ListElement{ year: "2011"; month: "Feb"; expenses: "4"; income: "8" }
+ ListElement{ year: "2011"; month: "Mar"; expenses: "7"; income: "12" }
+ ListElement{ year: "2011"; month: "Apr"; expenses: "9"; income: "15" }
+ ListElement{ year: "2011"; month: "May"; expenses: "7"; income: "19" }
+ ListElement{ year: "2011"; month: "Jun"; expenses: "9"; income: "18" }
+ ListElement{ year: "2011"; month: "Jul"; expenses: "13"; income: "17" }
+ ListElement{ year: "2011"; month: "Aug"; expenses: "5"; income: "9" }
+ ListElement{ year: "2011"; month: "Sep"; expenses: "3"; income: "8" }
+ ListElement{ year: "2011"; month: "Oct"; expenses: "13"; income: "15" }
+ ListElement{ year: "2011"; month: "Nov"; expenses: "8"; income: "17" }
+ ListElement{ year: "2011"; month: "Dec"; expenses: "7"; income: "10" }
+
+ ListElement{ year: "2012"; month: "Jan"; expenses: "12"; income: "16" }
+ ListElement{ year: "2012"; month: "Feb"; expenses: "24"; income: "28" }
+ ListElement{ year: "2012"; month: "Mar"; expenses: "27"; income: "22" }
+ ListElement{ year: "2012"; month: "Apr"; expenses: "29"; income: "25" }
+ ListElement{ year: "2012"; month: "May"; expenses: "27"; income: "29" }
+ ListElement{ year: "2012"; month: "Jun"; expenses: "19"; income: "18" }
+ ListElement{ year: "2012"; month: "Jul"; expenses: "13"; income: "17" }
+ ListElement{ year: "2012"; month: "Aug"; expenses: "15"; income: "19" }
+ ListElement{ year: "2012"; month: "Sep"; expenses: "3"; income: "8" }
+ ListElement{ year: "2012"; month: "Oct"; expenses: "3"; income: "6" }
+ ListElement{ year: "2012"; month: "Nov"; expenses: "4"; income: "8" }
+ ListElement{ year: "2012"; month: "Dec"; expenses: "5"; income: "9" }
+ }
+}
diff --git a/tests/qmlcamera/qml/qmlcamera/main.qml b/tests/qmlcamera/qml/qmlcamera/main.qml
new file mode 100644
index 00000000..72d2a45f
--- /dev/null
+++ b/tests/qmlcamera/qml/qmlcamera/main.qml
@@ -0,0 +1,150 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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.QtDataVisualization 1.0
+import "."
+
+Item {
+ id: mainview
+ width: 1280
+ height: 1024
+ visible: true
+
+ Data {
+ id: chartData
+ }
+
+ Axes {
+ id: chartAxes
+ }
+
+ Item {
+ id: dataView
+ width: parent.width - camControlArea.width
+ height: parent.height
+ anchors.right: parent.right;
+
+ Bars3D {
+ id: testChart
+ width: dataView.width
+ height: dataView.height
+ shadowQuality: Bars3D.ShadowQualityMedium
+ selectionMode: Bars3D.SelectionModeItem
+ font.pointSize: 35
+ theme: Bars3D.ThemeRetro
+ labelStyle: Bars3D.LabelStyleFromTheme
+ dataProxy: chartData.proxy
+ barThickness: 0.5
+ barSpacing: Qt.size(0.5, 0.5)
+ barSpacingRelative: false
+
+ columnAxis: chartAxes.column
+ valueAxis: chartAxes.expenses
+ itemLabelFormat: "@valueTitle for @colLabel, @rowLabel: @valueLabel"
+
+ onSelectedBarPosChanged: {
+ // Set camControlArea current row to selected bar
+ var rowRole = chartData.proxy.rowLabels[position.x];
+ var colRole = chartData.proxy.columnLabels[position.y];
+ }
+
+ // Bind UI controls to the camera
+ scene.activeCamera.wrapXRotation: false
+ scene.activeCamera.xRotation: camControlArea.xValue
+ scene.activeCamera.yRotation: camControlArea.yValue
+ scene.activeCamera.zoomLevel: zoomSlider.value
+ inputHandler: null
+ }
+ }
+
+ ControlSurface {
+ id: camControlArea
+ x: 0
+ y: 0
+ width: 298
+ height: 298
+ minXValue: testChart.scene.activeCamera.minXRotation
+ minYValue: testChart.scene.activeCamera.minYRotation
+ maxXValue: testChart.scene.activeCamera.maxXRotation
+ maxYValue: testChart.scene.activeCamera.maxYRotation
+ }
+
+ Slider {
+ id: zoomSlider
+ width: camControlArea.width
+ anchors.top: camControlArea.bottom
+ value: 100
+ minimumValue: 10
+ maximumValue: 300
+ }
+
+ Button {
+ id: mappingToggle
+ anchors.bottom: parent.bottom
+ width: camControlArea.width
+ text: "Show Income"
+ onClicked: {
+ if (chartData.mapping.valueRole === "expenses") {
+ chartData.mapping.valueRole = "income"
+ text = "Show Expenses"
+ testChart.valueAxis = chartAxes.income
+ } else {
+ chartData.mapping.valueRole = "expenses"
+ text = "Show Income"
+ testChart.valueAxis = chartAxes.expenses
+ }
+ }
+ }
+
+ Button {
+ id: shadowToggle
+ anchors.bottom: mappingToggle.top
+ width: camControlArea.width
+ text: "Hide Shadows"
+ onClicked: {
+ if (testChart.shadowQuality == Bars3D.ShadowQualityNone) {
+ testChart.shadowQuality = Bars3D.ShadowQualityMedium;
+ text = "Hide Shadows"
+ } else {
+ testChart.shadowQuality = Bars3D.ShadowQualityNone;
+ text = "Show Shadows"
+ }
+ }
+ }
+
+ Button {
+ id: dataToggle
+ anchors.bottom: shadowToggle.top
+ width: camControlArea.width
+ text: "Show 2010 - 2012"
+ onClicked: {
+ if (testChart.rowAxis.max !== 6) {
+ text = "Show 2010 - 2012"
+ chartData.mapping.autoRowCategories = true
+ } else {
+ text = "Show all years"
+ // Explicitly defining row categories, since we do not want to show data for
+ // all years in the model, just for the selected ones.
+ chartData.mapping.autoRowCategories = false
+ chartData.mapping.rowCategories = ["2010", "2011", "2012"]
+ }
+ }
+ }
+}
diff --git a/tests/qmlcamera/qmlcamera.desktop b/tests/qmlcamera/qmlcamera.desktop
new file mode 100644
index 00000000..10a0a2e7
--- /dev/null
+++ b/tests/qmlcamera/qmlcamera.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Version=1.0
+Type=Application
+Terminal=false
+Name=qmlcamera
+Exec=/opt/qmlcamera/bin/qmlcamera
+Icon=qmlcamera64
+X-Window-Icon=
+X-HildonDesk-ShowInToolbar=true
+X-Osso-Type=application/x-executable
diff --git a/examples/qmlbarchart/qmlbarchart.pro b/tests/qmlcamera/qmlcamera.pro
index ef609ef6..374dc012 100644
--- a/examples/qmlbarchart/qmlbarchart.pro
+++ b/tests/qmlcamera/qmlcamera.pro
@@ -1,9 +1,9 @@
-!include( ../examples.pri ) {
- error( "Couldn't find the examples.pri file!" )
+!include( ../tests.pri ) {
+ error( "Couldn't find the tests.pri file!" )
}
# Add more folders to ship with the application, here
-folder_01.source = qml/qmlbarchart
+folder_01.source = qml/qmlcamera
folder_01.target = qml
DEPLOYMENTFOLDERS = folder_01
@@ -26,4 +26,10 @@ include(qtquick2applicationviewer/qtquick2applicationviewer.pri)
qtcAddDeployment()
RESOURCES += \
- qmlbarchart.qrc
+ qmlcamera.qrc
+
+OTHER_FILES += \
+ qml/qmlcamera/Data.qml \
+ qml/qmlcamera/Axes.qml \
+ qml/qmlcamera/main.qml \
+ qml/qmlcamera/ControlSurface.qml
diff --git a/tests/qmlcamera/qmlcamera.qrc b/tests/qmlcamera/qmlcamera.qrc
new file mode 100644
index 00000000..d9b993c7
--- /dev/null
+++ b/tests/qmlcamera/qmlcamera.qrc
@@ -0,0 +1,7 @@
+<RCC>
+ <qresource prefix="/qml">
+ <file alias="main.qml">qml/qmlcamera/main.qml</file>
+ <file alias="Data.qml">qml/qmlcamera/Data.qml</file>
+ <file alias="Axes.qml">qml/qmlcamera/Axes.qml</file>
+ </qresource>
+</RCC>
diff --git a/tests/qmlcamera/qmlcamera64.png b/tests/qmlcamera/qmlcamera64.png
new file mode 100644
index 00000000..707d5c4e
--- /dev/null
+++ b/tests/qmlcamera/qmlcamera64.png
Binary files differ
diff --git a/tests/qmlcamera/qmlcamera80.png b/tests/qmlcamera/qmlcamera80.png
new file mode 100644
index 00000000..6ad8096c
--- /dev/null
+++ b/tests/qmlcamera/qmlcamera80.png
Binary files differ
diff --git a/tests/qmlcamera/qmlcamera_harmattan.desktop b/tests/qmlcamera/qmlcamera_harmattan.desktop
new file mode 100644
index 00000000..8e9e9857
--- /dev/null
+++ b/tests/qmlcamera/qmlcamera_harmattan.desktop
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Version=1.0
+Type=Application
+Terminal=false
+Name=qmlcamera
+Exec=/usr/bin/single-instance /opt/qmlcamera/bin/qmlcamera
+Icon=/usr/share/icons/hicolor/80x80/apps/qmlcamera80.png
+X-Window-Icon=
+X-HildonDesk-ShowInToolbar=true
+X-Osso-Type=application/x-executable
diff --git a/tests/qmlcamera/qtquick2applicationviewer/qtquick2applicationviewer.cpp b/tests/qmlcamera/qtquick2applicationviewer/qtquick2applicationviewer.cpp
new file mode 100644
index 00000000..10709d7a
--- /dev/null
+++ b/tests/qmlcamera/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/tests/qmlcamera/qtquick2applicationviewer/qtquick2applicationviewer.h b/tests/qmlcamera/qtquick2applicationviewer/qtquick2applicationviewer.h
new file mode 100644
index 00000000..cf66f140
--- /dev/null
+++ b/tests/qmlcamera/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/qmlbarchart/qtquick2applicationviewer/qtquick2applicationviewer.pri b/tests/qmlcamera/qtquick2applicationviewer/qtquick2applicationviewer.pri
index e5f7990f..e5f7990f 100644
--- a/examples/qmlbarchart/qtquick2applicationviewer/qtquick2applicationviewer.pri
+++ b/tests/qmlcamera/qtquick2applicationviewer/qtquick2applicationviewer.pri
diff --git a/examples/scatterchart/main.cpp b/tests/scattertest/main.cpp
index ab6eb313..35ba228d 100644
--- a/examples/scatterchart/main.cpp
+++ b/tests/scattertest/main.cpp
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -81,17 +81,20 @@ int main(int argc, char **argv)
insertBunchButton->setText(QStringLiteral("Insert bunch of items"));
QPushButton *changeOneButton = new QPushButton(widget);
- changeOneButton->setText(QStringLiteral("Change item"));
+ changeOneButton->setText(QStringLiteral("Change selected item"));
QPushButton *changeBunchButton = new QPushButton(widget);
changeBunchButton->setText(QStringLiteral("Change bunch of items"));
QPushButton *removeOneButton = new QPushButton(widget);
- removeOneButton->setText(QStringLiteral("Remove item"));
+ removeOneButton->setText(QStringLiteral("Remove selected item"));
QPushButton *removeBunchButton = new QPushButton(widget);
removeBunchButton->setText(QStringLiteral("Remove bunch of items"));
+ QPushButton *setSelectedItemButton = new QPushButton(widget);
+ setSelectedItemButton->setText(QStringLiteral("Select/deselect item 3"));
+
QPushButton *startTimerButton = new QPushButton(widget);
startTimerButton->setText(QStringLiteral("Start/stop timer"));
@@ -108,7 +111,10 @@ int main(int argc, char **argv)
shadowQuality->addItem(QStringLiteral("Low"));
shadowQuality->addItem(QStringLiteral("Medium"));
shadowQuality->addItem(QStringLiteral("High"));
- shadowQuality->setCurrentIndex(1);
+ shadowQuality->addItem(QStringLiteral("Low Soft"));
+ shadowQuality->addItem(QStringLiteral("Medium Soft"));
+ shadowQuality->addItem(QStringLiteral("High Soft"));
+ shadowQuality->setCurrentIndex(3);
QFontComboBox *fontList = new QFontComboBox(widget);
@@ -131,6 +137,7 @@ int main(int argc, char **argv)
vLayout->addWidget(changeBunchButton, 0, Qt::AlignTop);
vLayout->addWidget(removeOneButton, 0, Qt::AlignTop);
vLayout->addWidget(removeBunchButton, 0, Qt::AlignTop);
+ vLayout->addWidget(setSelectedItemButton, 0, Qt::AlignTop);
vLayout->addWidget(startTimerButton, 0, Qt::AlignTop);
vLayout->addWidget(backgroundCheckBox);
vLayout->addWidget(gridCheckBox);
@@ -170,12 +177,14 @@ int main(int argc, char **argv)
&ScatterDataModifier::removeOne);
QObject::connect(removeBunchButton, &QPushButton::clicked, modifier,
&ScatterDataModifier::removeBunch);
+ QObject::connect(setSelectedItemButton, &QPushButton::clicked, modifier,
+ &ScatterDataModifier::selectItem);
QObject::connect(startTimerButton, &QPushButton::clicked, modifier,
&ScatterDataModifier::startStopTimer);
QObject::connect(themeButton, &QPushButton::clicked, modifier,
&ScatterDataModifier::changeTheme);
QObject::connect(labelButton, &QPushButton::clicked, modifier,
- &ScatterDataModifier::changeTransparency);
+ &ScatterDataModifier::changeStyle);
QObject::connect(shadowQuality, SIGNAL(currentIndexChanged(int)), modifier,
SLOT(changeShadowQuality(int)));
@@ -183,6 +192,8 @@ int main(int argc, char **argv)
&QComboBox::setCurrentIndex);
QObject::connect(chart, &Q3DScatter::shadowQualityChanged, modifier,
&ScatterDataModifier::shadowQualityUpdatedByVisual);
+ QObject::connect(chart, &Q3DScatter::selectedItemIndexChanged, modifier,
+ &ScatterDataModifier::handleSelectionChange);
QObject::connect(fontList, &QFontComboBox::currentFontChanged, modifier,
&ScatterDataModifier::changeFont);
diff --git a/examples/scatterchart/scatterchart.cpp b/tests/scattertest/scatterchart.cpp
index ac8676b5..f23ee99d 100644
--- a/examples/scatterchart/scatterchart.cpp
+++ b/tests/scattertest/scatterchart.cpp
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -17,10 +17,12 @@
****************************************************************************/
#include "scatterchart.h"
-#include <QtDataVis3D/qscatterdataproxy.h>
-#include <QtDataVis3D/qvalueaxis.h>
+#include <QtDataVisualization/qscatterdataproxy.h>
+#include <QtDataVisualization/q3dvalueaxis.h>
+#include <QtDataVisualization/q3dscene.h>
+#include <QtDataVisualization/q3dcamera.h>
#include <qmath.h>
-using namespace QtDataVis3D;
+using namespace QtDataVisualization;
//#define RANDOM_SCATTER
@@ -28,15 +30,23 @@ const int numberOfItems = 10000;
ScatterDataModifier::ScatterDataModifier(Q3DScatter *scatter)
: m_chart(scatter),
- m_fontSize(30.0f)
+ m_fontSize(30.0f),
+ m_selectedItem(-1)
{
- m_chart->setFontSize(m_fontSize);
- m_chart->setObjectType(QDataVis::Spheres, true);
- m_chart->setTheme(QDataVis::ThemeBrownSand);
- m_chart->setShadowQuality(QDataVis::ShadowHigh);
+ QFont font = m_chart->font();
+ font.setPointSize(m_fontSize);
+ m_chart->setFont(font);
+ m_chart->setObjectType(QDataVis::MeshStyleSpheres, true);
+ m_chart->setTheme(QDataVis::ThemeStoneMoss);
+ m_chart->setShadowQuality(QDataVis::ShadowQualityHigh);
+ m_chart->scene()->activeCamera()->setCameraPreset(QDataVis::CameraPresetFront);
+ m_chart->setAxisX(new Q3DValueAxis);
+ m_chart->setAxisY(new Q3DValueAxis);
+ m_chart->setAxisZ(new Q3DValueAxis);
QScatterDataProxy *proxy = new QScatterDataProxy;
- m_chart->setDataProxy(proxy);
+ proxy->setItemLabelFormat("@xTitle: @xLabel @yTitle: @yLabel @zTitle: @zLabel");
+ m_chart->setActiveDataProxy(proxy);
connect(&m_timer, &QTimer::timeout, this, &ScatterDataModifier::timeout);
}
@@ -54,18 +64,18 @@ void ScatterDataModifier::start()
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);
+ m_chart->axisX()->setTitle("X");
+ m_chart->axisY()->setTitle("Y");
+ m_chart->axisZ()->setTitle("Z");
+ m_chart->axisX()->setRange(-50.0, 50.0);
+ m_chart->axisY()->setRange(-1.0, 1.0);
+ m_chart->axisZ()->setRange(-50.0, 50.0);
QScatterDataArray *dataArray = new QScatterDataArray;
dataArray->resize(numberOfItems);
QScatterDataItem *ptrToDataArray = &dataArray->first();
-#if RANDOM_SCATTER
+#ifdef RANDOM_SCATTER
for (int i = 0; i < numberOfItems; i++) {
ptrToDataArray->setPosition(randVector());
ptrToDataArray++;
@@ -80,7 +90,7 @@ void ScatterDataModifier::addData()
}
#endif
- static_cast<QScatterDataProxy *>(m_chart->dataProxy())->resetArray(dataArray);
+ static_cast<QScatterDataProxy *>(m_chart->activeDataProxy())->resetArray(dataArray);
}
void ScatterDataModifier::changeStyle()
@@ -88,16 +98,16 @@ void ScatterDataModifier::changeStyle()
static int model = 0;
switch (model) {
case 0:
- m_chart->setObjectType(QDataVis::Dots, false);
+ m_chart->setObjectType(QDataVis::MeshStyleDots, false);
break;
case 1:
- m_chart->setObjectType(QDataVis::Dots, true);
+ m_chart->setObjectType(QDataVis::MeshStyleDots, true);
break;
case 2:
- m_chart->setObjectType(QDataVis::Spheres, false);
+ m_chart->setObjectType(QDataVis::MeshStyleSpheres, false);
break;
case 3:
- m_chart->setObjectType(QDataVis::Spheres, true);
+ m_chart->setObjectType(QDataVis::MeshStyleSpheres, true);
break;
}
model++;
@@ -107,32 +117,32 @@ void ScatterDataModifier::changeStyle()
void ScatterDataModifier::changePresetCamera()
{
- static int preset = QDataVis::PresetFrontLow;
+ static int preset = QDataVis::CameraPresetFrontLow;
- m_chart->setCameraPreset((QDataVis::CameraPreset)preset);
+ m_chart->scene()->activeCamera()->setCameraPreset((QDataVis::CameraPreset)preset);
- if (++preset > QDataVis::PresetDirectlyAboveCCW45)
- preset = QDataVis::PresetFrontLow;
+ if (++preset > QDataVis::CameraPresetDirectlyAboveCCW45)
+ preset = QDataVis::CameraPresetFrontLow;
}
void ScatterDataModifier::changeTheme()
{
- static int theme = QDataVis::ThemeSystem;
+ static int theme = QDataVis::ThemeQt;
- m_chart->setTheme((QDataVis::ColorTheme)theme);
+ m_chart->setTheme((QDataVis::Theme)theme);
- if (++theme > QDataVis::ThemeLight)
- theme = QDataVis::ThemeSystem;
+ if (++theme > QDataVis::ThemeIsabelle)
+ theme = QDataVis::ThemeQt;
}
-void ScatterDataModifier::changeTransparency()
+void ScatterDataModifier::changeLabelStyle()
{
- static int transparency = QDataVis::TransparencyNone;
+ static int style = QDataVis::LabelStyleOpaque;
- m_chart->setLabelTransparency((QDataVis::LabelTransparency)transparency);
+ m_chart->setLabelStyle((QDataVis::LabelStyle)style);
- if (++transparency > QDataVis::TransparencyNoBackground)
- transparency = QDataVis::TransparencyNone;
+ if (++style > QDataVis::LabelStyleTransparent)
+ style = QDataVis::LabelStyleOpaque;
}
void ScatterDataModifier::changeFont(const QFont &font)
@@ -145,39 +155,29 @@ void ScatterDataModifier::changeFont(const QFont &font)
void ScatterDataModifier::changeFontSize(int fontsize)
{
m_fontSize = fontsize;
- m_chart->setFontSize((GLfloat)m_fontSize);
+ QFont font = m_chart->font();
+ font.setPointSize(m_fontSize);
+ m_chart->setFont(font);
}
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
+ int quality = int(sq);
+ // Updates the UI component to show correct shadow quality
emit shadowQualityChanged(quality);
}
void ScatterDataModifier::clear()
{
- m_chart->dataProxy()->resetArray(0);
+ m_chart->activeDataProxy()->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();
+ int addIndex = m_chart->activeDataProxy()->addItem(item);
+ qDebug() << m_loopCounter << "added one to index:" << addIndex << "array size:" << m_chart->activeDataProxy()->array()->size();
}
void ScatterDataModifier::addBunch()
@@ -185,15 +185,15 @@ 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();
+ int addIndex = m_chart->activeDataProxy()->addItems(items);
+ qDebug() << m_loopCounter << "added bunch to index:" << addIndex << "array size:" << m_chart->activeDataProxy()->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();
+ m_chart->activeDataProxy()->insertItem(0, item);
+ qDebug() << m_loopCounter << "Inserted one, array size:" << m_chart->activeDataProxy()->array()->size();
}
void ScatterDataModifier::insertBunch()
@@ -201,41 +201,43 @@ 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();
+ m_chart->activeDataProxy()->insertItems(0, items);
+ qDebug() << m_loopCounter << "Inserted bunch, array size:" << m_chart->activeDataProxy()->array()->size();
}
void ScatterDataModifier::changeOne()
{
- if (m_chart->dataProxy()->array()->size()) {
+ if (m_selectedItem >= 0 && m_chart->activeDataProxy()->array()->size()) {
QScatterDataItem item(randVector());
- m_chart->dataProxy()->setItem(0, item);
- qDebug() << m_loopCounter << "Changed one, array size:" << m_chart->dataProxy()->array()->size();
+ m_chart->activeDataProxy()->setItem(m_selectedItem, item);
+ qDebug() << m_loopCounter << "Changed one, array size:" << m_chart->activeDataProxy()->array()->size();
}
}
void ScatterDataModifier::changeBunch()
{
- if (m_chart->dataProxy()->array()->size()) {
- int amount = qMin(m_chart->dataProxy()->array()->size(), 100);
+ if (m_chart->activeDataProxy()->array()->size()) {
+ int amount = qMin(m_chart->activeDataProxy()->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();
+ m_chart->activeDataProxy()->setItems(0, items);
+ qDebug() << m_loopCounter << "Changed bunch, array size:" << m_chart->activeDataProxy()->array()->size();
}
}
void ScatterDataModifier::removeOne()
{
- m_chart->dataProxy()->removeItems(0, 1);
- qDebug() << m_loopCounter << "Removed one, array size:" << m_chart->dataProxy()->array()->size();
+ if (m_selectedItem >= 0) {
+ m_chart->activeDataProxy()->removeItems(m_selectedItem, 1);
+ qDebug() << m_loopCounter << "Removed one, array size:" << m_chart->activeDataProxy()->array()->size();
+ }
}
void ScatterDataModifier::removeBunch()
{
- m_chart->dataProxy()->removeItems(0, 100);
- qDebug() << m_loopCounter << "Removed bunch, array size:" << m_chart->dataProxy()->array()->size();
+ m_chart->activeDataProxy()->removeItems(0, 100);
+ qDebug() << m_loopCounter << "Removed bunch, array size:" << m_chart->activeDataProxy()->array()->size();
}
void ScatterDataModifier::timeout()
@@ -288,20 +290,25 @@ void ScatterDataModifier::startStopTimer()
}
}
+void ScatterDataModifier::selectItem()
+{
+ int targetItem(3);
+ int noSelection(-1);
+ if (m_selectedItem != targetItem)
+ m_chart->setSelectedItemIndex(targetItem);
+ else
+ m_chart->setSelectedItemIndex(noSelection);
+}
+
+void ScatterDataModifier::handleSelectionChange(int index)
+{
+ m_selectedItem = index;
+ qDebug() << "Selected item index:" << index;
+}
+
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;
- }
+ QDataVis::ShadowQuality sq = QDataVis::ShadowQuality(quality);
m_chart->setShadowQuality(sq);
emit shadowQualityChanged(quality);
}
diff --git a/examples/scatterchart/scatterchart.h b/tests/scattertest/scatterchart.h
index 8500ef29..7132e7ce 100644
--- a/examples/scatterchart/scatterchart.h
+++ b/tests/scattertest/scatterchart.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -19,13 +19,13 @@
#ifndef SCATTERDATAMODIFIER_H
#define SCATTERDATAMODIFIER_H
-#include <QtDataVis3D/q3dscatter.h>
+#include <QtDataVisualization/q3dscatter.h>
#include <QFont>
#include <QDebug>
#include <QTimer>
-using namespace QtDataVis3D;
+using namespace QtDataVisualization;
class ScatterDataModifier : public QObject
{
@@ -38,7 +38,7 @@ public:
void changeStyle();
void changePresetCamera();
void changeTheme();
- void changeTransparency();
+ void changeLabelStyle();
void changeFont(const QFont &font);
void changeFontSize(int fontsize);
void setBackgroundEnabled(int enabled);
@@ -59,6 +59,8 @@ public slots:
void removeBunch();
void timeout();
void startStopTimer();
+ void selectItem();
+ void handleSelectionChange(int index);
signals:
void shadowQualityChanged(int quality);
@@ -69,6 +71,7 @@ private:
int m_fontSize;
QTimer m_timer;
int m_loopCounter;
+ int m_selectedItem;
};
#endif
diff --git a/examples/scatterchart/scatterchart.pro b/tests/scattertest/scattertest.pro
index 5dee59fd..62fb3d39 100644
--- a/examples/scatterchart/scatterchart.pro
+++ b/tests/scattertest/scattertest.pro
@@ -1,5 +1,5 @@
-!include( ../examples.pri ) {
- error( "Couldn't find the examples.pri file!" )
+!include( ../tests.pri ) {
+ error( "Couldn't find the tests.pri file!" )
}
SOURCES += main.cpp scatterchart.cpp
diff --git a/examples/spectrum/3rdparty/fftreal/Array.h b/tests/spectrum/3rdparty/fftreal/Array.h
index a08e3cf2..a08e3cf2 100644
--- a/examples/spectrum/3rdparty/fftreal/Array.h
+++ b/tests/spectrum/3rdparty/fftreal/Array.h
diff --git a/examples/spectrum/3rdparty/fftreal/Array.hpp b/tests/spectrum/3rdparty/fftreal/Array.hpp
index 8300077e..8300077e 100644
--- a/examples/spectrum/3rdparty/fftreal/Array.hpp
+++ b/tests/spectrum/3rdparty/fftreal/Array.hpp
diff --git a/examples/spectrum/3rdparty/fftreal/DynArray.h b/tests/spectrum/3rdparty/fftreal/DynArray.h
index 8041a0c1..8041a0c1 100644
--- a/examples/spectrum/3rdparty/fftreal/DynArray.h
+++ b/tests/spectrum/3rdparty/fftreal/DynArray.h
diff --git a/examples/spectrum/3rdparty/fftreal/DynArray.hpp b/tests/spectrum/3rdparty/fftreal/DynArray.hpp
index e62b10f8..e62b10f8 100644
--- a/examples/spectrum/3rdparty/fftreal/DynArray.hpp
+++ b/tests/spectrum/3rdparty/fftreal/DynArray.hpp
diff --git a/examples/spectrum/3rdparty/fftreal/FFTReal.dsp b/tests/spectrum/3rdparty/fftreal/FFTReal.dsp
index fe970db0..fe970db0 100644
--- a/examples/spectrum/3rdparty/fftreal/FFTReal.dsp
+++ b/tests/spectrum/3rdparty/fftreal/FFTReal.dsp
diff --git a/examples/spectrum/3rdparty/fftreal/FFTReal.dsw b/tests/spectrum/3rdparty/fftreal/FFTReal.dsw
index 076b0aeb..076b0aeb 100644
--- a/examples/spectrum/3rdparty/fftreal/FFTReal.dsw
+++ b/tests/spectrum/3rdparty/fftreal/FFTReal.dsw
diff --git a/examples/spectrum/3rdparty/fftreal/FFTReal.h b/tests/spectrum/3rdparty/fftreal/FFTReal.h
index 9fb27250..9fb27250 100644
--- a/examples/spectrum/3rdparty/fftreal/FFTReal.h
+++ b/tests/spectrum/3rdparty/fftreal/FFTReal.h
diff --git a/examples/spectrum/3rdparty/fftreal/FFTReal.hpp b/tests/spectrum/3rdparty/fftreal/FFTReal.hpp
index 335d771d..335d771d 100644
--- a/examples/spectrum/3rdparty/fftreal/FFTReal.hpp
+++ b/tests/spectrum/3rdparty/fftreal/FFTReal.hpp
diff --git a/examples/spectrum/3rdparty/fftreal/FFTRealFixLen.h b/tests/spectrum/3rdparty/fftreal/FFTRealFixLen.h
index 0b802668..0b802668 100644
--- a/examples/spectrum/3rdparty/fftreal/FFTRealFixLen.h
+++ b/tests/spectrum/3rdparty/fftreal/FFTRealFixLen.h
diff --git a/examples/spectrum/3rdparty/fftreal/FFTRealFixLen.hpp b/tests/spectrum/3rdparty/fftreal/FFTRealFixLen.hpp
index 6defb009..6defb009 100644
--- a/examples/spectrum/3rdparty/fftreal/FFTRealFixLen.hpp
+++ b/tests/spectrum/3rdparty/fftreal/FFTRealFixLen.hpp
diff --git a/examples/spectrum/3rdparty/fftreal/FFTRealFixLenParam.h b/tests/spectrum/3rdparty/fftreal/FFTRealFixLenParam.h
index 163c0832..163c0832 100644
--- a/examples/spectrum/3rdparty/fftreal/FFTRealFixLenParam.h
+++ b/tests/spectrum/3rdparty/fftreal/FFTRealFixLenParam.h
diff --git a/examples/spectrum/3rdparty/fftreal/FFTRealPassDirect.h b/tests/spectrum/3rdparty/fftreal/FFTRealPassDirect.h
index 7d19c02e..7d19c02e 100644
--- a/examples/spectrum/3rdparty/fftreal/FFTRealPassDirect.h
+++ b/tests/spectrum/3rdparty/fftreal/FFTRealPassDirect.h
diff --git a/examples/spectrum/3rdparty/fftreal/FFTRealPassDirect.hpp b/tests/spectrum/3rdparty/fftreal/FFTRealPassDirect.hpp
index db9d568e..db9d568e 100644
--- a/examples/spectrum/3rdparty/fftreal/FFTRealPassDirect.hpp
+++ b/tests/spectrum/3rdparty/fftreal/FFTRealPassDirect.hpp
diff --git a/examples/spectrum/3rdparty/fftreal/FFTRealPassInverse.h b/tests/spectrum/3rdparty/fftreal/FFTRealPassInverse.h
index 2de89527..2de89527 100644
--- a/examples/spectrum/3rdparty/fftreal/FFTRealPassInverse.h
+++ b/tests/spectrum/3rdparty/fftreal/FFTRealPassInverse.h
diff --git a/examples/spectrum/3rdparty/fftreal/FFTRealPassInverse.hpp b/tests/spectrum/3rdparty/fftreal/FFTRealPassInverse.hpp
index 57375469..57375469 100644
--- a/examples/spectrum/3rdparty/fftreal/FFTRealPassInverse.hpp
+++ b/tests/spectrum/3rdparty/fftreal/FFTRealPassInverse.hpp
diff --git a/examples/spectrum/3rdparty/fftreal/FFTRealSelect.h b/tests/spectrum/3rdparty/fftreal/FFTRealSelect.h
index bd722d4d..bd722d4d 100644
--- a/examples/spectrum/3rdparty/fftreal/FFTRealSelect.h
+++ b/tests/spectrum/3rdparty/fftreal/FFTRealSelect.h
diff --git a/examples/spectrum/3rdparty/fftreal/FFTRealSelect.hpp b/tests/spectrum/3rdparty/fftreal/FFTRealSelect.hpp
index 9ddf5864..9ddf5864 100644
--- a/examples/spectrum/3rdparty/fftreal/FFTRealSelect.hpp
+++ b/tests/spectrum/3rdparty/fftreal/FFTRealSelect.hpp
diff --git a/examples/spectrum/3rdparty/fftreal/FFTRealUseTrigo.h b/tests/spectrum/3rdparty/fftreal/FFTRealUseTrigo.h
index c4368ee0..c4368ee0 100644
--- a/examples/spectrum/3rdparty/fftreal/FFTRealUseTrigo.h
+++ b/tests/spectrum/3rdparty/fftreal/FFTRealUseTrigo.h
diff --git a/examples/spectrum/3rdparty/fftreal/FFTRealUseTrigo.hpp b/tests/spectrum/3rdparty/fftreal/FFTRealUseTrigo.hpp
index aa968b81..aa968b81 100644
--- a/examples/spectrum/3rdparty/fftreal/FFTRealUseTrigo.hpp
+++ b/tests/spectrum/3rdparty/fftreal/FFTRealUseTrigo.hpp
diff --git a/examples/spectrum/3rdparty/fftreal/OscSinCos.h b/tests/spectrum/3rdparty/fftreal/OscSinCos.h
index 775fc14f..775fc14f 100644
--- a/examples/spectrum/3rdparty/fftreal/OscSinCos.h
+++ b/tests/spectrum/3rdparty/fftreal/OscSinCos.h
diff --git a/examples/spectrum/3rdparty/fftreal/OscSinCos.hpp b/tests/spectrum/3rdparty/fftreal/OscSinCos.hpp
index 749aef04..749aef04 100644
--- a/examples/spectrum/3rdparty/fftreal/OscSinCos.hpp
+++ b/tests/spectrum/3rdparty/fftreal/OscSinCos.hpp
diff --git a/examples/spectrum/3rdparty/fftreal/TestAccuracy.h b/tests/spectrum/3rdparty/fftreal/TestAccuracy.h
index 4b07a6b6..4b07a6b6 100644
--- a/examples/spectrum/3rdparty/fftreal/TestAccuracy.h
+++ b/tests/spectrum/3rdparty/fftreal/TestAccuracy.h
diff --git a/examples/spectrum/3rdparty/fftreal/TestAccuracy.hpp b/tests/spectrum/3rdparty/fftreal/TestAccuracy.hpp
index 5c794f74..5c794f74 100644
--- a/examples/spectrum/3rdparty/fftreal/TestAccuracy.hpp
+++ b/tests/spectrum/3rdparty/fftreal/TestAccuracy.hpp
diff --git a/examples/spectrum/3rdparty/fftreal/TestHelperFixLen.h b/tests/spectrum/3rdparty/fftreal/TestHelperFixLen.h
index ecff96d3..ecff96d3 100644
--- a/examples/spectrum/3rdparty/fftreal/TestHelperFixLen.h
+++ b/tests/spectrum/3rdparty/fftreal/TestHelperFixLen.h
diff --git a/examples/spectrum/3rdparty/fftreal/TestHelperFixLen.hpp b/tests/spectrum/3rdparty/fftreal/TestHelperFixLen.hpp
index 25048b91..25048b91 100644
--- a/examples/spectrum/3rdparty/fftreal/TestHelperFixLen.hpp
+++ b/tests/spectrum/3rdparty/fftreal/TestHelperFixLen.hpp
diff --git a/examples/spectrum/3rdparty/fftreal/TestHelperNormal.h b/tests/spectrum/3rdparty/fftreal/TestHelperNormal.h
index a7bff5c2..a7bff5c2 100644
--- a/examples/spectrum/3rdparty/fftreal/TestHelperNormal.h
+++ b/tests/spectrum/3rdparty/fftreal/TestHelperNormal.h
diff --git a/examples/spectrum/3rdparty/fftreal/TestHelperNormal.hpp b/tests/spectrum/3rdparty/fftreal/TestHelperNormal.hpp
index e037696a..e037696a 100644
--- a/examples/spectrum/3rdparty/fftreal/TestHelperNormal.hpp
+++ b/tests/spectrum/3rdparty/fftreal/TestHelperNormal.hpp
diff --git a/examples/spectrum/3rdparty/fftreal/TestSpeed.h b/tests/spectrum/3rdparty/fftreal/TestSpeed.h
index 22957818..22957818 100644
--- a/examples/spectrum/3rdparty/fftreal/TestSpeed.h
+++ b/tests/spectrum/3rdparty/fftreal/TestSpeed.h
diff --git a/examples/spectrum/3rdparty/fftreal/TestSpeed.hpp b/tests/spectrum/3rdparty/fftreal/TestSpeed.hpp
index e716b2a7..e716b2a7 100644
--- a/examples/spectrum/3rdparty/fftreal/TestSpeed.hpp
+++ b/tests/spectrum/3rdparty/fftreal/TestSpeed.hpp
diff --git a/examples/spectrum/3rdparty/fftreal/TestWhiteNoiseGen.h b/tests/spectrum/3rdparty/fftreal/TestWhiteNoiseGen.h
index d815f8e3..d815f8e3 100644
--- a/examples/spectrum/3rdparty/fftreal/TestWhiteNoiseGen.h
+++ b/tests/spectrum/3rdparty/fftreal/TestWhiteNoiseGen.h
diff --git a/examples/spectrum/3rdparty/fftreal/TestWhiteNoiseGen.hpp b/tests/spectrum/3rdparty/fftreal/TestWhiteNoiseGen.hpp
index 13b7eb3e..13b7eb3e 100644
--- a/examples/spectrum/3rdparty/fftreal/TestWhiteNoiseGen.hpp
+++ b/tests/spectrum/3rdparty/fftreal/TestWhiteNoiseGen.hpp
diff --git a/examples/spectrum/3rdparty/fftreal/def.h b/tests/spectrum/3rdparty/fftreal/def.h
index 99c545f5..99c545f5 100644
--- a/examples/spectrum/3rdparty/fftreal/def.h
+++ b/tests/spectrum/3rdparty/fftreal/def.h
diff --git a/examples/spectrum/3rdparty/fftreal/fftreal.pas b/tests/spectrum/3rdparty/fftreal/fftreal.pas
index ea637545..ea637545 100644
--- a/examples/spectrum/3rdparty/fftreal/fftreal.pas
+++ b/tests/spectrum/3rdparty/fftreal/fftreal.pas
diff --git a/examples/spectrum/3rdparty/fftreal/fftreal.pro b/tests/spectrum/3rdparty/fftreal/fftreal.pro
index f6abeeb1..f6abeeb1 100644
--- a/examples/spectrum/3rdparty/fftreal/fftreal.pro
+++ b/tests/spectrum/3rdparty/fftreal/fftreal.pro
diff --git a/examples/spectrum/3rdparty/fftreal/fftreal_wrapper.cpp b/tests/spectrum/3rdparty/fftreal/fftreal_wrapper.cpp
index 45aee653..f6fc37e0 100644
--- a/examples/spectrum/3rdparty/fftreal/fftreal_wrapper.cpp
+++ b/tests/spectrum/3rdparty/fftreal/fftreal_wrapper.cpp
@@ -3,7 +3,7 @@
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
-** This file is part of the examples of QtDataVis3D.
+** This file is part of the examples of QtDataVisualization.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as
diff --git a/examples/spectrum/3rdparty/fftreal/fftreal_wrapper.h b/tests/spectrum/3rdparty/fftreal/fftreal_wrapper.h
index 2fb602de..4cfa580b 100644
--- a/examples/spectrum/3rdparty/fftreal/fftreal_wrapper.h
+++ b/tests/spectrum/3rdparty/fftreal/fftreal_wrapper.h
@@ -3,7 +3,7 @@
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
-** This file is part of the examples of QtDataVis3D.
+** This file is part of the examples of QtDataVisualization.
**
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Lesser General Public License as
diff --git a/examples/spectrum/3rdparty/fftreal/license.txt b/tests/spectrum/3rdparty/fftreal/license.txt
index 918fe68e..918fe68e 100644
--- a/examples/spectrum/3rdparty/fftreal/license.txt
+++ b/tests/spectrum/3rdparty/fftreal/license.txt
diff --git a/examples/spectrum/3rdparty/fftreal/readme.txt b/tests/spectrum/3rdparty/fftreal/readme.txt
index 0c5ce162..0c5ce162 100644
--- a/examples/spectrum/3rdparty/fftreal/readme.txt
+++ b/tests/spectrum/3rdparty/fftreal/readme.txt
diff --git a/examples/spectrum/3rdparty/fftreal/test.cpp b/tests/spectrum/3rdparty/fftreal/test.cpp
index 7b6ed2ca..7b6ed2ca 100644
--- a/examples/spectrum/3rdparty/fftreal/test.cpp
+++ b/tests/spectrum/3rdparty/fftreal/test.cpp
diff --git a/examples/spectrum/3rdparty/fftreal/test_fnc.h b/tests/spectrum/3rdparty/fftreal/test_fnc.h
index 26221566..26221566 100644
--- a/examples/spectrum/3rdparty/fftreal/test_fnc.h
+++ b/tests/spectrum/3rdparty/fftreal/test_fnc.h
diff --git a/examples/spectrum/3rdparty/fftreal/test_fnc.hpp b/tests/spectrum/3rdparty/fftreal/test_fnc.hpp
index 4b5f9f59..4b5f9f59 100644
--- a/examples/spectrum/3rdparty/fftreal/test_fnc.hpp
+++ b/tests/spectrum/3rdparty/fftreal/test_fnc.hpp
diff --git a/examples/spectrum/3rdparty/fftreal/test_settings.h b/tests/spectrum/3rdparty/fftreal/test_settings.h
index b893afc8..b893afc8 100644
--- a/examples/spectrum/3rdparty/fftreal/test_settings.h
+++ b/tests/spectrum/3rdparty/fftreal/test_settings.h
diff --git a/examples/spectrum/3rdparty/fftreal/testapp.dpr b/tests/spectrum/3rdparty/fftreal/testapp.dpr
index 54f2eb99..54f2eb99 100644
--- a/examples/spectrum/3rdparty/fftreal/testapp.dpr
+++ b/tests/spectrum/3rdparty/fftreal/testapp.dpr
diff --git a/examples/spectrum/README.txt b/tests/spectrum/README.txt
index c39d4a70..c39d4a70 100644
--- a/examples/spectrum/README.txt
+++ b/tests/spectrum/README.txt
diff --git a/examples/spectrum/spectrum.pri b/tests/spectrum/spectrum.pri
index 31a3767c..31a3767c 100644
--- a/examples/spectrum/spectrum.pri
+++ b/tests/spectrum/spectrum.pri
diff --git a/examples/spectrum/spectrum.pro b/tests/spectrum/spectrum.pro
index 9a8d45ae..2f44bfac 100644
--- a/examples/spectrum/spectrum.pro
+++ b/tests/spectrum/spectrum.pro
@@ -1,4 +1,7 @@
qtHaveModule(multimedia) {
+!include( ../tests.pri ) {
+ error( "Couldn't find the tests.pri file!" )
+}
include(spectrum.pri)
TEMPLATE = subdirs
diff --git a/examples/spectrum/spectrumapp/engine.cpp b/tests/spectrum/spectrumapp/engine.cpp
index c23a4f78..9d049384 100644
--- a/examples/spectrum/spectrumapp/engine.cpp
+++ b/tests/spectrum/spectrumapp/engine.cpp
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -81,6 +81,12 @@ Engine::Engine(QObject *parent)
SLOT(spectrumChanged(FrequencySpectrum)));
initialize();
+ qDebug() << "output devices:";
+ foreach (QAudioDeviceInfo device, m_availableAudioOutputDevices)
+ qDebug() << device.deviceName();
+ qDebug() << "input devices:";
+ foreach (QAudioDeviceInfo device, m_availableAudioInputDevices)
+ qDebug() << device.deviceName();
}
Engine::~Engine()
diff --git a/examples/spectrum/spectrumapp/engine.h b/tests/spectrum/spectrumapp/engine.h
index cdd8373f..1ad86065 100644
--- a/examples/spectrum/spectrumapp/engine.h
+++ b/tests/spectrum/spectrumapp/engine.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
diff --git a/examples/spectrum/spectrumapp/frequencyspectrum.cpp b/tests/spectrum/spectrumapp/frequencyspectrum.cpp
index 013d0454..c5f62cef 100644
--- a/examples/spectrum/spectrumapp/frequencyspectrum.cpp
+++ b/tests/spectrum/spectrumapp/frequencyspectrum.cpp
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
diff --git a/examples/spectrum/spectrumapp/frequencyspectrum.h b/tests/spectrum/spectrumapp/frequencyspectrum.h
index fac9a1b7..0008985f 100644
--- a/examples/spectrum/spectrumapp/frequencyspectrum.h
+++ b/tests/spectrum/spectrumapp/frequencyspectrum.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
diff --git a/examples/spectrum/spectrumapp/main.cpp b/tests/spectrum/spectrumapp/main.cpp
index d0333e75..3d2e2bf1 100644
--- a/examples/spectrum/spectrumapp/main.cpp
+++ b/tests/spectrum/spectrumapp/main.cpp
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
@@ -19,9 +19,12 @@
#include "engine.h"
#include "utils.h"
-#include <QtDataVis3D/q3dbars.h>
-#include <QtDataVis3D/qbardataproxy.h>
-#include <QtDataVis3D/qvalueaxis.h>
+#include <QtDataVisualization/q3dbars.h>
+#include <QtDataVisualization/qbardataproxy.h>
+#include <QtDataVisualization/q3dvalueaxis.h>
+#include <QtDataVisualization/q3dcategoryaxis.h>
+#include <QtDataVisualization/q3dscene.h>
+#include <QtDataVisualization/q3dcamera.h>
#include <QGuiApplication>
#include <QAudio>
@@ -29,7 +32,7 @@
//#define USE_CONES
-using namespace QtDataVis3D;
+using namespace QtDataVisualization;
class MainApp : public QObject
{
@@ -66,43 +69,44 @@ MainApp::MainApp(Q3DBars *window)
m_lowFreq(SpectrumLowFreq),
m_highFreq(SpectrumHighFreq)
{
- m_chart->setupSampleSpace(SpectrumNumBands * 2, SpectrumNumBands);
+ m_chart->rowAxis()->setMax(SpectrumNumBands * 2);
+ m_chart->columnAxis()->setMax(SpectrumNumBands - 1);
// Disable grid
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(QDataVis::ShadowNone);
+ m_chart->setShadowQuality(QDataVis::ShadowQualityNone);
#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));
+ m_chart->setBarThickness(1.25);
+ m_chart->setBarSpacing(QSizeF(0.2, -0.75));
// Set bar type, smooth cones
- m_chart->setBarType(QDataVis::Cones, true);
+ m_chart->setBarType(QDataVis::MeshStyleCones, true);
// Adjust zoom manually; automatic zoom level calculation does not work well with negative
- // spacings (in setBarSpecs)
+ // spacings (in setBarSpacing)
m_chart->setCameraPosition(10.0f, 5.0f, 70);
#else
// 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));
+ m_chart->setBarThickness(2.0);
+ m_chart->setBarSpacing(QSizeF(0.0, 0.0));
// Set bar type, flat bars
- m_chart->setBarType(QDataVis::Bars, false);
+ m_chart->setBarType(QDataVis::MeshStyleBars, false);
// Adjust camera position
- m_chart->setCameraPosition(10.0f, 7.5f, 75);
+ m_chart->scene()->activeCamera()->setCameraPosition(10.0f, 7.5f, 75);
#endif
// Set color scheme
- m_chart->setBarColor(QColor(Qt::black), QColor(Qt::red), QColor(Qt::darkYellow));
+ m_chart->setBarColor(QColor(Qt::red), false);
// Disable selection
- m_chart->setSelectionMode(QDataVis::ModeNone);
+ m_chart->setSelectionMode(QDataVis::SelectionModeNone);
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);
+ m_chart->setActiveDataProxy(proxy);
}
MainApp::~MainApp()
@@ -139,7 +143,7 @@ void MainApp::spectrumChanged(qint64 position, qint64 length, const FrequencySpe
(*data)[barIndex(e.frequency)].setValue(qMax(data->at(barIndex(e.frequency)).value(), qreal(e.amplitude)));
}
}
- static_cast<QBarDataProxy *>(m_chart->dataProxy())->insertRow(0, data);
+ static_cast<QBarDataProxy *>(m_chart->activeDataProxy())->insertRow(0, data);
}
void MainApp::stateChanged(QAudio::Mode mode, QAudio::State state)
@@ -190,7 +194,7 @@ int MainApp::barIndex(qreal frequency) const
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
- app.setApplicationName("QtDataVis3D spectrum analyzer");
+ app.setApplicationName("QtDataVisualization spectrum analyzer");
Q3DBars window;
window.resize(1024, 768);
diff --git a/examples/spectrum/spectrumapp/soundFiles/Rockhop.wav b/tests/spectrum/spectrumapp/soundFiles/Rockhop.wav
index e56e1c0f..e56e1c0f 100644
--- a/examples/spectrum/spectrumapp/soundFiles/Rockhop.wav
+++ b/tests/spectrum/spectrumapp/soundFiles/Rockhop.wav
Binary files differ
diff --git a/examples/spectrum/spectrumapp/soundFiles/futurebells_beat.wav b/tests/spectrum/spectrumapp/soundFiles/futurebells_beat.wav
index c45cbc71..c45cbc71 100644
--- a/examples/spectrum/spectrumapp/soundFiles/futurebells_beat.wav
+++ b/tests/spectrum/spectrumapp/soundFiles/futurebells_beat.wav
Binary files differ
diff --git a/examples/spectrum/spectrumapp/soundFiles/onclassical_demo_fiati-di-parma_thuille_terzo-tempo_sestetto_small-version.wav b/tests/spectrum/spectrumapp/soundFiles/onclassical_demo_fiati-di-parma_thuille_terzo-tempo_sestetto_small-version.wav
index 78b8dbda..78b8dbda 100644
--- a/examples/spectrum/spectrumapp/soundFiles/onclassical_demo_fiati-di-parma_thuille_terzo-tempo_sestetto_small-version.wav
+++ b/tests/spectrum/spectrumapp/soundFiles/onclassical_demo_fiati-di-parma_thuille_terzo-tempo_sestetto_small-version.wav
Binary files differ
diff --git a/examples/spectrum/spectrumapp/spectrum.h b/tests/spectrum/spectrumapp/spectrum.h
index 015989d5..97096b1c 100644
--- a/examples/spectrum/spectrumapp/spectrum.h
+++ b/tests/spectrum/spectrumapp/spectrum.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
diff --git a/examples/spectrum/spectrumapp/spectrum.qrc b/tests/spectrum/spectrumapp/spectrum.qrc
index 9368abc7..9368abc7 100644
--- a/examples/spectrum/spectrumapp/spectrum.qrc
+++ b/tests/spectrum/spectrumapp/spectrum.qrc
diff --git a/examples/spectrum/spectrumapp/spectrumanalyser.cpp b/tests/spectrum/spectrumapp/spectrumanalyser.cpp
index 4cebfde9..b86a851c 100644
--- a/examples/spectrum/spectrumapp/spectrumanalyser.cpp
+++ b/tests/spectrum/spectrumapp/spectrumanalyser.cpp
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
diff --git a/examples/spectrum/spectrumapp/spectrumanalyser.h b/tests/spectrum/spectrumapp/spectrumanalyser.h
index 6d9291ef..0e40fe66 100644
--- a/examples/spectrum/spectrumapp/spectrumanalyser.h
+++ b/tests/spectrum/spectrumapp/spectrumanalyser.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
diff --git a/examples/spectrum/spectrumapp/spectrumapp.pro b/tests/spectrum/spectrumapp/spectrumapp.pro
index c2455f78..940cce75 100644
--- a/examples/spectrum/spectrumapp/spectrumapp.pro
+++ b/tests/spectrum/spectrumapp/spectrumapp.pro
@@ -1,5 +1,5 @@
-!include( ../../examples.pri ) {
- error( "Couldn't find the examples.pri file!" )
+!include( ../../tests.pri ) {
+ error( "Couldn't find the tests.pri file!" )
}
!include( ../spectrum.pri ) {
@@ -50,7 +50,7 @@ RESOURCES = spectrum.qrc
android {
target.path = /libs/$$ANDROID_TARGET_ARCH
} else {
- target.path = $$[QT_INSTALL_EXAMPLES]/datavis3d/spectrum
+ target.path = $$[QT_INSTALL_EXAMPLES]/datavisualization/spectrum
}
INSTALLS += target
diff --git a/examples/spectrum/spectrumapp/utils.cpp b/tests/spectrum/spectrumapp/utils.cpp
index bad6cc48..f007959c 100644
--- a/examples/spectrum/spectrumapp/utils.cpp
+++ b/tests/spectrum/spectrumapp/utils.cpp
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
diff --git a/examples/spectrum/spectrumapp/utils.h b/tests/spectrum/spectrumapp/utils.h
index f0ae5633..009f895b 100644
--- a/examples/spectrum/spectrumapp/utils.h
+++ b/tests/spectrum/spectrumapp/utils.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
diff --git a/examples/spectrum/spectrumapp/wavfile.cpp b/tests/spectrum/spectrumapp/wavfile.cpp
index 24482507..56dd340e 100644
--- a/examples/spectrum/spectrumapp/wavfile.cpp
+++ b/tests/spectrum/spectrumapp/wavfile.cpp
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
diff --git a/examples/spectrum/spectrumapp/wavfile.h b/tests/spectrum/spectrumapp/wavfile.h
index e408911b..25673630 100644
--- a/examples/spectrum/spectrumapp/wavfile.h
+++ b/tests/spectrum/spectrumapp/wavfile.h
@@ -4,7 +4,7 @@
** 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.
+** This file is part of the QtDataVisualization module.
**
** Licensees holding valid Qt Enterprise licenses may use this file in
** accordance with the Qt Enterprise License Agreement provided with the
diff --git a/tests/surfacetest/Heightmap.png b/tests/surfacetest/Heightmap.png
new file mode 100644
index 00000000..2a860111
--- /dev/null
+++ b/tests/surfacetest/Heightmap.png
Binary files differ
diff --git a/tests/surfacetest/graphmodifier.cpp b/tests/surfacetest/graphmodifier.cpp
new file mode 100644
index 00000000..d4e99031
--- /dev/null
+++ b/tests/surfacetest/graphmodifier.cpp
@@ -0,0 +1,388 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 "graphmodifier.h"
+#include <QtDataVisualization/Q3DValueAxis>
+#include <QtDataVisualization/QSurfaceDataProxy>
+
+#include <qmath.h>
+#include <QLinearGradient>
+#include <QDebug>
+
+QT_DATAVISUALIZATION_USE_NAMESPACE
+
+//#define JITTER_PLANE
+//#define WONKY_PLANE
+
+GraphModifier::GraphModifier(Q3DSurface *graph)
+ : m_graph(graph),
+ m_gridSliderX(0),
+ m_gridSliderZ(0),
+ m_axisRangeSliderX(0),
+ m_axisRangeSliderZ(0),
+ m_axisMinSliderX(0),
+ m_axisMinSliderZ(0),
+ m_xCount(50),
+ m_zCount(50),
+ m_activeSample(0),
+ m_fontSize(40),
+ m_rangeX(16.0),
+ m_rangeZ(16.0),
+ m_minX(-8.0),
+ m_minZ(-8.0),
+ m_planeArray(0)
+{
+ m_graph->setAxisX(new Q3DValueAxis);
+ m_graph->setAxisY(new Q3DValueAxis);
+ m_graph->setAxisZ(new Q3DValueAxis);
+ m_graph->axisX()->setRange(m_minX, m_minX + m_rangeX);
+ m_graph->axisZ()->setRange(m_minZ, m_minZ + m_rangeZ);
+ changeStyle();
+
+ connect(&m_timer, &QTimer::timeout, this, &GraphModifier::timeout);
+}
+
+GraphModifier::~GraphModifier()
+{
+ delete m_graph;
+}
+
+void GraphModifier::toggleSmooth(bool enabled)
+{
+ qDebug() << "GraphModifier::toggleSmooth " << enabled;
+ m_graph->setSmoothSurfaceEnabled(enabled);
+}
+
+void GraphModifier::toggleSurfaceGrid(bool enable)
+{
+ qDebug() << "GraphModifier::toggleSurfaceGrid" << enable;
+ m_graph->setSurfaceGridEnabled(enable);
+}
+
+void GraphModifier::toggleSqrtSin(bool enable)
+{
+ if (enable) {
+ qDebug() << "Create Sqrt&Sin surface, (" << m_xCount << ", " << m_zCount << ")";
+
+ float minX = -10.0;
+ float maxX = 10.0;
+ float minZ = -10.0;
+ float maxZ = 10.0;
+ float stepX = (maxX - minX) / float(m_xCount - 1);
+ float stepZ = (maxZ - minZ) / float(m_zCount - 1);
+
+ QSurfaceDataArray *dataArray = new QSurfaceDataArray;
+ dataArray->reserve(m_zCount);
+ for (float i = 0; i < m_zCount; i++) {
+ QSurfaceDataRow *newRow = new QSurfaceDataRow(m_xCount);
+ for (float j = 0; j < m_xCount; j++) {
+ float x = j * stepX + minX;
+ float z = i * stepZ + minZ;
+ float R = qSqrt(x * x + z * z) + 0.01f;
+ float y = (qSin(R) / R + 0.24f) * 1.61f + 1.0f;
+ (*newRow)[j].setPosition(QVector3D(x, y, z));
+ }
+ *dataArray << newRow;
+ }
+
+ m_graph->axisY()->setRange(1.0, 3.0);
+ m_graph->axisX()->setLabelFormat("%.2f");
+ m_graph->axisZ()->setLabelFormat("%.2f");
+
+ resetArrayAndSliders(dataArray, minZ, maxZ, minX, maxX);
+
+ m_activeSample = GraphModifier::SqrtSin;
+ } else {
+ qDebug() << "Remove surface";
+ }
+}
+
+void GraphModifier::togglePlane(bool enable)
+{
+ qDebug() << "GraphModifier::togglePlane " << enable;
+
+ if (enable) {
+ m_planeArray = new QSurfaceDataArray;
+
+#ifdef JITTER_PLANE
+ m_timer.start(0);
+#endif
+ m_graph->axisY()->setRange(0.0, 1.0);
+ m_graph->axisX()->setLabelFormat("%.2f");
+ m_graph->axisZ()->setLabelFormat("%.2f");
+
+ m_planeArray->reserve(m_zCount);
+ float minX = -10.0;
+ float maxX = 20.0;
+ float minZ = -10.0;
+ float maxZ = 10.0;
+ float stepX = (maxX - minX) / float(m_xCount - 1);
+ float stepZ = (maxZ - minZ) / float(m_zCount - 1);
+#ifdef WONKY_PLANE
+ float halfZ = m_zCount / 2;
+ float wonkyFactor = 0.01f;
+ float maxStepX = 0.0f;
+ for (float i = 0; i < m_zCount; i++) {
+ QSurfaceDataRow *newRow = new QSurfaceDataRow(m_xCount);
+ if (i < halfZ) {
+ stepX += wonkyFactor;
+ maxStepX = stepX;
+ } else {
+ stepX -= wonkyFactor;
+ }
+ for (float j = 0; j < m_xCount; j++) {
+ (*newRow)[j].setPosition(QVector3D(j * stepX + minX, -0.04f,
+ i * stepZ + minZ));
+
+ }
+ *m_planeArray << newRow;
+ }
+
+ resetArrayAndSliders(m_planeArray, minZ, maxZ, minX, m_xCount * maxStepX + minZ);
+#else
+ for (float i = 0; i < m_zCount; i++) {
+ QSurfaceDataRow *newRow = new QSurfaceDataRow(m_xCount);
+ for (float j = 0; j < m_xCount; j++)
+ (*newRow)[j].setPosition(QVector3D(j * stepX + minX, -0.04f, i * stepZ + minZ));
+
+ *m_planeArray << newRow;
+ }
+
+ resetArrayAndSliders(m_planeArray, minZ, maxZ, minX, maxX);
+#endif
+
+ m_activeSample = GraphModifier::Plane;
+ }
+#ifdef JITTER_PLANE
+ else {
+ m_timer.stop();
+ }
+#endif
+}
+
+void GraphModifier::setHeightMapData(bool enable)
+{
+ if (enable) {
+ // Do the height map the hard way.
+ // Easier alternative would be to use the QHeightMapSurfaceDataProxy.
+ QImage image(":/maps/map");
+
+ QSurfaceDataArray *dataArray = new QSurfaceDataArray;
+ uchar *bits = image.bits();
+
+ int p = image.width() * 4 * (image.height() - 1);
+ dataArray->reserve(image.height());
+ float minX = 34.0;
+ float maxX = 40.0;
+ float minZ = 18.0;
+ float maxZ = 24.0;
+ float xMul = (maxX - minX) / float(image.width() - 1);
+ float zMul = (maxZ - minZ) / float(image.height() - 1);
+ for (int i = 0; i < image.height(); i++, p -= image.width() * 4) {
+ QSurfaceDataRow *newRow = new QSurfaceDataRow(image.width());
+ for (int j = 0; j < image.width(); j++) {
+ (*newRow)[j].setPosition(QVector3D((float(j) * xMul) + minX,
+ (float(bits[p + (j * 4)]) + 1.0f) / 1.0f,
+ (float(i) * zMul) + minZ));
+ }
+ *dataArray << newRow;
+ }
+
+ m_graph->axisY()->setAutoAdjustRange(true);
+ m_graph->axisX()->setLabelFormat("%.1f N");
+ m_graph->axisZ()->setLabelFormat("%.1f E");
+
+ resetArrayAndSliders(dataArray, minZ, maxZ, minX, maxX);
+
+ m_activeSample = GraphModifier::Map;
+ }
+}
+
+void GraphModifier::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 GraphModifier::adjustXCount(int count)
+{
+ m_xCount = count;
+ if (m_gridSlidersLocked)
+ m_gridSliderZ->setValue(count);
+
+ updateSamples();
+
+ qDebug() << "X count =" << count;
+}
+
+void GraphModifier::adjustZCount(int count)
+{
+ m_zCount = count;
+
+ updateSamples();
+
+ qDebug() << "Z count =" << count;
+}
+
+void GraphModifier::adjustXRange(int range)
+{
+ m_rangeX = range;
+ m_graph->axisX()->setRange(m_minX, m_minX + m_rangeX);
+
+ qDebug() << "X Range =" << range;
+}
+
+void GraphModifier::adjustZRange(int range)
+{
+ m_rangeZ = range;
+ m_graph->axisZ()->setRange(m_minZ, m_minZ + m_rangeZ);
+
+ qDebug() << "Z Range =" << range;
+}
+
+void GraphModifier::adjustXMin(int min)
+{
+ m_minX = min;
+ m_graph->axisX()->setRange(m_minX, m_minX + m_rangeX);
+
+ qDebug() << "X Minimum =" << min;
+}
+
+void GraphModifier::adjustZMin(int min)
+{
+ m_minZ = min;
+ m_graph->axisZ()->setRange(m_minZ, m_minZ + m_rangeZ);
+
+ qDebug() << "Z Minimum =" << min;
+}
+
+void GraphModifier::gradientPressed()
+{
+ QLinearGradient gradient;
+ gradient.setColorAt(0.0, Qt::black);
+ gradient.setColorAt(0.33, Qt::blue);
+ gradient.setColorAt(0.67, Qt::red);
+ gradient.setColorAt(1.0, Qt::yellow);
+ m_graph->setGradient(gradient);
+}
+
+void GraphModifier::changeFont(const QFont &font)
+{
+ QFont newFont = font;
+ newFont.setPointSizeF(m_fontSize);
+ m_graph->setFont(newFont);
+}
+
+void GraphModifier::changeStyle()
+{
+ static int style = QDataVis::LabelStyleFromTheme;
+
+ m_graph->setLabelStyle((QDataVis::LabelStyle)style);
+
+ if (++style > QDataVis::LabelStyleTransparent)
+ style = QDataVis::LabelStyleOpaque;
+}
+
+void GraphModifier::changeTheme(int theme)
+{
+ m_graph->setTheme((QDataVis::Theme)theme);
+}
+
+void GraphModifier::timeout()
+{
+ int rows = m_planeArray->size();
+ int columns = m_planeArray->at(0)->size();
+
+ // Induce minor random jitter to the existing plane array
+ for (int i = 0; i < rows; i++) {
+ for (int j = 0; j < columns; j++) {
+ (*m_planeArray->at(i))[j].setX(m_planeArray->at(i)->at(j).x()
+ * ((float((rand() % 10) + 5.0f) / 10000.0f) + 0.999f));
+ (*m_planeArray->at(i))[j].setY(m_planeArray->at(i)->at(j).y()
+ * ((float((rand() % 10) + 5.0f) / 1000.0f) + 0.99f) + 0.0001f);
+ (*m_planeArray->at(i))[j].setZ(m_planeArray->at(i)->at(j).z()
+ * ((float((rand() % 10) + 5.0f) / 10000.0f) + 0.999f));
+ }
+ }
+
+ // Reset same array to make it redraw
+ m_graph->activeDataProxy()->resetArray(m_planeArray);
+}
+
+void GraphModifier::resetArrayAndSliders(QSurfaceDataArray *array, qreal minZ, qreal maxZ, qreal minX, qreal maxX)
+{
+ m_axisMinSliderX->setValue(minX);
+ m_axisMinSliderZ->setValue(minZ);
+ m_axisRangeSliderX->setValue(maxX - minX);
+ m_axisRangeSliderZ->setValue(maxZ - minZ);
+
+ m_graph->activeDataProxy()->resetArray(array);
+}
+
+void GraphModifier::changeShadowQuality(int quality)
+{
+ QDataVis::ShadowQuality sq = QDataVis::ShadowQuality(quality);
+ m_graph->setShadowQuality(sq);
+}
+
+void GraphModifier::changeSelectionMode(int mode)
+{
+ switch (mode) {
+ case 0:
+ qDebug() << "QDataVis::SelectionModeNone";
+ m_graph->setSelectionMode(QDataVis::SelectionModeNone);
+ break;
+ case 1:
+ qDebug() << "QDataVis::SelectionModeItem";
+ m_graph->setSelectionMode(QDataVis::SelectionModeItem);
+ break;
+ case 2:
+ qDebug() << "QDataVis::SelectionModeSliceRow";
+ m_graph->setSelectionMode(QDataVis::SelectionModeSliceRow);
+ break;
+ case 3:
+ qDebug() << "QDataVis::SelectionModeSliceColumn";
+ m_graph->setSelectionMode(QDataVis::SelectionModeSliceColumn);
+ break;
+ default:
+ qDebug() << __FUNCTION__ << " Unsupported selection mode.";
+ break;
+ }
+}
+
+void GraphModifier::updateSamples()
+{
+ switch (m_activeSample) {
+ case SqrtSin:
+ toggleSqrtSin(true);
+ break;
+
+ case Plane:
+ togglePlane(true);
+ break;
+
+ default:
+ break;
+ }
+}
+
diff --git a/tests/surfacetest/graphmodifier.h b/tests/surfacetest/graphmodifier.h
new file mode 100644
index 00000000..83b1873b
--- /dev/null
+++ b/tests/surfacetest/graphmodifier.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 GRAPHMODIFIER_H
+#define GRAPHMODIFIER_H
+
+#include <QtDataVisualization/Q3DSurface>
+#include <QtDataVisualization/QSurfaceDataProxy>
+#include <QSlider>
+#include <QTimer>
+
+using namespace QtDataVisualization;
+
+class GraphModifier : public QObject
+{
+ Q_OBJECT
+public:
+ enum Samples {
+ SqrtSin = 1,
+ Plane,
+ Map
+ };
+
+ explicit GraphModifier(Q3DSurface *graph);
+ ~GraphModifier();
+
+ void toggleSmooth(bool enabled);
+ void toggleSurfaceGrid(bool enable);
+ void toggleSqrtSin(bool enable);
+ void togglePlane(bool enable);
+ void setHeightMapData(bool enable);
+ void toggleGridSliderLock(bool enable);
+ void setGridSliderX(QSlider *slider) { m_gridSliderX = slider; }
+ void setGridSliderZ(QSlider *slider) { m_gridSliderZ = slider; }
+ void setAxisRangeSliderX(QSlider *slider) { m_axisRangeSliderX = slider; }
+ void setAxisRangeSliderZ(QSlider *slider) { m_axisRangeSliderZ = slider; }
+ void setAxisMinSliderX(QSlider *slider) { m_axisMinSliderX = slider; }
+ void setAxisMinSliderZ(QSlider *slider) { m_axisMinSliderZ = slider; }
+ void adjustXCount(int count);
+ void adjustZCount(int count);
+ void adjustXRange(int range);
+ void adjustZRange(int range);
+ void adjustXMin(int min);
+ void adjustZMin(int min);
+ void updateSamples();
+ void gradientPressed();
+ void changeFont(const QFont &font);
+ void changeStyle();
+
+public slots:
+ void changeShadowQuality(int quality);
+ void changeTheme(int theme);
+ void changeSelectionMode(int mode);
+ void timeout();
+
+private:
+ void resetArrayAndSliders(QSurfaceDataArray *array, qreal minZ, qreal maxZ, qreal minX,
+ qreal maxX);
+
+ Q3DSurface *m_graph;
+ QSlider *m_gridSliderX;
+ QSlider *m_gridSliderZ;
+ QSlider *m_axisRangeSliderX;
+ QSlider *m_axisRangeSliderZ;
+ QSlider *m_axisMinSliderX;
+ QSlider *m_axisMinSliderZ;
+ bool m_gridSlidersLocked;
+ int m_xCount;
+ int m_zCount;
+ int m_activeSample;
+ int m_fontSize;
+ qreal m_rangeX;
+ qreal m_rangeZ;
+ qreal m_minX;
+ qreal m_minZ;
+ QTimer m_timer;
+ QSurfaceDataArray *m_planeArray;
+};
+
+#endif
diff --git a/tests/surfacetest/main.cpp b/tests/surfacetest/main.cpp
new file mode 100644
index 00000000..19f30e5d
--- /dev/null
+++ b/tests/surfacetest/main.cpp
@@ -0,0 +1,256 @@
+/****************************************************************************
+**
+** 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 QtDataVisualization 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 "graphmodifier.h"
+
+#include <QApplication>
+#include <QWidget>
+#include <QHBoxLayout>
+#include <QVBoxLayout>
+#include <QPushButton>
+#include <QCheckBox>
+#include <QRadioButton>
+#include <QSlider>
+#include <QLabel>
+#include <QScreen>
+#include <QPainter>
+#include <QFontComboBox>
+#include <QDebug>
+
+using namespace QtDataVisualization;
+
+const int initialTheme = 4;
+
+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 *surfaceGraph = new Q3DSurface();
+ QSize screenSize = surfaceGraph->screen()->size();
+
+ // Set to default, should be same as the initial on themeList
+ surfaceGraph->setTheme(QDataVis::Theme(initialTheme));
+
+ QWidget *container = QWidget::createWindowContainer(surfaceGraph);
+ 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(surfaceGraph->isSmoothSurfaceEnabled());
+
+ QCheckBox *surfaceGridCB = new QCheckBox(widget);
+ surfaceGridCB->setText(QStringLiteral("Surface Grid"));
+ surfaceGridCB->setChecked(true);
+
+ //QCheckBox *sqrtSinCB = new QCheckBox(widget);
+ QRadioButton *sqrtSinCB = new QRadioButton(widget);
+ sqrtSinCB->setText(QStringLiteral("Sqrt & Sin"));
+ sqrtSinCB->setChecked(false);
+
+ QRadioButton *planeCB = new QRadioButton(widget);
+ planeCB->setText(QStringLiteral("Plane"));
+ planeCB->setChecked(false);
+
+ QRadioButton *heightMapCB = new QRadioButton(widget);
+ heightMapCB->setText(QStringLiteral("Height map"));
+ heightMapCB->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(30);
+ gridSliderX->setMaximum(200);
+ gridSliderX->setEnabled(true);
+ QSlider *gridSliderZ = new QSlider(Qt::Horizontal, widget);
+ gridSliderZ->setTickInterval(1);
+ gridSliderZ->setMinimum(2);
+ gridSliderZ->setValue(30);
+ gridSliderZ->setMaximum(200);
+ gridSliderZ->setEnabled(true);
+
+ QSlider *axisRangeSliderX = new QSlider(Qt::Horizontal, widget);
+ axisRangeSliderX->setTickInterval(1);
+ axisRangeSliderX->setMinimum(2);
+ axisRangeSliderX->setValue(16);
+ axisRangeSliderX->setMaximum(100);
+ axisRangeSliderX->setEnabled(true);
+ QSlider *axisRangeSliderZ = new QSlider(Qt::Horizontal, widget);
+ axisRangeSliderZ->setTickInterval(1);
+ axisRangeSliderZ->setMinimum(2);
+ axisRangeSliderZ->setValue(16);
+ axisRangeSliderZ->setMaximum(100);
+ axisRangeSliderZ->setEnabled(true);
+
+ QSlider *axisMinSliderX = new QSlider(Qt::Horizontal, widget);
+ axisMinSliderX->setTickInterval(1);
+ axisMinSliderX->setMinimum(-50);
+ axisMinSliderX->setValue(-8);
+ axisMinSliderX->setMaximum(50);
+ axisMinSliderX->setEnabled(true);
+ QSlider *axisMinSliderZ = new QSlider(Qt::Horizontal, widget);
+ axisMinSliderZ->setTickInterval(1);
+ axisMinSliderZ->setMinimum(-50);
+ axisMinSliderZ->setValue(-8);
+ axisMinSliderZ->setMaximum(50);
+ axisMinSliderZ->setEnabled(true);
+
+ QLinearGradient gr(0, 0, 100, 1);
+ gr.setColorAt(0.0, Qt::black);
+ gr.setColorAt(0.33, Qt::blue);
+ gr.setColorAt(0.67, Qt::red);
+ gr.setColorAt(1.0, Qt::yellow);
+ QPixmap pm(100, 24);
+ QPainter pmp(&pm);
+ pmp.setBrush(QBrush(gr));
+ pmp.setPen(Qt::NoPen);
+ pmp.drawRect(0, 0, 100, 24);
+ QPushButton *colorPB = new QPushButton();
+ colorPB->setIcon(QIcon(pm));
+ colorPB->setIconSize(QSize(100, 24));
+
+ QFontComboBox *fontList = new QFontComboBox(widget);
+ fontList->setCurrentFont(QFont("Arial"));
+
+ QPushButton *labelButton = new QPushButton(widget);
+ labelButton->setText(QStringLiteral("Change label style"));
+
+ QComboBox *themeList = new QComboBox(widget);
+ themeList->addItem(QStringLiteral("Qt"));
+ themeList->addItem(QStringLiteral("Primary Colors"));
+ themeList->addItem(QStringLiteral("Digia"));
+ themeList->addItem(QStringLiteral("Stone Moss"));
+ themeList->addItem(QStringLiteral("Army Blue"));
+ themeList->addItem(QStringLiteral("Retro"));
+ themeList->addItem(QStringLiteral("Ebony"));
+ themeList->addItem(QStringLiteral("Isabelle"));
+ themeList->setCurrentIndex(initialTheme);
+
+// QComboBox *shadowQuality = new QComboBox(widget);
+// shadowQuality->addItem(QStringLiteral("None"));
+// shadowQuality->addItem(QStringLiteral("Low"));
+// shadowQuality->addItem(QStringLiteral("Medium"));
+// shadowQuality->addItem(QStringLiteral("High"));
+// shadowQuality->addItem(QStringLiteral("Low Soft"));
+// shadowQuality->addItem(QStringLiteral("Medium Soft"));
+// shadowQuality->addItem(QStringLiteral("High Soft"));
+// shadowQuality->setCurrentIndex(3);
+ QComboBox *selectionMode = new QComboBox(widget);
+ selectionMode->addItem(QStringLiteral("SelectionModeNone"));
+ selectionMode->addItem(QStringLiteral("SelectionModeItem"));
+ selectionMode->addItem(QStringLiteral("SelectionModeSliceRow"));
+ selectionMode->addItem(QStringLiteral("SelectionModeSliceColumn"));
+ selectionMode->setCurrentIndex(1);
+
+ // 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(heightMapCB);
+ vLayout->addWidget(new QLabel(QStringLiteral("Adjust sample count")));
+ vLayout->addWidget(gridSlidersLockCB);
+ vLayout->addWidget(gridSliderX);
+ vLayout->addWidget(gridSliderZ);
+ vLayout->addWidget(new QLabel(QStringLiteral("Adjust axis range")));
+ vLayout->addWidget(axisRangeSliderX);
+ vLayout->addWidget(axisRangeSliderZ);
+ vLayout->addWidget(new QLabel(QStringLiteral("Adjust axis minimum")));
+ vLayout->addWidget(axisMinSliderX);
+ vLayout->addWidget(axisMinSliderZ);
+ vLayout->addWidget(colorPB);
+ vLayout->addWidget(new QLabel(QStringLiteral("Change font")));
+ vLayout->addWidget(fontList);
+ vLayout->addWidget(labelButton);
+ vLayout->addWidget(new QLabel(QStringLiteral("Change theme")));
+ vLayout->addWidget(themeList);
+// vLayout->addWidget(new QLabel(QStringLiteral("Adjust shadow quality")));
+// vLayout->addWidget(shadowQuality);
+ vLayout->addWidget(new QLabel(QStringLiteral("Selection Mode")));
+ vLayout->addWidget(selectionMode);
+
+ widget->show();
+
+ GraphModifier *modifier = new GraphModifier(surfaceGraph);
+
+ // Connect controls to slots on modifier
+ QObject::connect(smoothCB, &QCheckBox::stateChanged,
+ modifier, &GraphModifier::toggleSmooth);
+ QObject::connect(surfaceGridCB, &QCheckBox::stateChanged,
+ modifier, &GraphModifier::toggleSurfaceGrid);
+ QObject::connect(sqrtSinCB, &QRadioButton::toggled,
+ modifier, &GraphModifier::toggleSqrtSin);
+ QObject::connect(planeCB, &QCheckBox::toggled,
+ modifier, &GraphModifier::togglePlane);
+ QObject::connect(heightMapCB, &QCheckBox::toggled,
+ modifier, &GraphModifier::setHeightMapData);
+ QObject::connect(gridSlidersLockCB, &QCheckBox::stateChanged,
+ modifier, &GraphModifier::toggleGridSliderLock);
+ QObject::connect(gridSliderX, &QSlider::valueChanged,
+ modifier, &GraphModifier::adjustXCount);
+ QObject::connect(gridSliderZ, &QSlider::valueChanged,
+ modifier, &GraphModifier::adjustZCount);
+ QObject::connect(axisRangeSliderX, &QSlider::valueChanged,
+ modifier, &GraphModifier::adjustXRange);
+ QObject::connect(axisRangeSliderZ, &QSlider::valueChanged,
+ modifier, &GraphModifier::adjustZRange);
+ QObject::connect(axisMinSliderX, &QSlider::valueChanged,
+ modifier, &GraphModifier::adjustXMin);
+ QObject::connect(axisMinSliderZ, &QSlider::valueChanged,
+ modifier, &GraphModifier::adjustZMin);
+ QObject::connect(colorPB, &QPushButton::pressed,
+ modifier, &GraphModifier::gradientPressed);
+ QObject::connect(fontList, &QFontComboBox::currentFontChanged,
+ modifier, &GraphModifier::changeFont);
+ QObject::connect(labelButton, &QPushButton::clicked,
+ modifier, &GraphModifier::changeStyle);
+ QObject::connect(themeList, SIGNAL(currentIndexChanged(int)),
+ modifier, SLOT(changeTheme(int)));
+// QObject::connect(shadowQuality, SIGNAL(currentIndexChanged(int)),
+// modifier, SLOT(changeShadowQuality(int)));
+ QObject::connect(selectionMode, SIGNAL(currentIndexChanged(int)),
+ modifier, SLOT(changeSelectionMode(int)));
+
+ modifier->setGridSliderZ(gridSliderZ);
+ modifier->setGridSliderX(gridSliderX);
+ modifier->setAxisRangeSliderX(axisRangeSliderX);
+ modifier->setAxisRangeSliderZ(axisRangeSliderZ);
+ modifier->setAxisMinSliderX(axisMinSliderX);
+ modifier->setAxisMinSliderZ(axisMinSliderZ);
+ modifier->toggleGridSliderLock(gridSlidersLockCB->checkState());
+ sqrtSinCB->setChecked(true);
+
+ return app.exec();
+}
diff --git a/tests/surfacetest/surfacetest.pro b/tests/surfacetest/surfacetest.pro
new file mode 100644
index 00000000..9ab890a7
--- /dev/null
+++ b/tests/surfacetest/surfacetest.pro
@@ -0,0 +1,16 @@
+!include( ../tests.pri ) {
+ error( "Couldn't find the tests.pri file!" )
+}
+
+SOURCES += main.cpp \
+ graphmodifier.cpp
+
+QT += widgets
+
+INSTALLS += target
+
+HEADERS += \
+ graphmodifier.h
+
+RESOURCES += \
+ surfacetest.qrc
diff --git a/tests/surfacetest/surfacetest.qrc b/tests/surfacetest/surfacetest.qrc
new file mode 100644
index 00000000..c18da2c4
--- /dev/null
+++ b/tests/surfacetest/surfacetest.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/maps">
+ <file alias="map">Heightmap.png</file>
+ </qresource>
+</RCC>
diff --git a/tests/tests.pri b/tests/tests.pri
new file mode 100644
index 00000000..815ce4dd
--- /dev/null
+++ b/tests/tests.pri
@@ -0,0 +1,72 @@
+android {
+ target.path = /libs/$$ANDROID_TARGET_ARCH
+} else {
+ target.path = $$[QT_INSTALL_TESTS]/datavisualization/$$TARGET
+}
+
+win32 {
+ CONFIG(debug, release|debug):DESTDIR = $$OUT_PWD/debug
+ CONFIG(release, release|debug):DESTDIR = $$OUT_PWD/release
+} else {
+ DESTDIR = $$OUT_PWD
+}
+
+LIBS += -L$$OUT_PWD/../../lib
+
+TEMPLATE = app
+
+QT += datavisualization
+
+contains(TARGET, qml.*) {
+ uri = com.digia.QtDataVisualization
+ lib_name = datavisualizationqml2
+
+ uri_replaced = $$replace(uri, \\., $$QMAKE_DIR_SEP)
+ make_qmldir_path = $$DESTDIR/$$uri_replaced
+ !exists($$make_qmldir_path) {
+ make_qmldir_target = \"$$replace(make_qmldir_path, /, $$QMAKE_DIR_SEP)\"
+ system($$QMAKE_MKDIR $$make_qmldir_target)
+ }
+ copy_qmldir_examples.target = $$make_qmldir_path/qmldir
+ copy_qmldir_examples.depends = $$_PRO_FILE_PWD_/../../src/$$lib_name/qmldir
+ copy_qmldir_examples.commands = $(COPY_FILE) \"$$replace(copy_qmldir_examples.depends, /, $$QMAKE_DIR_SEP)\" \"$$replace(copy_qmldir_examples.target, /, $$QMAKE_DIR_SEP)\"
+ QMAKE_EXTRA_TARGETS += copy_qmldir_examples
+ PRE_TARGETDEPS += $$copy_qmldir_examples.target
+
+ win32 {
+ CONFIG(debug, release|debug) {
+ src_dir = debug
+ src_lib = $${lib_name}d.dll
+ }
+ CONFIG(release, release|debug){
+ src_dir = release
+ src_lib = $${lib_name}.dll
+ }
+ } else {
+ src_dir = .
+ mac {
+ CONFIG(debug, release|debug) {
+ src_lib = lib$${lib_name}_debug.dylib
+ }
+ CONFIG(release, release|debug){
+ src_lib = lib$${lib_name}.dylib
+ }
+ } else {
+ # linux, android
+ src_lib = lib$${lib_name}.so
+ }
+ }
+ copy_lib.target = $$make_qmldir_path/$$src_lib
+ copy_lib.depends = $$OUT_PWD/../../src/$$lib_name/$$src_dir/$$src_lib
+ 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 {
+ android_qmldir.files = $$copy_qmldir_examples.target
+ android_qmldir.path = /assets/qml/$$uri_replaced
+ android_qmlplugin.files = $$copy_lib.target
+ android_qmlplugin.path = $$target.path
+ INSTALLS += android_qmldir android_qmlplugin
+ }
+}
diff --git a/tests/tests.pro b/tests/tests.pro
new file mode 100644
index 00000000..3fe3edb8
--- /dev/null
+++ b/tests/tests.pro
@@ -0,0 +1,17 @@
+!contains(QT_CONFIG, opengl) {
+ error(Tests requires OpenGL!)
+}
+contains(QT_CONFIG, opengles1) {
+ error(Tests do not support OpenGL ES 1!)
+}
+
+TEMPLATE = subdirs
+
+SUBDIRS += barstest \
+ scattertest \
+ surfacetest \
+ qmlcamera
+
+#SUBDIRS += kinectsurface
+
+qtHaveModule(multimedia):!android: SUBDIRS += spectrum