summaryrefslogtreecommitdiffstats
path: root/tests/manual
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@theqtcompany.com>2015-10-20 13:18:59 +0300
committerMiikka Heikkinen <miikka.heikkinen@theqtcompany.com>2015-10-22 10:08:51 +0000
commit31f9c57bc50ae053cfaf039a1dfdb128e2494458 (patch)
tree316138cb73c49877f5a80a8496c2f1b737122fb5 /tests/manual
parent4162ddeb02ee41fd4217d7f3d93d45cab3313ba8 (diff)
Fix issues with COIN builds
-Fix miscellaneous compile errors -Move manual tests to manual folder and enable export of autotests -Added widgets requirement -Fixed autotests -Fixed renderer and controller synchronization in QML case -Treat fallback Mesa as ES2 similar to setting AA_UseSoftwareOpenGL Change-Id: If6619733725d079e339bef16262e5ea1450ab20f Reviewed-by: Tomi Korpipää <tomi.korpipaa@theqtcompany.com>
Diffstat (limited to 'tests/manual')
-rw-r--r--tests/manual/barstest/barstest.pro10
-rw-r--r--tests/manual/barstest/barstest.qrc6
-rw-r--r--tests/manual/barstest/chart.cpp1778
-rw-r--r--tests/manual/barstest/chart.h190
-rw-r--r--tests/manual/barstest/custominputhandler.cpp57
-rw-r--r--tests/manual/barstest/custominputhandler.h39
-rw-r--r--tests/manual/barstest/main.cpp650
-rw-r--r--tests/manual/barstest/shuttle.obj6349
-rw-r--r--tests/manual/barstest/shuttle.pngbin0 -> 1361 bytes
-rw-r--r--tests/manual/directional/directional.pro8
-rw-r--r--tests/manual/directional/main.cpp166
-rw-r--r--tests/manual/directional/scatterdatamodifier.cpp220
-rw-r--r--tests/manual/directional/scatterdatamodifier.h72
-rw-r--r--tests/manual/galaxy/cumulativedistributor.cpp146
-rw-r--r--tests/manual/galaxy/cumulativedistributor.h79
-rw-r--r--tests/manual/galaxy/galaxy.pro23
-rw-r--r--tests/manual/galaxy/galaxydata.cpp481
-rw-r--r--tests/manual/galaxy/galaxydata.h117
-rw-r--r--tests/manual/galaxy/main.cpp163
-rw-r--r--tests/manual/galaxy/star.cpp54
-rw-r--r--tests/manual/galaxy/star.h46
-rw-r--r--tests/manual/itemmodeltest/itemmodeltest.pro7
-rw-r--r--tests/manual/itemmodeltest/main.cpp318
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/00openni_notes.txt2
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/ARC/XnOSARC.h166
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/ARC/XnPlatformARC.h194
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/Android-Arm/XnPlatformAndroid-Arm.h49
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/IXnNodeAllocator.h53
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/Linux-Arm/XnPlatformLinux-Arm.h37
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/Linux-x86/XnOSLinux-x86.h165
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/Linux-x86/XnPlatformLinux-x86.h195
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/MacOSX/XnPlatformMacOSX.h43
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/Win32/XnOSWin32.h157
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/Win32/XnPlatformWin32.h255
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/Win32/usb100.h270
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnAlgorithms.h81
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnArray.h313
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnBaseNode.h59
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnBitSet.h135
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnCallback.h41
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnCodecIDs.h34
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnContext.h569
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnCppWrapper.h10100
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnCyclicQueueT.h79
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnCyclicStackT.h80
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnDataTypes.h120
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnDerivedCast.h80
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnDump.h202
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnDumpWriters.h127
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnEnumerationErrors.h142
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnEvent.h301
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnEventT.h393
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnFPSCalculator.h72
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnGeneralBuffer.h119
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnHash.h1014
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnHashT.h668
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnInternalDefs.h27
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnLicensing.h72
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnList.h749
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnListT.h556
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnLog.h545
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnLogTypes.h80
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnLogWriterBase.h128
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnMacros.h128
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnModuleCFunctions.h1995
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnModuleCppInterface.h605
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnModuleCppRegistratration.h303
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnModuleInterface.h1351
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnNode.h76
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnNodeAllocator.h46
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnOS.h784
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnOSCpp.h163
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnOSMemory.h47
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnOSStrings.h47
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnOpenNI.h50
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnPlatform.h124
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnPrdNode.h2614
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnPrdNodeInfo.h126
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnPrdNodeInfoList.h226
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnProfiling.h131
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnPropNames.h62
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnQueries.h159
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnQueue.h198
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnQueueT.h63
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnScheduler.h92
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnStack.h151
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnStackT.h58
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnStatus.h110
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnStatusCodes.h81
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnStatusRegister.h81
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnStringsHash.h118
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnStringsHashT.h90
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnThreadSafeQueue.h156
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnTypes.h1188
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnUSB.h128
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnUSBDevice.h117
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnUtils.h427
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnVersion.h58
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/mingw-win32/XnOSLinux-x86.h165
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/mingw-win32/XnPlatformLinux-x86.h196
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/QKinectWrapper.cpp283
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/QKinectWrapper.h117
-rw-r--r--tests/manual/kinectsurface/QtKinectWrapper/config.pro60
-rw-r--r--tests/manual/kinectsurface/kinectsurface.pro71
-rw-r--r--tests/manual/kinectsurface/main.cpp187
-rw-r--r--tests/manual/kinectsurface/surfacedata.cpp403
-rw-r--r--tests/manual/kinectsurface/surfacedata.h106
-rw-r--r--tests/manual/manual.pro30
-rw-r--r--tests/manual/minimalbars/minimalbars.pro10
-rw-r--r--tests/manual/minimalscatter/minimalscatter.pro10
-rw-r--r--tests/manual/minimalsurface/minimalsurface.pro10
-rw-r--r--tests/manual/multigraphs/australia.pngbin0 -> 414991 bytes
-rw-r--r--tests/manual/multigraphs/data.cpp329
-rw-r--r--tests/manual/multigraphs/data.h101
-rw-r--r--tests/manual/multigraphs/main.cpp159
-rw-r--r--tests/manual/multigraphs/multigraphs.pro12
-rw-r--r--tests/manual/multigraphs/multigraphs.qrc5
-rw-r--r--tests/manual/qmlcamera/main.cpp48
-rw-r--r--tests/manual/qmlcamera/qml/qmlcamera/Axes.qml49
-rw-r--r--tests/manual/qmlcamera/qml/qmlcamera/ControlSurface.qml56
-rw-r--r--tests/manual/qmlcamera/qml/qmlcamera/Data.qml144
-rw-r--r--tests/manual/qmlcamera/qml/qmlcamera/main.qml238
-rw-r--r--tests/manual/qmlcamera/qmlcamera.pro10
-rw-r--r--tests/manual/qmlcamera/qmlcamera.qrc12
-rw-r--r--tests/manual/qmlcamera/shuttle.obj6349
-rw-r--r--tests/manual/qmlcamera/shuttle.pngbin0 -> 1361 bytes
-rw-r--r--tests/manual/qmldynamicdata/main.cpp51
-rw-r--r--tests/manual/qmldynamicdata/qml/qmldynamicdata/NewButton.qml46
-rw-r--r--tests/manual/qmldynamicdata/qml/qmldynamicdata/main.qml263
-rw-r--r--tests/manual/qmldynamicdata/qmldynamicdata.pro9
-rw-r--r--tests/manual/qmldynamicdata/qmldynamicdata.qrc6
-rw-r--r--tests/manual/qmlmultitest/main.cpp50
-rw-r--r--tests/manual/qmlmultitest/qml/qmlmultitest/Data.qml72
-rw-r--r--tests/manual/qmlmultitest/qml/qmlmultitest/NewButton.qml55
-rw-r--r--tests/manual/qmlmultitest/qml/qmlmultitest/main.qml251
-rw-r--r--tests/manual/qmlmultitest/qmlmultitest.pro12
-rw-r--r--tests/manual/qmlmultitest/qmlmultitest.qrc7
-rw-r--r--tests/manual/qmlmultiwindow/main.cpp50
-rw-r--r--tests/manual/qmlmultiwindow/qml/qmlmultiwindow/Data.qml51
-rw-r--r--tests/manual/qmlmultiwindow/qml/qmlmultiwindow/NewButton.qml55
-rw-r--r--tests/manual/qmlmultiwindow/qml/qmlmultiwindow/main.qml263
-rw-r--r--tests/manual/qmlmultiwindow/qmlmultiwindow.pro12
-rw-r--r--tests/manual/qmlmultiwindow/qmlmultiwindow.qrc7
-rw-r--r--tests/manual/qmlperf/datagenerator.cpp89
-rw-r--r--tests/manual/qmlperf/datagenerator.h47
-rw-r--r--tests/manual/qmlperf/main.cpp56
-rw-r--r--tests/manual/qmlperf/qml/qmlperf/main.qml194
-rw-r--r--tests/manual/qmlperf/qmlperf.pro16
-rw-r--r--tests/manual/qmlperf/qmlperf.qrc5
-rw-r--r--tests/manual/qmlvolume/datasource.cpp93
-rw-r--r--tests/manual/qmlvolume/datasource.h41
-rw-r--r--tests/manual/qmlvolume/main.cpp59
-rw-r--r--tests/manual/qmlvolume/qml/qmlvolume/NewButton.qml55
-rw-r--r--tests/manual/qmlvolume/qml/qmlvolume/main.qml167
-rw-r--r--tests/manual/qmlvolume/qmlvolume.pro16
-rw-r--r--tests/manual/qmlvolume/qmlvolume.qrc6
-rw-r--r--tests/manual/scattertest/main.cpp496
-rw-r--r--tests/manual/scattertest/scatterchart.cpp1172
-rw-r--r--tests/manual/scattertest/scatterchart.h132
-rw-r--r--tests/manual/scattertest/scattertest.pro8
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/Array.h97
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/Array.hpp98
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/DynArray.h100
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/DynArray.hpp143
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/FFTReal.dsp273
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/FFTReal.dsw29
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/FFTReal.h142
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/FFTReal.hpp916
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/FFTRealFixLen.h130
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/FFTRealFixLen.hpp322
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/FFTRealFixLenParam.h93
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/FFTRealPassDirect.h96
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/FFTRealPassDirect.hpp204
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/FFTRealPassInverse.h101
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/FFTRealPassInverse.hpp229
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/FFTRealSelect.h77
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/FFTRealSelect.hpp62
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/FFTRealUseTrigo.h101
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/FFTRealUseTrigo.hpp91
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/OscSinCos.h106
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/OscSinCos.hpp122
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/TestAccuracy.h105
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/TestAccuracy.hpp472
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/TestHelperFixLen.h93
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/TestHelperFixLen.hpp93
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/TestHelperNormal.h94
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/TestHelperNormal.hpp99
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/TestSpeed.h95
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/TestSpeed.hpp223
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/TestWhiteNoiseGen.h95
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/TestWhiteNoiseGen.hpp91
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/def.h60
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/fftreal.pas661
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/fftreal.pro44
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/fftreal_wrapper.cpp54
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/fftreal_wrapper.h63
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/license.txt459
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/readme.txt242
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/test.cpp267
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/test_fnc.h53
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/test_fnc.hpp56
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/test_settings.h45
-rw-r--r--tests/manual/spectrum/3rdparty/fftreal/testapp.dpr150
-rw-r--r--tests/manual/spectrum/README.txt103
-rw-r--r--tests/manual/spectrum/spectrum.pri18
-rw-r--r--tests/manual/spectrum/spectrum.pro16
-rw-r--r--tests/manual/spectrum/spectrumapp/engine.cpp622
-rw-r--r--tests/manual/spectrum/spectrumapp/engine.h250
-rw-r--r--tests/manual/spectrum/spectrumapp/frequencyspectrum.cpp70
-rw-r--r--tests/manual/spectrum/spectrumapp/frequencyspectrum.h79
-rw-r--r--tests/manual/spectrum/spectrumapp/main.cpp212
-rw-r--r--tests/manual/spectrum/spectrumapp/soundFiles/Rockhop.wavbin0 -> 1059308 bytes
-rw-r--r--tests/manual/spectrum/spectrumapp/soundFiles/futurebells_beat.wavbin0 -> 352084 bytes
-rw-r--r--tests/manual/spectrum/spectrumapp/soundFiles/onclassical_demo_fiati-di-parma_thuille_terzo-tempo_sestetto_small-version.wavbin0 -> 1055502 bytes
-rw-r--r--tests/manual/spectrum/spectrumapp/spectrum.h114
-rw-r--r--tests/manual/spectrum/spectrumapp/spectrum.qrc7
-rw-r--r--tests/manual/spectrum/spectrumapp/spectrumanalyser.cpp212
-rw-r--r--tests/manual/spectrum/spectrumapp/spectrumanalyser.h153
-rw-r--r--tests/manual/spectrum/spectrumapp/spectrumapp.pro73
-rw-r--r--tests/manual/spectrum/spectrumapp/utils.cpp120
-rw-r--r--tests/manual/spectrum/spectrumapp/utils.h93
-rw-r--r--tests/manual/spectrum/spectrumapp/wavfile.cpp132
-rw-r--r--tests/manual/spectrum/spectrumapp/wavfile.h47
-rw-r--r--tests/manual/surfacetest/Heightmap.pngbin0 -> 71764 bytes
-rw-r--r--tests/manual/surfacetest/graphmodifier.cpp1682
-rw-r--r--tests/manual/surfacetest/graphmodifier.h204
-rw-r--r--tests/manual/surfacetest/main.cpp748
-rw-r--r--tests/manual/surfacetest/mapimage.pngbin0 -> 159540 bytes
-rw-r--r--tests/manual/surfacetest/surfacetest.pro14
-rw-r--r--tests/manual/surfacetest/surfacetest.qrc6
-rw-r--r--tests/manual/tests.pri14
-rw-r--r--tests/manual/volumetrictest/cubeFilledFlat.obj54
-rw-r--r--tests/manual/volumetrictest/logo.pngbin0 -> 2205 bytes
-rw-r--r--tests/manual/volumetrictest/logo_no_padding.pngbin0 -> 2278 bytes
-rw-r--r--tests/manual/volumetrictest/main.cpp171
-rw-r--r--tests/manual/volumetrictest/volumetrictest.cpp719
-rw-r--r--tests/manual/volumetrictest/volumetrictest.h82
-rw-r--r--tests/manual/volumetrictest/volumetrictest.pro14
-rw-r--r--tests/manual/volumetrictest/volumetrictest.qrc7
239 files changed, 67858 insertions, 0 deletions
diff --git a/tests/manual/barstest/barstest.pro b/tests/manual/barstest/barstest.pro
new file mode 100644
index 00000000..56e24ef2
--- /dev/null
+++ b/tests/manual/barstest/barstest.pro
@@ -0,0 +1,10 @@
+!include( ../tests.pri ) {
+ error( "Couldn't find the tests.pri file!" )
+}
+
+SOURCES += main.cpp chart.cpp custominputhandler.cpp
+HEADERS += chart.h custominputhandler.h
+
+RESOURCES += barstest.qrc
+
+QT += widgets
diff --git a/tests/manual/barstest/barstest.qrc b/tests/manual/barstest/barstest.qrc
new file mode 100644
index 00000000..f7237eb7
--- /dev/null
+++ b/tests/manual/barstest/barstest.qrc
@@ -0,0 +1,6 @@
+<RCC>
+ <qresource prefix="/">
+ <file>shuttle.obj</file>
+ <file>shuttle.png</file>
+ </qresource>
+</RCC>
diff --git a/tests/manual/barstest/chart.cpp b/tests/manual/barstest/chart.cpp
new file mode 100644
index 00000000..9e316dd0
--- /dev/null
+++ b/tests/manual/barstest/chart.cpp
@@ -0,0 +1,1778 @@
+/******************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module.
+**
+** $QT_BEGIN_LICENSE:COMM$
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** $QT_END_LICENSE$
+**
+******************************************************************************/
+
+#include "chart.h"
+#include "custominputhandler.h"
+#include <QtDataVisualization/qcategory3daxis.h>
+#include <QtDataVisualization/qvalue3daxis.h>
+#include <QtDataVisualization/qlogvalue3daxisformatter.h>
+#include <QtDataVisualization/qbardataproxy.h>
+#include <QtDataVisualization/q3dscene.h>
+#include <QtDataVisualization/q3dcamera.h>
+#include <QtDataVisualization/q3dtheme.h>
+#include <QtDataVisualization/q3dinputhandler.h>
+#include <QtDataVisualization/qcustom3ditem.h>
+#include <QtCore/QTime>
+#include <QtCore/qmath.h>
+
+using namespace QtDataVisualization;
+
+const QString celsiusString = QString(QChar(0xB0)) + "C";
+
+GraphModifier::GraphModifier(Q3DBars *barchart, QColorDialog *colorDialog)
+ : m_graph(barchart),
+ m_colorDialog(colorDialog),
+ m_columnCount(21),
+ m_rowCount(21),
+ m_xRotation(0.0f),
+ m_yRotation(0.0f),
+ m_static(true),
+ m_barSpacingX(0.1f),
+ m_barSpacingZ(0.1f),
+ m_fontSize(20),
+ m_segments(10),
+ m_subSegments(3),
+ m_minval(-16.0f),
+ m_maxval(20.0f),
+ m_selectedBar(-1, -1),
+ m_selectedSeries(0),
+ m_autoAdjustingAxis(new QValue3DAxis),
+ m_fixedRangeAxis(new QValue3DAxis),
+ m_temperatureAxis(new QValue3DAxis),
+ m_yearAxis(new QCategory3DAxis),
+ m_monthAxis(new QCategory3DAxis),
+ m_genericRowAxis(new QCategory3DAxis),
+ m_genericColumnAxis(new QCategory3DAxis),
+ m_temperatureData(new QBar3DSeries),
+ m_temperatureData2(new QBar3DSeries),
+ m_genericData(new QBar3DSeries),
+ m_dummyData(new QBar3DSeries),
+ m_dummyData2(new QBar3DSeries),
+ m_dummyData3(new QBar3DSeries),
+ m_dummyData4(new QBar3DSeries),
+ m_dummyData5(new QBar3DSeries),
+ m_currentAxis(m_fixedRangeAxis),
+ m_negativeValuesOn(false),
+ m_useNullInputHandler(false),
+ m_defaultInputHandler(0),
+ m_ownTheme(0),
+ m_builtinTheme(new Q3DTheme(Q3DTheme::ThemeStoneMoss)),
+ m_customInputHandler(new CustomInputHandler),
+ m_extraSeries(0)
+{
+ m_temperatureData->setObjectName("m_temperatureData");
+ m_temperatureData2->setObjectName("m_temperatureData2");
+ m_genericData->setObjectName("m_genericData");
+ m_dummyData->setObjectName("m_dummyData");
+ m_dummyData2->setObjectName("m_dummyData2");
+ m_dummyData3->setObjectName("m_dummyData3");
+ m_dummyData4->setObjectName("m_dummyData4");
+ m_dummyData5->setObjectName("m_dummyData5");
+
+ // 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_graph->addAxis(m_autoAdjustingAxis);
+ m_graph->addAxis(m_fixedRangeAxis);
+ m_graph->addAxis(m_temperatureAxis);
+ m_graph->addAxis(m_yearAxis);
+ m_graph->addAxis(m_monthAxis);
+ m_graph->addAxis(m_genericRowAxis);
+ m_graph->addAxis(m_genericColumnAxis);
+
+ m_graph->setActiveTheme(m_builtinTheme);
+ m_graph->setShadowQuality(QAbstract3DGraph::ShadowQualitySoftMedium);
+
+ m_temperatureData->setName("Oulu");
+ m_temperatureData2->setName("Helsinki");
+ m_genericData->setName("Generic series");
+ m_dummyData->setName("Dummy 1");
+ m_dummyData2->setName("Dummy 2");
+ m_dummyData3->setName("Dummy 3");
+ m_dummyData4->setName("Dummy 4");
+ m_dummyData5->setName("Dummy 5");
+
+ m_temperatureData->setItemLabelFormat(QStringLiteral("@seriesName: @valueTitle for @colLabel @rowLabel: @valueLabel ~ %.4f"));
+ m_temperatureData2->setItemLabelFormat(QStringLiteral("@seriesName: @valueTitle for @colLabel @rowLabel: @valueLabel"));
+ m_genericData->setItemLabelFormat(QStringLiteral("@seriesName: @valueTitle for (@rowIdx, @colIdx): @valueLabel"));
+
+ m_dummyData->setItemLabelFormat(QStringLiteral("@seriesName: @valueLabel"));
+ m_dummyData2->setItemLabelFormat(QStringLiteral("@seriesName: @valueLabel"));
+ m_dummyData3->setItemLabelFormat(QStringLiteral("@seriesName: @valueLabel"));
+ m_dummyData4->setItemLabelFormat(QStringLiteral("@seriesName: @valueLabel"));
+ m_dummyData5->setItemLabelFormat(QStringLiteral("@seriesName: @valueLabel"));
+
+ m_genericData->dataProxy()->setColumnLabels(genericColumnLabels);
+
+ m_temperatureData->setBaseColor(Qt::red);
+ m_temperatureData->setSingleHighlightColor(Qt::cyan);
+ m_temperatureData->setMultiHighlightColor(Qt::magenta);
+ m_temperatureData2->setBaseColor(Qt::yellow);
+ m_genericData->setBaseColor(Qt::blue);
+
+ QLinearGradient barGradient1(0, 0, 1, 100);
+ barGradient1.setColorAt(1.0, Qt::red);
+ barGradient1.setColorAt(0.75001, Qt::red);
+ barGradient1.setColorAt(0.75, Qt::magenta);
+ barGradient1.setColorAt(0.50001, Qt::magenta);
+ barGradient1.setColorAt(0.50, Qt::blue);
+ barGradient1.setColorAt(0.25001, Qt::blue);
+ barGradient1.setColorAt(0.25, Qt::black);
+ barGradient1.setColorAt(0.0, Qt::black);
+
+ QLinearGradient barGradient2(0, 0, 1, 100);
+ barGradient2.setColorAt(1.0, Qt::red);
+ barGradient2.setColorAt(0.75, Qt::magenta);
+ barGradient2.setColorAt(0.50, Qt::blue);
+ barGradient2.setColorAt(0.25, Qt::black);
+ barGradient2.setColorAt(0.0, Qt::black);
+
+ QLinearGradient singleHighlightGradient(0, 0, 1, 100);
+ singleHighlightGradient.setColorAt(1.0, Qt::white);
+ singleHighlightGradient.setColorAt(0.75, Qt::lightGray);
+ singleHighlightGradient.setColorAt(0.50, Qt::gray);
+ singleHighlightGradient.setColorAt(0.25, Qt::darkGray);
+ singleHighlightGradient.setColorAt(0.0, Qt::black);
+
+ QLinearGradient multiHighlightGradient(0, 0, 1, 100);
+ multiHighlightGradient.setColorAt(1.0, Qt::lightGray);
+ multiHighlightGradient.setColorAt(0.75, Qt::gray);
+ multiHighlightGradient.setColorAt(0.50, Qt::darkGray);
+ multiHighlightGradient.setColorAt(0.25, Qt::black);
+ multiHighlightGradient.setColorAt(0.0, Qt::black);
+
+ m_temperatureData->setBaseGradient(barGradient1);
+ m_temperatureData2->setBaseGradient(barGradient2);
+ m_temperatureData->setSingleHighlightGradient(singleHighlightGradient);
+ m_temperatureData->setMultiHighlightGradient(multiHighlightGradient);
+
+ m_graph->activeTheme()->setFont(QFont("Times Roman", 20));
+
+ // Release and store the default input handler.
+ m_defaultInputHandler = static_cast<Q3DInputHandler *>(m_graph->activeInputHandler());
+ m_graph->releaseInputHandler(m_defaultInputHandler);
+ m_graph->setActiveInputHandler(m_defaultInputHandler);
+
+ QObject::connect(m_graph, &Q3DBars::shadowQualityChanged, this,
+ &GraphModifier::shadowQualityUpdatedByVisual);
+ QObject::connect(m_temperatureData, &QBar3DSeries::selectedBarChanged, this,
+ &GraphModifier::handleSelectionChange);
+ QObject::connect(m_temperatureData2, &QBar3DSeries::selectedBarChanged, this,
+ &GraphModifier::handleSelectionChange);
+ QObject::connect(m_genericData, &QBar3DSeries::selectedBarChanged, this,
+ &GraphModifier::handleSelectionChange);
+
+ QObject::connect(m_graph, &Q3DBars::rowAxisChanged, this,
+ &GraphModifier::handleRowAxisChanged);
+ QObject::connect(m_graph, &Q3DBars::columnAxisChanged, this,
+ &GraphModifier::handleColumnAxisChanged);
+ QObject::connect(m_graph, &Q3DBars::valueAxisChanged, this,
+ &GraphModifier::handleValueAxisChanged);
+ QObject::connect(m_graph, &Q3DBars::primarySeriesChanged, this,
+ &GraphModifier::handlePrimarySeriesChanged);
+ QObject::connect(m_temperatureAxis, &QAbstract3DAxis::labelsChanged, this,
+ &GraphModifier::handleValueAxisLabelsChanged);
+
+ QObject::connect(&m_insertRemoveTimer, &QTimer::timeout, this,
+ &GraphModifier::insertRemoveTimerTimeout);
+
+ m_graph->addSeries(m_temperatureData);
+ m_graph->addSeries(m_temperatureData2);
+
+ QObject::connect(&m_selectionTimer, &QTimer::timeout, this,
+ &GraphModifier::triggerSelection);
+ QObject::connect(&m_rotationTimer, &QTimer::timeout, this,
+ &GraphModifier::triggerRotation);
+
+ QObject::connect(m_graph, &QAbstract3DGraph::currentFpsChanged, this,
+ &GraphModifier::handleFpsChange);
+
+ resetTemperatureData();
+}
+
+GraphModifier::~GraphModifier()
+{
+ delete m_graph;
+ delete m_defaultInputHandler;
+}
+
+void GraphModifier::start()
+{
+ restart(false);
+}
+
+void GraphModifier::restart(bool dynamicData)
+{
+ m_static = !dynamicData;
+
+ if (m_static) {
+ m_graph->removeSeries(m_genericData);
+
+ m_graph->setTitle(QStringLiteral("Average temperatures in Oulu, Finland (2006-2012)"));
+
+ m_graph->setValueAxis(m_temperatureAxis);
+ m_graph->setRowAxis(m_yearAxis);
+ m_graph->setColumnAxis(m_monthAxis);
+
+ } else {
+ m_graph->addSeries(m_genericData);
+
+ m_graph->setTitle(QStringLiteral("Generic data"));
+
+ m_minval = m_fixedRangeAxis->min();
+ m_maxval = m_fixedRangeAxis->max();
+ m_graph->setValueAxis(m_currentAxis);
+ m_graph->setRowAxis(m_genericRowAxis);
+ m_graph->setColumnAxis(m_genericColumnAxis);
+ }
+}
+
+void GraphModifier::selectBar()
+{
+ QPoint targetBar(5, 5);
+ QPoint noSelection(-1, -1);
+ if (m_selectedBar != targetBar)
+ m_graph->seriesList().at(0)->setSelectedBar(targetBar);
+ else
+ m_graph->seriesList().at(0)->setSelectedBar(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_graph->setValueAxis(m_currentAxis);
+}
+
+void GraphModifier::releaseAxes()
+{
+ // Releases all axes we have created - 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_graph->releaseAxis(m_autoAdjustingAxis);
+ m_graph->releaseAxis(m_fixedRangeAxis);
+ m_graph->releaseAxis(m_temperatureAxis);
+ m_graph->releaseAxis(m_yearAxis);
+ m_graph->releaseAxis(m_monthAxis);
+ m_graph->releaseAxis(m_genericRowAxis);
+ m_graph->releaseAxis(m_genericColumnAxis);
+}
+
+void GraphModifier::releaseSeries()
+{
+ foreach (QBar3DSeries *series, m_graph->seriesList())
+ m_graph->removeSeries(series);
+}
+
+void GraphModifier::flipViews()
+{
+ m_graph->scene()->setSecondarySubviewOnTop(!m_graph->scene()->isSecondarySubviewOnTop());
+ qDebug() << "secondary subview on top:" << m_graph->scene()->isSecondarySubviewOnTop();
+ qDebug() << "point (50, 50) in primary subview:" << m_graph->scene()->isPointInPrimarySubView(QPoint(50, 50));
+ qDebug() << "point (50, 50) in secondary subview:" << m_graph->scene()->isPointInSecondarySubView(QPoint(50, 50));
+}
+
+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++) {
+ if (!m_negativeValuesOn)
+ (*dataRow)[j].setValue((float(i % 300 + 1) / 300.0) * float(rand() % int(m_maxval)));
+ else
+ (*dataRow)[j].setValue((float(i % 300 + 1) / 300.0) * float(rand() % int(m_maxval))
+ + m_minval);
+ }
+ dataArray->append(dataRow);
+ }
+
+ m_genericData->dataProxy()->resetArray(dataArray, genericRowLabels, genericColumnLabels);
+
+ qDebug() << "Created Massive Array (" << arrayDimension << "), time:" << timer.elapsed();
+}
+
+void GraphModifier::resetTemperatureData()
+{
+ // Set up data
+ static const 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
+ };
+
+ // 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);
+ }
+
+ QBarDataArray *dataSet2 = new QBarDataArray;
+
+ dataSet2->reserve(m_years.size());
+ for (int year = m_years.size() - 1; year >= 0; year--) {
+ dataRow = new QBarDataRow(m_months.size());
+ // Create data items
+ for (int month = m_months.size() - 1; month >= 0 ; month--) {
+ // Add data to rows
+ (*dataRow)[month].setValue(temp[year][month]);
+ }
+ // Add row to set
+ dataSet2->append(dataRow);
+ }
+
+ // Add data to chart (chart assumes ownership)
+ m_temperatureData->dataProxy()->resetArray(dataSet, m_years, m_months);
+ m_temperatureData2->dataProxy()->resetArray(dataSet2, 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 (float i = 0; i < m_columnCount; i++) {
+ if (!m_negativeValuesOn)
+ (*dataRow)[i].setValue(((i + 1) / (float)m_columnCount) * (float)(rand() % int(m_maxval)));
+ else
+ (*dataRow)[i].setValue(((i + 1) / (float)m_columnCount) * (float)(rand() % int(m_maxval))
+ - (float)(rand() % int(m_minval)));
+ }
+
+ // TODO Needs to be changed to account for data window offset once it is implemented.
+ QString label = QStringLiteral("Add %1").arg(addCounter++);
+ m_genericData->dataProxy()->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(float(j + i + m_genericData->dataProxy()->rowCount()) + m_minval);
+ 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_genericData->dataProxy()->addRows(dataArray, labels);
+}
+
+void GraphModifier::insertRow()
+{
+ QBarDataRow *dataRow = new QBarDataRow(m_columnCount);
+ for (float i = 0; i < m_columnCount; i++)
+ (*dataRow)[i].setValue(((i + 1) / (float)m_columnCount) * (float)(rand() % int(m_maxval))
+ + m_minval);
+
+ // TODO Needs to be changed to account for data window offset once it is implemented.
+ int row = qMax(m_selectedBar.x(), 0);
+ QString label = QStringLiteral("Insert %1").arg(insertCounter++);
+ m_genericData->dataProxy()->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(float(j + i + m_genericData->dataProxy()->rowCount()) + m_minval);
+ 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_selectedBar.x(), 0);
+ m_genericData->dataProxy()->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_selectedBar.x();
+ int column = m_selectedBar.y();
+ if (row >= 0 && column >= 0) {
+ QBarDataItem item(float(rand() % 100));
+ m_genericData->dataProxy()->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_selectedBar.x();
+ if (row >= 0) {
+ QBarDataRow *newRow = new QBarDataRow(m_genericData->dataProxy()->rowAt(row)->size());
+ for (int i = 0; i < newRow->size(); i++)
+ (*newRow)[i].setValue(float(rand() % int(m_maxval)) + m_minval);
+ QString label = QStringLiteral("Change %1").arg(changeCounter++);
+ m_genericData->dataProxy()->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_selectedBar.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_genericData->dataProxy()->rowAt(i)->size());
+ for (int j = 0; j < newRow->size(); j++)
+ (*newRow)[j].setValue(float(rand() % int(m_maxval)) + m_minval);
+ newArray.append(newRow);
+ labels.append(QStringLiteral("Change %1").arg(changeCounter++));
+ }
+ m_genericData->dataProxy()->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_selectedBar.x();
+ if (row >= 0)
+ m_genericData->dataProxy()->removeRows(row, 1);
+}
+
+void GraphModifier::removeRows()
+{
+ // TODO Needs to be changed to account for data window offset once it is implemented.
+ int row = m_selectedBar.x();
+ if (row >= 0) {
+ int startRow = qMax(row - 3, 0);
+ m_genericData->dataProxy()->removeRows(startRow, 3);
+ }
+}
+
+void GraphModifier::changeStyle()
+{
+ static int model = 0;
+ switch (model) {
+ case 0:
+ m_graph->seriesList().at(0)->setMesh(QAbstract3DSeries::MeshCylinder);
+ m_graph->seriesList().at(0)->setMeshSmooth(false);
+ break;
+ case 1:
+ m_graph->seriesList().at(0)->setMesh(QAbstract3DSeries::MeshCylinder);
+ m_graph->seriesList().at(0)->setMeshSmooth(true);
+ break;
+ case 2:
+ m_graph->seriesList().at(0)->setMesh(QAbstract3DSeries::MeshCone);
+ m_graph->seriesList().at(0)->setMeshSmooth(false);
+ break;
+ case 3:
+ m_graph->seriesList().at(0)->setMesh(QAbstract3DSeries::MeshCone);
+ m_graph->seriesList().at(0)->setMeshSmooth(true);
+ break;
+ case 4:
+ m_graph->seriesList().at(0)->setMesh(QAbstract3DSeries::MeshBar);
+ m_graph->seriesList().at(0)->setMeshSmooth(false);
+ break;
+ case 5:
+ m_graph->seriesList().at(0)->setMesh(QAbstract3DSeries::MeshBar);
+ m_graph->seriesList().at(0)->setMeshSmooth(true);
+ break;
+ case 6:
+ m_graph->seriesList().at(0)->setMesh(QAbstract3DSeries::MeshPyramid);
+ m_graph->seriesList().at(0)->setMeshSmooth(false);
+ break;
+ case 7:
+ m_graph->seriesList().at(0)->setMesh(QAbstract3DSeries::MeshPyramid);
+ m_graph->seriesList().at(0)->setMeshSmooth(true);
+ break;
+ case 8:
+ m_graph->seriesList().at(0)->setMesh(QAbstract3DSeries::MeshBevelBar);
+ m_graph->seriesList().at(0)->setMeshSmooth(false);
+ break;
+ case 9:
+ m_graph->seriesList().at(0)->setMesh(QAbstract3DSeries::MeshBevelBar);
+ m_graph->seriesList().at(0)->setMeshSmooth(true);
+ break;
+ }
+ model++;
+ if (model > 9)
+ model = 0;
+}
+
+void GraphModifier::changePresetCamera()
+{
+ static int preset = Q3DCamera::CameraPresetFrontLow;
+
+ m_graph->scene()->activeCamera()->setCameraPreset((Q3DCamera::CameraPreset)preset);
+
+ if (++preset > Q3DCamera::CameraPresetDirectlyBelow)
+ preset = Q3DCamera::CameraPresetFrontLow;
+}
+
+void GraphModifier::changeTheme()
+{
+ static int theme = Q3DTheme::ThemeQt;
+
+ Q3DTheme *currentTheme = m_graph->activeTheme();
+ m_builtinTheme->setType(Q3DTheme::Theme(theme));
+ if (currentTheme == m_ownTheme)
+ m_graph->setActiveTheme(m_builtinTheme);
+
+ switch (theme) {
+ case Q3DTheme::ThemeQt:
+ qDebug() << __FUNCTION__ << "ThemeQt";
+ break;
+ case Q3DTheme::ThemePrimaryColors:
+ qDebug() << __FUNCTION__ << "ThemePrimaryColors";
+ break;
+ case Q3DTheme::ThemeDigia:
+ qDebug() << __FUNCTION__ << "ThemeDigia";
+ break;
+ case Q3DTheme::ThemeStoneMoss:
+ qDebug() << __FUNCTION__ << "ThemeStoneMoss";
+ break;
+ case Q3DTheme::ThemeArmyBlue:
+ qDebug() << __FUNCTION__ << "ThemeArmyBlue";
+ break;
+ case Q3DTheme::ThemeRetro:
+ qDebug() << __FUNCTION__ << "ThemeRetro";
+ break;
+ case Q3DTheme::ThemeEbony:
+ qDebug() << __FUNCTION__ << "ThemeEbony";
+ break;
+ case Q3DTheme::ThemeIsabelle:
+ qDebug() << __FUNCTION__ << "ThemeIsabelle";
+ break;
+ default:
+ qDebug() << __FUNCTION__ << "Unknown theme";
+ break;
+ }
+
+ if (++theme > Q3DTheme::ThemeIsabelle)
+ theme = Q3DTheme::ThemeQt;
+}
+
+void GraphModifier::changeLabelStyle()
+{
+ m_graph->activeTheme()->setLabelBackgroundEnabled(!m_graph->activeTheme()->isLabelBackgroundEnabled());
+}
+
+void GraphModifier::changeSelectionMode()
+{
+ static int selectionMode = m_graph->selectionMode();
+
+ if (++selectionMode > (QAbstract3DGraph::SelectionItemAndColumn | QAbstract3DGraph::SelectionSlice | QAbstract3DGraph::SelectionMultiSeries))
+ selectionMode = QAbstract3DGraph::SelectionNone;
+
+ m_graph->setSelectionMode((QAbstract3DGraph::SelectionFlag)selectionMode);
+}
+
+void GraphModifier::changeFont(const QFont &font)
+{
+ QFont newFont = font;
+ newFont.setPointSize(m_fontSize);
+ m_graph->activeTheme()->setFont(newFont);
+}
+
+void GraphModifier::changeFontSize(int fontsize)
+{
+ m_fontSize = fontsize;
+ QFont font = m_graph->activeTheme()->font();
+ font.setPointSize(m_fontSize);
+ m_graph->activeTheme()->setFont(font);
+}
+
+void GraphModifier::shadowQualityUpdatedByVisual(QAbstract3DGraph::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_selectedBar = position;
+ int index = 0;
+ foreach (QBar3DSeries *series, m_graph->seriesList()) {
+ if (series == sender()) {
+ if (series->selectedBar() != QBar3DSeries::invalidSelectionPosition())
+ m_selectedSeries = series;
+ break;
+ }
+ index++;
+ }
+
+ if (m_selectedSeries->selectedBar() == QBar3DSeries::invalidSelectionPosition())
+ m_selectedSeries = 0;
+
+ qDebug() << "Selected bar position:" << position << "series:" << index;
+}
+
+void GraphModifier::setUseNullInputHandler(bool useNull)
+{
+ qDebug() << "setUseNullInputHandler" << useNull;
+ if (m_useNullInputHandler == useNull)
+ return;
+
+ m_useNullInputHandler = useNull;
+
+ if (useNull)
+ m_graph->setActiveInputHandler(0);
+ else
+ m_graph->setActiveInputHandler(m_defaultInputHandler);
+}
+
+void GraphModifier::handleRowAxisChanged(QCategory3DAxis *axis)
+{
+ qDebug() << __FUNCTION__ << axis << axis->orientation() << (axis == m_graph->rowAxis());
+}
+
+void GraphModifier::handleColumnAxisChanged(QCategory3DAxis *axis)
+{
+ qDebug() << __FUNCTION__ << axis << axis->orientation() << (axis == m_graph->columnAxis());
+}
+
+void GraphModifier::handleValueAxisChanged(QValue3DAxis *axis)
+{
+ qDebug() << __FUNCTION__ << axis << axis->orientation() << (axis == m_graph->valueAxis());
+}
+
+void GraphModifier::handlePrimarySeriesChanged(QBar3DSeries *series)
+{
+ qDebug() << __FUNCTION__ << series;
+}
+
+void GraphModifier::changeShadowQuality(int quality)
+{
+ QAbstract3DGraph::ShadowQuality sq = QAbstract3DGraph::ShadowQuality(quality);
+ m_graph->setShadowQuality(sq);
+ emit shadowQualityChanged(quality);
+}
+
+void GraphModifier::showFiveSeries()
+{
+ releaseSeries();
+ releaseAxes();
+ m_graph->setSelectionMode(QAbstract3DGraph::SelectionItemRowAndColumn | QAbstract3DGraph::SelectionMultiSeries);
+
+ m_dummyData->dataProxy()->resetArray(makeDummyData(), QStringList(), QStringList());
+ m_dummyData2->dataProxy()->resetArray(makeDummyData(), QStringList(), QStringList());
+ m_dummyData3->dataProxy()->resetArray(makeDummyData(), QStringList(), QStringList());
+ m_dummyData4->dataProxy()->resetArray(makeDummyData(), QStringList(), QStringList());
+ m_dummyData5->dataProxy()->resetArray(makeDummyData(), QStringList(), QStringList());
+
+ m_graph->addSeries(m_dummyData);
+ m_graph->addSeries(m_dummyData2);
+ m_graph->addSeries(m_dummyData3);
+ m_graph->addSeries(m_dummyData4);
+
+ // Toggle between four and five series
+ static int count = 0;
+ if (++count % 2)
+ m_graph->addSeries(m_dummyData5);
+}
+
+QBarDataArray *GraphModifier::makeDummyData()
+{
+ // Set up data
+ static const float temp[4][4] = {
+ {10.0f, 5.0f, 10.0f, 5.0f},
+ {5.0f, 10.0f, 5.0f, 10.0f},
+ {10.0f, 5.0f, 10.0f, 5.0f},
+ {5.0f, 10.0f, 5.0f, 10.0f}
+ };
+
+ // Create data rows
+ QBarDataArray *dataSet = new QBarDataArray;
+ QBarDataRow *dataRow;
+
+ dataSet->reserve(4);
+ for (int i = 0; i < 4; i++) {
+ dataRow = new QBarDataRow(4);
+ // Create data items
+ for (int j = 0; j < 4; j++) {
+ // Add data to rows
+ (*dataRow)[j].setValue(temp[i][j]);
+ }
+ // Add row to set
+ dataSet->append(dataRow);
+ }
+ return dataSet;
+}
+
+// Executes one step of the primary series test
+void GraphModifier::primarySeriesTest()
+{
+ static int nextStep = 0;
+
+ QStringList testLabels;
+ QStringList testLabels2;
+ QStringList testLabels3;
+ QStringList testLabels5;
+ testLabels << "1" << "2" << "3" << "4";
+ testLabels2 << "11" << "22" << "33" << "44";
+ testLabels3 << "111" << "222" << "333" << "444";
+ testLabels5 << "11111" << "22222" << "33333" << "44444";
+
+ switch (nextStep++) {
+ case 0: {
+ qDebug() << "Step 0 - Init:";
+ m_graph->addSeries(m_dummyData); // Add one series to enforce release in releaseProxies()
+ releaseSeries();
+ releaseAxes();
+ m_dummyData->dataProxy()->resetArray(makeDummyData(),
+ testLabels,
+ QStringList() << "A" << "B" << "C" << "D");
+ m_dummyData2->dataProxy()->resetArray(makeDummyData(),
+ testLabels2,
+ QStringList() << "AA" << "BB" << "CC" << "DD");
+ m_dummyData3->dataProxy()->resetArray(makeDummyData(),
+ testLabels3,
+ QStringList() << "AAA" << "BBB" << "CCC" << "DDD");
+ m_dummyData4->dataProxy()->resetArray(makeDummyData(),
+ QStringList() << "1111" << "2222" << "3333" << "4444",
+ QStringList() << "AAAA" << "BBBB" << "CCCC" << "DDDD");
+ m_dummyData5->dataProxy()->resetArray(makeDummyData(),
+ testLabels5,
+ QStringList() << "AAAAA" << "BBBBB" << "CCCCC" << "DDDDD");
+
+ m_graph->addSeries(m_dummyData);
+ m_graph->addSeries(m_dummyData2);
+ m_graph->addSeries(m_dummyData3);
+
+ m_dummyData->setBaseColor(Qt::black);
+ m_dummyData2->setBaseColor(Qt::white);
+ m_dummyData3->setBaseColor(Qt::red);
+ m_dummyData4->setBaseColor(Qt::blue);
+ m_dummyData5->setBaseColor(Qt::green);
+
+ if (m_graph->primarySeries() == m_dummyData)
+ if (m_graph->rowAxis()->labels() == testLabels)
+ qDebug() << "--> SUCCESS";
+ else
+ qDebug() << "--> FAIL!!! Row labels incorrect: " << m_graph->rowAxis()->labels();
+ else
+ qDebug() << "--> FAIL!!! Primary should be m_dummyData, actual: " << m_graph->primarySeries();
+ break;
+ }
+ case 1: {
+ qDebug() << "Step 1 - Set another series as primary:";
+ m_graph->setPrimarySeries(m_dummyData3);
+ if (m_graph->primarySeries() == m_dummyData3) {
+ if (m_graph->rowAxis()->labels() == testLabels3)
+ qDebug() << "--> SUCCESS";
+ else
+ qDebug() << "--> FAIL!!! Row labels incorrect: " << m_graph->rowAxis()->labels();
+ } else {
+ qDebug() << "--> FAIL!!! Primary should be m_dummyData3, actual: " << m_graph->primarySeries();
+ }
+ break;
+ }
+ case 2: {
+ qDebug() << "Step 2 - Add new series:";
+ m_graph->addSeries(m_dummyData4);
+ if (m_graph->primarySeries() == m_dummyData3)
+ if (m_graph->rowAxis()->labels() == testLabels3)
+ qDebug() << "--> SUCCESS";
+ else
+ qDebug() << "--> FAIL!!! Row labels incorrect: " << m_graph->rowAxis()->labels();
+ else
+ qDebug() << "--> FAIL!!! Primary should be m_dummyData3, actual: " << m_graph->primarySeries();
+ break;
+ }
+ case 3: {
+ qDebug() << "Step 3 - Reset primary series:";
+ m_graph->setPrimarySeries(0);
+ if (m_graph->primarySeries() == m_dummyData)
+ if (m_graph->rowAxis()->labels() == testLabels)
+ qDebug() << "--> SUCCESS";
+ else
+ qDebug() << "--> FAIL!!! Row labels incorrect: " << m_graph->rowAxis()->labels();
+ else
+ qDebug() << "--> FAIL!!! Primary should be m_dummyData, actual: " << m_graph->primarySeries();
+ break;
+ }
+ case 4: {
+ qDebug() << "Step 4 - Set new series at primary:";
+ m_graph->setPrimarySeries(m_dummyData5);
+ if (m_graph->primarySeries() == m_dummyData5)
+ if (m_graph->rowAxis()->labels() == testLabels5)
+ qDebug() << "--> SUCCESS";
+ else
+ qDebug() << "--> FAIL!!! Row labels incorrect: " << m_graph->rowAxis()->labels();
+ else
+ qDebug() << "--> FAIL!!! Primary should be m_dummyData5, actual: " << m_graph->primarySeries();
+ break;
+ }
+ case 5: {
+ qDebug() << "Step 5 - Remove nonexistent series:";
+ m_graph->removeSeries(0);
+ if (m_graph->primarySeries() == m_dummyData5)
+ if (m_graph->rowAxis()->labels() == testLabels5)
+ qDebug() << "--> SUCCESS";
+ else
+ qDebug() << "--> FAIL!!! Row labels incorrect: " << m_graph->rowAxis()->labels();
+ else
+ qDebug() << "--> FAIL!!! Primary should be m_dummyData5, actual: " << m_graph->primarySeries();
+ break;
+ }
+ case 6: {
+ qDebug() << "Step 6 - Remove non-primary series:";
+ m_graph->removeSeries(m_dummyData);
+ if (m_graph->primarySeries() == m_dummyData5)
+ if (m_graph->rowAxis()->labels() == testLabels5)
+ qDebug() << "--> SUCCESS";
+ else
+ qDebug() << "--> FAIL!!! Row labels incorrect: " << m_graph->rowAxis()->labels();
+ else
+ qDebug() << "--> FAIL!!! Primary should be m_dummyData5, actual: " << m_graph->primarySeries();
+ break;
+ }
+ case 7: {
+ qDebug() << "Step 7 - Remove primary series:";
+ m_graph->removeSeries(m_dummyData5);
+ if (m_graph->primarySeries() == m_dummyData2) // first series removed, second should be first now
+ if (m_graph->rowAxis()->labels() == testLabels2)
+ qDebug() << "--> SUCCESS";
+ else
+ qDebug() << "--> FAIL!!! Row labels incorrect: " << m_graph->rowAxis()->labels();
+ else
+ qDebug() << "--> FAIL!!! Primary should be m_dummyData3, actual: " << m_graph->primarySeries();
+ break;
+ }
+ case 8: {
+ qDebug() << "Step 8 - move a series (m_dummyData2) forward to a different position";
+ m_graph->insertSeries(3, m_dummyData2);
+ if (m_graph->primarySeries() == m_dummyData2)
+ if (m_graph->seriesList().at(2) == m_dummyData2) // moving series forward, index decrements
+ qDebug() << "--> SUCCESS";
+ else
+ qDebug() << "--> FAIL!!! Moved to incorrect index, index 2 has:" << m_graph->seriesList().at(2);
+ else
+ qDebug() << "--> FAIL!!! Primary should be m_dummyData3, actual: " << m_graph->primarySeries();
+ break;
+ }
+ case 9: {
+ qDebug() << "Step 9 - move a series (m_dummyData4) backward to a different position";
+ m_graph->insertSeries(0, m_dummyData4);
+ if (m_graph->primarySeries() == m_dummyData2)
+ if (m_graph->seriesList().at(0) == m_dummyData4)
+ qDebug() << "--> SUCCESS";
+ else
+ qDebug() << "--> FAIL!!! Moved to incorrect index, index 0 has:" << m_graph->seriesList().at(0);
+ else
+ qDebug() << "--> FAIL!!! Primary should be m_dummyData3, actual: " << m_graph->primarySeries();
+ break;
+ }
+ case 10: {
+ qDebug() << "Step 10 - Insert a series (m_dummyData) series to position 2";
+ m_graph->insertSeries(2, m_dummyData);
+ if (m_graph->primarySeries() == m_dummyData2)
+ if (m_graph->seriesList().at(2) == m_dummyData)
+ qDebug() << "--> SUCCESS";
+ else
+ qDebug() << "--> FAIL!!! Moved to incorrect index, index 2 has:" << m_graph->seriesList().at(2);
+ else
+ qDebug() << "--> FAIL!!! Primary should be m_dummyData3, actual: " << m_graph->primarySeries();
+ break;
+ }
+ case 11: {
+ qDebug() << "Step 11 - Remove everything";
+ m_graph->removeSeries(m_dummyData);
+ m_graph->removeSeries(m_dummyData2);
+ m_graph->removeSeries(m_dummyData3);
+ m_graph->removeSeries(m_dummyData4);
+ m_graph->removeSeries(m_dummyData5);
+ if (m_graph->primarySeries() == 0)
+ if (m_graph->rowAxis()->labels() == QStringList())
+ qDebug() << "--> SUCCESS";
+ else
+ qDebug() << "--> FAIL!!! Row labels incorrect: " << m_graph->rowAxis()->labels();
+ else
+ qDebug() << "--> FAIL!!! Primary should be null, actual: " << m_graph->primarySeries();
+ break;
+ }
+ default:
+ qDebug() << "-- Restarting test sequence --";
+ nextStep = 0;
+ break;
+ }
+}
+
+void GraphModifier::insertRemoveTestToggle()
+{
+ if (m_insertRemoveTimer.isActive()) {
+ m_insertRemoveTimer.stop();
+ m_selectionTimer.stop();
+ m_graph->removeSeries(m_dummyData);
+ m_graph->removeSeries(m_dummyData2);
+ releaseSeries();
+ releaseAxes();
+ m_graph->setActiveInputHandler(m_defaultInputHandler);
+ } else {
+ releaseSeries();
+ releaseAxes();
+ m_graph->rowAxis()->setRange(0, 32);
+ m_graph->columnAxis()->setRange(0, 10);
+ m_graph->setActiveInputHandler(m_customInputHandler);
+ m_graph->addSeries(m_dummyData);
+ m_graph->addSeries(m_dummyData2);
+ m_insertRemoveStep = 0;
+ m_insertRemoveTimer.start(100);
+ m_selectionTimer.start(10);
+ }
+}
+
+void GraphModifier::toggleRotation()
+{
+ if (m_rotationTimer.isActive())
+ m_rotationTimer.stop();
+ else
+ m_rotationTimer.start(20);
+}
+
+void GraphModifier::useLogAxis()
+{
+ static int counter = -1;
+ static QLogValue3DAxisFormatter *logFormatter = 0;
+ static float minRange = 1.0f;
+ counter++;
+
+ switch (counter) {
+ case 0: {
+ qDebug() << "Case" << counter << ": Default log axis";
+ logFormatter = new QLogValue3DAxisFormatter;
+ m_graph->valueAxis()->setFormatter(logFormatter);
+ m_graph->valueAxis()->setRange(minRange, 1200.0f);
+ m_graph->valueAxis()->setLabelFormat(QStringLiteral("%.3f"));
+ break;
+ }
+ case 1: {
+ qDebug() << "Case" << counter << ": Hide max label";
+ logFormatter->setShowEdgeLabels(false);
+ break;
+ }
+ case 2: {
+ qDebug() << "Case" << counter << ": Try to hide subgrid unsuccessfully";
+ m_graph->valueAxis()->setSubSegmentCount(1);
+ break;
+ }
+ case 3: {
+ qDebug() << "Case" << counter << ": Hide subgrid property";
+ logFormatter->setAutoSubGrid(false);
+ m_graph->valueAxis()->setSubSegmentCount(1);
+ break;
+ }
+ case 4: {
+ qDebug() << "Case" << counter << ": Different base: 2";
+ logFormatter->setBase(2.0f);
+ logFormatter->setAutoSubGrid(true);
+ break;
+ }
+ case 5: {
+ qDebug() << "Case" << counter << ": Different base: 16";
+ logFormatter->setBase(16.0f);
+ break;
+ }
+ case 6: {
+ qDebug() << "Case" << counter << ": Invalid bases";
+ logFormatter->setBase(-1.0f);
+ logFormatter->setBase(1.0f);
+ break;
+ }
+ case 7: {
+ qDebug() << "Case" << counter << ": Zero base";
+ logFormatter->setBase(0.0f);
+ break;
+ }
+ case 8: {
+ qDebug() << "Case" << counter << ": Explicit ranges and segments";
+ int segmentCount = 6;
+ int base = 4;
+ m_graph->valueAxis()->setSegmentCount(segmentCount);
+ m_graph->valueAxis()->setSubSegmentCount(base - 1);
+ m_graph->valueAxis()->setRange(1.0f / float(base * base), qPow(base, segmentCount - 2));
+ break;
+ }
+ case 9: {
+ qDebug() << "Case" << counter << ": Negative range";
+ m_graph->valueAxis()->setRange(-20.0f, 50.0f);
+ break;
+ }
+ case 10: {
+ qDebug() << "Case" << counter << ": Non-integer base";
+ logFormatter->setBase(3.3f);
+ logFormatter->setAutoSubGrid(true);
+ break;
+ }
+ default:
+ qDebug() << "Resetting logaxis test";
+ minRange++;
+ counter = -1;
+ break;
+ }
+}
+
+void GraphModifier::changeValueAxisFormat(const QString & text)
+{
+ m_graph->valueAxis()->setLabelFormat(text);
+}
+
+void GraphModifier::changeLogBase(const QString &text)
+{
+ QLogValue3DAxisFormatter *formatter =
+ qobject_cast<QLogValue3DAxisFormatter *>(m_graph->valueAxis()->formatter());
+ if (formatter)
+ formatter->setBase(qreal(text.toDouble()));
+}
+
+void GraphModifier::addRemoveSeries()
+{
+ static int counter = 0;
+
+ switch (counter) {
+ case 0: {
+ qDebug() << __FUNCTION__ << counter << "New series";
+ m_extraSeries = new QBar3DSeries;
+ m_graph->addSeries(m_extraSeries);
+ QObject::connect(m_extraSeries, &QBar3DSeries::selectedBarChanged, this,
+ &GraphModifier::handleSelectionChange);
+ }
+ break;
+ case 1: {
+ qDebug() << __FUNCTION__ << counter << "Add data to series";
+ QBarDataArray *array = new QBarDataArray;
+ array->reserve(5);
+ for (int i = 0; i < 5; i++) {
+ array->append(new QBarDataRow(10));
+ for (int j = 0; j < 10; j++)
+ (*array->at(i))[j].setValue(i * j);
+ }
+ m_extraSeries->dataProxy()->resetArray(array);
+ }
+ break;
+ case 2: {
+ qDebug() << __FUNCTION__ << counter << "Hide series";
+ m_extraSeries->setVisible(false);
+ }
+ break;
+ case 3: {
+ qDebug() << __FUNCTION__ << counter << "Modify data when hidden";
+ QBarDataArray array;
+ array.reserve(5);
+ for (int i = 0; i < 5; i++) {
+ array.append(new QBarDataRow(10));
+ for (int j = 0; j < 10; j++)
+ (*array.at(i))[j].setValue(2 * i * j);
+ }
+ m_extraSeries->dataProxy()->addRows(array);
+ }
+ break;
+ case 4: {
+ qDebug() << __FUNCTION__ << counter << "Show series again";
+ m_extraSeries->setVisible(true);
+ }
+ break;
+ case 5: {
+ qDebug() << __FUNCTION__ << counter << "Remove series";
+ m_graph->removeSeries(m_extraSeries);
+ delete m_extraSeries;
+ m_extraSeries = 0;
+ }
+ break;
+ default:
+ qDebug() << __FUNCTION__ << "Resetting test";
+ counter = -1;
+ }
+ counter++;
+}
+
+void GraphModifier::testItemAndRowChanges()
+{
+ static int counter = 0;
+ const int rowCount = 12;
+ const int colCount = 10;
+ const float flatValue = 10.0f;
+ static QBar3DSeries *series0 = 0;
+ static QBar3DSeries *series1 = 0;
+ static QBar3DSeries *series2 = 0;
+ QBarDataItem item25;
+ QBarDataItem item50;
+ QBarDataItem item75;
+ item25.setValue(25);
+ item50.setValue(50);
+ item75.setValue(75);
+
+ switch (counter) {
+ case 0: {
+ qDebug() << __FUNCTION__ << counter << "Setup test";
+ releaseSeries();
+ releaseAxes();
+ delete series0;
+ delete series1;
+ delete series2;
+ series0 = new QBar3DSeries;
+ series1 = new QBar3DSeries;
+ series2 = new QBar3DSeries;
+ populateFlatSeries(series0, rowCount, colCount, flatValue);
+ populateFlatSeries(series1, rowCount, colCount, flatValue);
+ populateFlatSeries(series2, rowCount, colCount, flatValue);
+ m_graph->rowAxis()->setRange(4.0f, 8.0f);
+ m_graph->columnAxis()->setRange(3.0f, 6.0f);
+ m_graph->valueAxis()->setRange(0.0f, 100.0f);
+ m_graph->addSeries(series0);
+ m_graph->addSeries(series1);
+ m_graph->addSeries(series2);
+ //counter = 11; // skip single item tests
+ }
+ break;
+ case 1: {
+ qDebug() << __FUNCTION__ << counter << "Change single item, unselected";
+ series0->dataProxy()->setItem(4, 3, item50);
+ }
+ break;
+ case 2: {
+ qDebug() << __FUNCTION__ << counter << "Change single item, selected";
+ series1->setSelectedBar(QPoint(4, 5));
+ series1->dataProxy()->setItem(4, 5, item25);
+ }
+ break;
+ case 3: {
+ qDebug() << __FUNCTION__ << counter << "Change item outside visible area";
+ series1->dataProxy()->setItem(0, 3, item25);
+ }
+ break;
+ case 4: {
+ qDebug() << __FUNCTION__ << counter << "Change single item from two series, unselected";
+ series0->dataProxy()->setItem(5, 3, item25);
+ series1->dataProxy()->setItem(5, 3, item75);
+ }
+ break;
+ case 5: {
+ qDebug() << __FUNCTION__ << counter << "Change single item from two series, one selected";
+ series0->dataProxy()->setItem(5, 4, item25);
+ series1->dataProxy()->setItem(4, 5, item75);
+ }
+ break;
+ case 6: {
+ qDebug() << __FUNCTION__ << counter << "Change single item from two series, one outside range";
+ series0->dataProxy()->setItem(1, 2, item25);
+ series1->dataProxy()->setItem(6, 6, item75);
+ }
+ break;
+ case 7: {
+ qDebug() << __FUNCTION__ << counter << "Change single item from two series, both outside range";
+ series0->dataProxy()->setItem(1, 2, item25);
+ series1->dataProxy()->setItem(8, 8, item75);
+ }
+ break;
+ case 8: {
+ qDebug() << __FUNCTION__ << counter << "Change item to same value";
+ series1->dataProxy()->setItem(6, 6, item75);
+ }
+ break;
+ case 9: {
+ qDebug() << __FUNCTION__ << counter << "Change 3 items on each series";
+ series0->dataProxy()->setItem(7, 3, item25);
+ series0->dataProxy()->setItem(7, 4, item50);
+ series0->dataProxy()->setItem(7, 5, item75);
+ series1->dataProxy()->setItem(6, 3, item25);
+ series1->dataProxy()->setItem(6, 4, item50);
+ series1->dataProxy()->setItem(6, 5, item75);
+ }
+ break;
+ case 10: {
+ qDebug() << __FUNCTION__ << counter << "Level the field single item at a time";
+ QBarDataItem item;
+ item.setValue(15.0f);
+ for (int i = 0; i < rowCount; i++) {
+ for (int j = 0; j < colCount; j++) {
+ series0->dataProxy()->setItem(i, j, item);
+ series1->dataProxy()->setItem(i, j, item);
+ series2->dataProxy()->setItem(i, j, item);
+ }
+ }
+ }
+ break;
+ case 11: {
+ qDebug() << __FUNCTION__ << counter << "Change same items multiple times";
+ series0->dataProxy()->setItem(7, 3, item25);
+ series1->dataProxy()->setItem(7, 3, item25);
+ series0->dataProxy()->setItem(7, 3, item50);
+ series1->dataProxy()->setItem(7, 3, item50);
+ series0->dataProxy()->setItem(7, 3, item75);
+ series1->dataProxy()->setItem(7, 3, item75);
+ }
+ break;
+ case 12: {
+ qDebug() << __FUNCTION__ << counter << "Change row";
+ series0->dataProxy()->setRow(5, createFlatRow(colCount, 50.0f));
+ }
+ break;
+ case 13: {
+ qDebug() << __FUNCTION__ << counter << "Change row with selected item";
+ series1->setSelectedBar(QPoint(6, 6));
+ series1->dataProxy()->setRow(6, createFlatRow(colCount, 40.0f));
+ }
+ break;
+ case 14: {
+ qDebug() << __FUNCTION__ << counter << "Change hidden row";
+ series1->dataProxy()->setRow(9, createFlatRow(colCount, 50.0f));
+ }
+ break;
+ case 15: {
+ qDebug() << __FUNCTION__ << counter << "Change multiple rows singly";
+ series0->dataProxy()->setRow(6, createFlatRow(colCount, 70.0f));
+ series1->dataProxy()->setRow(6, createFlatRow(colCount, 80.0f));
+ series2->dataProxy()->setRow(6, createFlatRow(colCount, 90.0f));
+ }
+ break;
+ case 16: {
+ qDebug() << __FUNCTION__ << counter << "Change multiple rows many at a time";
+ QBarDataArray newRows;
+ newRows.reserve(4);
+ newRows.append(createFlatRow(colCount, 26.0f));
+ newRows.append(createFlatRow(colCount, 30.0f));
+ newRows.append(createFlatRow(colCount, 34.0f));
+ newRows.append(createFlatRow(colCount, 38.0f));
+ series0->dataProxy()->setRows(2, newRows);
+ newRows[0] = createFlatRow(colCount, 26.0f);
+ newRows[1] = createFlatRow(colCount, 30.0f);
+ newRows[2] = createFlatRow(colCount, 34.0f);
+ newRows[3] = createFlatRow(colCount, 38.0f);
+ series1->dataProxy()->setRows(3, newRows);
+ newRows[0] = createFlatRow(colCount, 26.0f);
+ newRows[1] = createFlatRow(colCount, 30.0f);
+ newRows[2] = createFlatRow(colCount, 34.0f);
+ newRows[3] = createFlatRow(colCount, 38.0f);
+ series2->dataProxy()->setRows(4, newRows);
+ }
+ break;
+ case 17: {
+ qDebug() << __FUNCTION__ << counter << "Change same rows multiple times";
+ QBarDataArray newRows;
+ newRows.reserve(4);
+ newRows.append(createFlatRow(colCount, 65.0f));
+ newRows.append(createFlatRow(colCount, 65.0f));
+ newRows.append(createFlatRow(colCount, 65.0f));
+ newRows.append(createFlatRow(colCount, 65.0f));
+ series0->dataProxy()->setRows(4, newRows);
+ newRows[0] = createFlatRow(colCount, 65.0f);
+ newRows[1] = createFlatRow(colCount, 65.0f);
+ newRows[2] = createFlatRow(colCount, 65.0f);
+ newRows[3] = createFlatRow(colCount, 65.0f);
+ series1->dataProxy()->setRows(4, newRows);
+ newRows[0] = createFlatRow(colCount, 65.0f);
+ newRows[1] = createFlatRow(colCount, 65.0f);
+ newRows[2] = createFlatRow(colCount, 65.0f);
+ newRows[3] = createFlatRow(colCount, 65.0f);
+ series2->dataProxy()->setRows(4, newRows);
+ series0->dataProxy()->setRow(6, createFlatRow(colCount, 20.0f));
+ series1->dataProxy()->setRow(6, createFlatRow(colCount, 20.0f));
+ series2->dataProxy()->setRow(6, createFlatRow(colCount, 20.0f));
+ series0->dataProxy()->setRow(6, createFlatRow(colCount, 90.0f));
+ series1->dataProxy()->setRow(6, createFlatRow(colCount, 90.0f));
+ series2->dataProxy()->setRow(6, createFlatRow(colCount, 90.0f));
+ }
+ break;
+ case 18: {
+ qDebug() << __FUNCTION__ << counter << "Change row to different length";
+ series0->dataProxy()->setRow(4, createFlatRow(5, 20.0f));
+ series1->dataProxy()->setRow(4, createFlatRow(0, 20.0f));
+ series2->dataProxy()->setRow(4, 0);
+ }
+ break;
+ case 19: {
+ qDebug() << __FUNCTION__ << counter << "Change selected row shorter so that selected item is no longer valid";
+ series1->dataProxy()->setRow(6, createFlatRow(6, 20.0f));
+ }
+ break;
+ default:
+ qDebug() << __FUNCTION__ << "Resetting test";
+ counter = -1;
+ }
+ counter++;
+}
+
+void GraphModifier::reverseValueAxis(int enabled)
+{
+ m_graph->valueAxis()->setReversed(enabled);
+}
+
+void GraphModifier::setInputHandlerRotationEnabled(int enabled)
+{
+ m_defaultInputHandler->setRotationEnabled(enabled);
+}
+
+void GraphModifier::setInputHandlerZoomEnabled(int enabled)
+{
+ m_defaultInputHandler->setZoomEnabled(enabled);
+}
+
+void GraphModifier::setInputHandlerSelectionEnabled(int enabled)
+{
+ m_defaultInputHandler->setSelectionEnabled(enabled);
+}
+
+void GraphModifier::setInputHandlerZoomAtTargetEnabled(int enabled)
+{
+ m_defaultInputHandler->setZoomAtTargetEnabled(enabled);
+}
+
+void GraphModifier::changeValueAxisSegments(int value)
+{
+ qDebug() << __FUNCTION__ << value;
+ m_segments = value;
+ m_graph->valueAxis()->setSegmentCount(m_segments);
+}
+
+void GraphModifier::insertRemoveTimerTimeout()
+{
+ if (m_insertRemoveStep < 32) {
+ for (int k = 0; k < 1; k++) {
+ QBarDataRow *dataRow = new QBarDataRow(10);
+ for (float i = 0; i < 10; i++)
+ (*dataRow)[i].setValue(((i + 1) / 10.0f) * (float)(rand() % 100));
+
+ QString label = QStringLiteral("Insert %1").arg(insertCounter++);
+ m_dummyData->dataProxy()->insertRow(0, dataRow, label);
+ }
+ } else {
+ for (int k = 0; k < 1; k++)
+ m_dummyData->dataProxy()->removeRows(0, 1);
+ }
+
+ if (m_insertRemoveStep < 16 || (m_insertRemoveStep > 31 && m_insertRemoveStep < 48)) {
+ for (int k = 0; k < 2; k++) {
+ QBarDataRow *dataRow = new QBarDataRow(10);
+ for (float i = 0; i < 10; i++)
+ (*dataRow)[i].setValue(((i + 1) / 10.0f) * (float)(rand() % 100));
+
+ QString label = QStringLiteral("Insert %1").arg(insertCounter++);
+ m_dummyData2->dataProxy()->insertRow(0, dataRow, label);
+ }
+ } else {
+ for (int k = 0; k < 2; k++)
+ m_dummyData2->dataProxy()->removeRows(0, 1);
+ }
+
+ if (m_insertRemoveStep++ > 63)
+ m_insertRemoveStep = 0;
+}
+
+void GraphModifier::triggerSelection()
+{
+ m_graph->scene()->setSelectionQueryPosition(m_customInputHandler->inputPosition());
+}
+
+void GraphModifier::triggerRotation()
+{
+ if (m_selectedSeries) {
+ QPoint selectedBar = m_selectedSeries->selectedBar();
+ if (selectedBar != QBar3DSeries::invalidSelectionPosition()) {
+ QBarDataItem item(*(m_selectedSeries->dataProxy()->itemAt(selectedBar.x(), selectedBar.y())));
+ item.setRotation(item.rotation() + 1.0f);
+ m_selectedSeries->dataProxy()->setItem(selectedBar.x(), selectedBar.y(), item);
+ }
+ } else {
+ // Rotate the first series instead
+ static float seriesAngle = 0.0f;
+ if (m_graph->seriesList().size())
+ m_graph->seriesList().at(0)->setMeshAngle(seriesAngle++);
+ }
+}
+
+void GraphModifier::handleValueAxisLabelsChanged()
+{
+ qDebug() << __FUNCTION__;
+}
+
+void GraphModifier::handleFpsChange(qreal fps)
+{
+ static const QString fpsPrefix(QStringLiteral("FPS: "));
+ m_fpsLabel->setText(fpsPrefix + QString::number(qRound(fps)));
+}
+
+void GraphModifier::setCameraTargetX(int value)
+{
+ // Value is (-100, 100), normalize
+ m_cameraTarget.setX(float(value) / 100.0f);
+ m_graph->scene()->activeCamera()->setTarget(m_cameraTarget);
+ qDebug() << "m_cameraTarget:" << m_cameraTarget;
+}
+
+void GraphModifier::setCameraTargetY(int value)
+{
+ // Value is (-100, 100), normalize
+ m_cameraTarget.setY(float(value) / 100.0f);
+ m_graph->scene()->activeCamera()->setTarget(m_cameraTarget);
+ qDebug() << "m_cameraTarget:" << m_cameraTarget;
+}
+
+void GraphModifier::setCameraTargetZ(int value)
+{
+ // Value is (-100, 100), normalize
+ m_cameraTarget.setZ(float(value) / 100.0f);
+ m_graph->scene()->activeCamera()->setTarget(m_cameraTarget);
+ qDebug() << "m_cameraTarget:" << m_cameraTarget;
+}
+
+void GraphModifier::setFloorLevel(int value)
+{
+ m_graph->setFloorLevel(float(value));
+ qDebug() << "Floor level:" << value;
+}
+
+void GraphModifier::setGraphMargin(int value)
+{
+ m_graph->setMargin(qreal(value) / 100.0);
+ qDebug() << "Setting margin:" << m_graph->margin() << value;
+}
+
+void GraphModifier::populateFlatSeries(QBar3DSeries *series, int rows, int columns, float value)
+{
+ QBarDataArray *dataArray = new QBarDataArray;
+ dataArray->reserve(rows);
+ for (int i = 0; i < rows; i++) {
+ QBarDataRow *dataRow = new QBarDataRow(columns);
+ for (int j = 0; j < columns; j++)
+ (*dataRow)[j].setValue(value);
+ dataArray->append(dataRow);
+ }
+ QStringList axisLabels;
+ int count = qMax(rows, columns);
+ for (int i = 0; i < count; i++)
+ axisLabels << QString::number(i);
+
+ series->dataProxy()->resetArray(dataArray, axisLabels, axisLabels);
+}
+
+QBarDataRow *GraphModifier::createFlatRow(int columns, float value)
+{
+ QBarDataRow *dataRow = new QBarDataRow(columns);
+ for (int j = 0; j < columns; j++)
+ (*dataRow)[j].setValue(value);
+ return dataRow;
+}
+
+void GraphModifier::setBackgroundEnabled(int enabled)
+{
+ m_graph->activeTheme()->setBackgroundEnabled(bool(enabled));
+}
+
+void GraphModifier::setGridEnabled(int enabled)
+{
+ m_graph->activeTheme()->setGridEnabled(bool(enabled));
+}
+
+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);
+}
+
+void GraphModifier::setFpsMeasurement(bool enable)
+{
+ m_graph->setMeasureFps(enable);
+}
+
+void GraphModifier::setSpecsRatio(int barwidth)
+{
+ m_graph->setBarThickness((float)barwidth / 30.0f);
+}
+
+void GraphModifier::setSpacingSpecsX(int spacing)
+{
+ m_barSpacingX = (float)spacing / 100.0f;
+ m_graph->setBarSpacing(QSizeF(m_barSpacingX, m_barSpacingZ));
+}
+
+void GraphModifier::setSpacingSpecsZ(int spacing)
+{
+ m_barSpacingZ = (float)spacing / 100.0f;
+ m_graph->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);
+}
+
+void GraphModifier::setMinY(int min)
+{
+ m_fixedRangeAxis->setMin(min);
+ m_negativeValuesOn = (min < 0) ? true : false;
+ m_minval = min;
+}
+
+void GraphModifier::setMaxY(int max)
+{
+ m_fixedRangeAxis->setMax(max);
+ m_maxval = max;
+}
+
+void GraphModifier::changeColorStyle()
+{
+ int style = m_graph->activeTheme()->colorStyle();
+
+ if (++style > Q3DTheme::ColorStyleRangeGradient)
+ style = Q3DTheme::ColorStyleUniform;
+
+ m_graph->activeTheme()->setColorStyle(Q3DTheme::ColorStyle(style));
+}
+
+void GraphModifier::useOwnTheme()
+{
+ // Own theme is persistent, any changes to it via UI will be remembered
+ if (!m_ownTheme) {
+ m_ownTheme = new Q3DTheme();
+ m_ownTheme->setBackgroundEnabled(true);
+ m_ownTheme->setGridEnabled(true);
+ m_ownTheme->setAmbientLightStrength(0.3f);
+ m_ownTheme->setBackgroundColor(QColor(QRgb(0x99ca53)));
+ QList<QColor> colors;
+ colors.append(QColor(QRgb(0x209fdf)));
+ m_ownTheme->setBaseColors(colors);
+ m_ownTheme->setColorStyle(Q3DTheme::ColorStyleUniform);
+ m_ownTheme->setGridLineColor(QColor(QRgb(0x99ca53)));
+ m_ownTheme->setHighlightLightStrength(7.0f);
+ m_ownTheme->setLabelBackgroundEnabled(true);
+ m_ownTheme->setLabelBorderEnabled(true);
+ m_ownTheme->setLightColor(Qt::white);
+ m_ownTheme->setLightStrength(6.0f);
+ m_ownTheme->setMultiHighlightColor(QColor(QRgb(0x6d5fd5)));
+ m_ownTheme->setSingleHighlightColor(QColor(QRgb(0xf6a625)));
+ m_ownTheme->setLabelBackgroundColor(QColor(0xf6, 0xa6, 0x25, 0xa0));
+ m_ownTheme->setLabelTextColor(QColor(QRgb(0x404044)));
+ m_ownTheme->setWindowColor(QColor(QRgb(0xffffff)));
+ }
+
+ m_graph->setActiveTheme(m_ownTheme);
+
+ m_colorDialog->open();
+}
+
+void GraphModifier::changeBaseColor(const QColor &color)
+{
+ qDebug() << "base color changed to" << color;
+ QList<QColor> colors;
+ colors.append(color);
+ m_graph->activeTheme()->setBaseColors(colors);
+}
+
+void GraphModifier::setGradient()
+{
+ QLinearGradient barGradient(0, 0, 1, 100);
+ barGradient.setColorAt(1.0, Qt::lightGray);
+ barGradient.setColorAt(0.75001, Qt::lightGray);
+ barGradient.setColorAt(0.75, Qt::blue);
+ barGradient.setColorAt(0.50001, Qt::blue);
+ barGradient.setColorAt(0.50, Qt::red);
+ barGradient.setColorAt(0.25001, Qt::red);
+ barGradient.setColorAt(0.25, Qt::yellow);
+ barGradient.setColorAt(0.0, Qt::yellow);
+
+ QLinearGradient singleHighlightGradient(0, 0, 1, 100);
+ singleHighlightGradient.setColorAt(1.0, Qt::white);
+ singleHighlightGradient.setColorAt(0.75, Qt::lightGray);
+ singleHighlightGradient.setColorAt(0.50, Qt::gray);
+ singleHighlightGradient.setColorAt(0.25, Qt::darkGray);
+ singleHighlightGradient.setColorAt(0.0, Qt::black);
+
+ QLinearGradient multiHighlightGradient(0, 0, 1, 100);
+ multiHighlightGradient.setColorAt(1.0, Qt::black);
+ multiHighlightGradient.setColorAt(0.75, Qt::darkBlue);
+ multiHighlightGradient.setColorAt(0.50, Qt::darkRed);
+ multiHighlightGradient.setColorAt(0.25, Qt::darkYellow);
+ multiHighlightGradient.setColorAt(0.0, Qt::darkGray);
+
+ QList<QLinearGradient> barGradients;
+ barGradients.append(barGradient);
+ m_graph->activeTheme()->setBaseGradients(barGradients);
+ m_graph->activeTheme()->setSingleHighlightGradient(singleHighlightGradient);
+ m_graph->activeTheme()->setMultiHighlightGradient(multiHighlightGradient);
+
+ m_graph->activeTheme()->setColorStyle(Q3DTheme::ColorStyleObjectGradient);
+}
+
+void GraphModifier::toggleMultiseriesScaling()
+{
+ m_graph->setMultiSeriesUniform(!m_graph->isMultiSeriesUniform());
+}
+
+void GraphModifier::setReflection(bool enabled)
+{
+ m_graph->setReflection(enabled);
+}
+
+void GraphModifier::setReflectivity(int value)
+{
+ qreal reflectivity = (qreal)value / 100.0;
+ m_graph->setReflectivity(reflectivity);
+}
+
+void GraphModifier::toggleCustomItem()
+{
+ static int counter = 0;
+ int state = ++counter % 3;
+
+ QVector3D positionOne = QVector3D(6.0f, -15.0f, 3.0f);
+ QVector3D positionTwo = QVector3D(2.0f, 18.0f, 3.0f);
+
+ if (state == 0) {
+ m_graph->removeCustomItemAt(positionTwo);
+ } else if (state == 1) {
+ QCustom3DItem *item = new QCustom3DItem();
+ item->setMeshFile(":/shuttle.obj");
+ item->setPosition(positionOne);
+ item->setScaling(QVector3D(0.1f, 0.1f, 0.1f));
+ item->setRotation(QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, rand()));
+ item->setTextureImage(QImage(":/shuttle.png"));
+ m_graph->addCustomItem(item);
+ } else {
+ m_graph->removeCustomItemAt(positionOne);
+ QCustom3DItem *item = new QCustom3DItem();
+ item->setMeshFile(":/shuttle.obj");
+ item->setPosition(positionTwo);
+ item->setScaling(QVector3D(0.1f, 0.1f, 0.1f));
+ item->setRotation(QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, rand()));
+ item->setTextureImage(QImage(":/shuttle.png"));
+ m_graph->addCustomItem(item);
+ }
+}
diff --git a/tests/manual/barstest/chart.h b/tests/manual/barstest/chart.h
new file mode 100644
index 00000000..16bf82a3
--- /dev/null
+++ b/tests/manual/barstest/chart.h
@@ -0,0 +1,190 @@
+/******************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module.
+**
+** $QT_BEGIN_LICENSE:COMM$
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** $QT_END_LICENSE$
+**
+******************************************************************************/
+
+#ifndef CHARTMODIFIER_H
+#define CHARTMODIFIER_H
+
+#include <QtDataVisualization/q3dbars.h>
+#include <QtDataVisualization/q3dinputhandler.h>
+#include <QtDataVisualization/qbar3dseries.h>
+#include <QtDataVisualization/q3dtheme.h>
+#include <QFont>
+#include <QDebug>
+#include <QStringList>
+#include <QPointer>
+#include <QColorDialog>
+#include <QTimer>
+#include <QLabel>
+
+using namespace QtDataVisualization;
+
+class GraphModifier : public QObject
+{
+ Q_OBJECT
+public:
+ explicit GraphModifier(Q3DBars *barchart, QColorDialog *colorDialog);
+ ~GraphModifier();
+
+ void resetTemperatureData();
+ void addRow();
+ void addRows();
+ void insertRow();
+ void insertRows();
+ void changeItem();
+ void changeRow();
+ void changeRows();
+ void removeRow();
+ void removeRows();
+ void changeStyle();
+ void changePresetCamera();
+ void changeTheme();
+ void changeLabelStyle();
+ void changeSelectionMode();
+ void changeFont(const QFont &font);
+ void changeFontSize(int fontsize);
+ void rotateX(int rotation);
+ void rotateY(int rotation);
+ void setFpsMeasurement(bool enable);
+ void setBackgroundEnabled(int enabled);
+ void setGridEnabled(int enabled);
+ 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 setMinY(int min);
+ void setMaxY(int max);
+ void start();
+ void restart(bool dynamicData);
+ void selectBar();
+ void swapAxis();
+ void releaseAxes();
+ void releaseSeries();
+ void createMassiveArray();
+ void useOwnTheme();
+ void changeBaseColor(const QColor &color);
+ void changeColorStyle();
+ void showFiveSeries();
+ QBarDataArray *makeDummyData();
+ void primarySeriesTest();
+ void insertRemoveTestToggle();
+ void toggleRotation();
+ void useLogAxis();
+ void changeValueAxisFormat(const QString & text);
+ void changeLogBase(const QString & text);
+ void setFpsLabel(QLabel *fpsLabel) { m_fpsLabel = fpsLabel; }
+ void addRemoveSeries();
+ void testItemAndRowChanges();
+ void reverseValueAxis(int enabled);
+ void setInputHandlerRotationEnabled(int enabled);
+ void setInputHandlerZoomEnabled(int enabled);
+ void setInputHandlerSelectionEnabled(int enabled);
+ void setInputHandlerZoomAtTargetEnabled(int enabled);
+ void setReflection(bool enabled);
+ void setReflectivity(int value);
+ void toggleCustomItem();
+
+public Q_SLOTS:
+ void flipViews();
+ void setGradient();
+ void toggleMultiseriesScaling();
+ void changeShadowQuality(int quality);
+ void shadowQualityUpdatedByVisual(QAbstract3DGraph::ShadowQuality shadowQuality);
+ void handleSelectionChange(const QPoint &position);
+ void setUseNullInputHandler(bool useNull);
+ void changeValueAxisSegments(int value);
+
+ void handleRowAxisChanged(QCategory3DAxis *axis);
+ void handleColumnAxisChanged(QCategory3DAxis *axis);
+ void handleValueAxisChanged(QValue3DAxis *axis);
+ void handlePrimarySeriesChanged(QBar3DSeries *series);
+
+ void insertRemoveTimerTimeout();
+ void triggerSelection();
+ void triggerRotation();
+ void handleValueAxisLabelsChanged();
+ void handleFpsChange(qreal fps);
+ void setCameraTargetX(int value);
+ void setCameraTargetY(int value);
+ void setCameraTargetZ(int value);
+ void setFloorLevel(int value);
+ void setGraphMargin(int value);
+
+Q_SIGNALS:
+ void shadowQualityChanged(int quality);
+
+private:
+ void populateFlatSeries(QBar3DSeries *series, int rows, int columns, float value);
+ QBarDataRow *createFlatRow(int columns, float value);
+
+ Q3DBars *m_graph;
+ QColorDialog *m_colorDialog;
+ int m_columnCount;
+ int m_rowCount;
+ float m_xRotation;
+ float m_yRotation;
+ bool m_static;
+ float m_barSpacingX;
+ float m_barSpacingZ;
+ int m_fontSize;
+ int m_segments;
+ int m_subSegments;
+ float m_minval;
+ float m_maxval;
+ QStringList m_months;
+ QStringList m_years;
+ QPoint m_selectedBar;
+ QBar3DSeries *m_selectedSeries;
+ QValue3DAxis *m_autoAdjustingAxis;
+ QValue3DAxis *m_fixedRangeAxis;
+ QValue3DAxis *m_temperatureAxis;
+ QCategory3DAxis *m_yearAxis;
+ QCategory3DAxis *m_monthAxis;
+ QCategory3DAxis *m_genericRowAxis;
+ QCategory3DAxis *m_genericColumnAxis;
+ QBar3DSeries *m_temperatureData;
+ QBar3DSeries *m_temperatureData2;
+ QBar3DSeries *m_genericData;
+ QBar3DSeries *m_dummyData;
+ QBar3DSeries *m_dummyData2;
+ QBar3DSeries *m_dummyData3;
+ QBar3DSeries *m_dummyData4;
+ QBar3DSeries *m_dummyData5;
+ QValue3DAxis *m_currentAxis;
+ bool m_negativeValuesOn;
+ bool m_useNullInputHandler;
+ Q3DInputHandler *m_defaultInputHandler;
+ Q3DTheme *m_ownTheme;
+ Q3DTheme *m_builtinTheme;
+ QTimer m_insertRemoveTimer;
+ int m_insertRemoveStep;
+ QAbstract3DInputHandler *m_customInputHandler;
+ QTimer m_selectionTimer;
+ QTimer m_rotationTimer;
+ QLabel *m_fpsLabel;
+ QBar3DSeries *m_extraSeries;
+ QVector3D m_cameraTarget;
+};
+
+#endif
diff --git a/tests/manual/barstest/custominputhandler.cpp b/tests/manual/barstest/custominputhandler.cpp
new file mode 100644
index 00000000..8439981d
--- /dev/null
+++ b/tests/manual/barstest/custominputhandler.cpp
@@ -0,0 +1,57 @@
+/******************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module.
+**
+** $QT_BEGIN_LICENSE:COMM$
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** $QT_END_LICENSE$
+**
+******************************************************************************/
+
+#include "custominputhandler.h"
+
+#include <QtDataVisualization/Q3DCamera>
+
+CustomInputHandler::CustomInputHandler(QObject *parent) :
+ QAbstract3DInputHandler(parent)
+{
+}
+
+//! [0]
+void CustomInputHandler::mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos)
+{
+ Q_UNUSED(event)
+ setInputPosition(mousePos);
+}
+//! [0]
+
+//! [1]
+void CustomInputHandler::wheelEvent(QWheelEvent *event)
+{
+ // Adjust zoom level based on what zoom range we're in.
+ int zoomLevel = scene()->activeCamera()->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;
+
+ scene()->activeCamera()->setZoomLevel(zoomLevel);
+}
+//! [1]
diff --git a/tests/manual/barstest/custominputhandler.h b/tests/manual/barstest/custominputhandler.h
new file mode 100644
index 00000000..d6216e9d
--- /dev/null
+++ b/tests/manual/barstest/custominputhandler.h
@@ -0,0 +1,39 @@
+/******************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module.
+**
+** $QT_BEGIN_LICENSE:COMM$
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** $QT_END_LICENSE$
+**
+******************************************************************************/
+
+#ifndef CUSTOMINPUTHANDLER_H
+#define CUSTOMINPUTHANDLER_H
+
+#include <QtDataVisualization/QAbstract3DInputHandler>
+
+using namespace QtDataVisualization;
+
+class CustomInputHandler : public QAbstract3DInputHandler
+{
+ Q_OBJECT
+public:
+ explicit CustomInputHandler(QObject *parent = 0);
+
+ virtual void mouseMoveEvent(QMouseEvent *event, const QPoint &mousePos);
+ virtual void wheelEvent(QWheelEvent *event);
+};
+
+#endif
diff --git a/tests/manual/barstest/main.cpp b/tests/manual/barstest/main.cpp
new file mode 100644
index 00000000..f4da5f3d
--- /dev/null
+++ b/tests/manual/barstest/main.cpp
@@ -0,0 +1,650 @@
+/******************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module.
+**
+** $QT_BEGIN_LICENSE:COMM$
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** $QT_END_LICENSE$
+**
+******************************************************************************/
+
+#include "chart.h"
+
+#include <QApplication>
+#include <QWidget>
+#include <QHBoxLayout>
+#include <QVBoxLayout>
+#include <QPushButton>
+#include <QCheckBox>
+#include <QSlider>
+#include <QFontComboBox>
+#include <QLabel>
+#include <QScreen>
+#include <QFontDatabase>
+#include <QLinearGradient>
+#include <QPainter>
+#include <QColorDialog>
+#include <QLineEdit>
+#include <QSpinBox>
+#include <QtGui/QOpenGLContext>
+#include <QtDataVisualization/QCustom3DItem>
+#include <QtDataVisualization/QCustom3DLabel>
+#include <QtDataVisualization/QCustom3DVolume>
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+
+ // Test creating custom items before graph is created
+ QCustom3DItem customItem;
+ QCustom3DLabel customLabel;
+ QCustom3DVolume customVolume;
+
+ QWidget *widget = new QWidget;
+ QHBoxLayout *hLayout = new QHBoxLayout(widget);
+ QVBoxLayout *vLayout = new QVBoxLayout();
+ QVBoxLayout *vLayout2 = new QVBoxLayout();
+ QVBoxLayout *vLayout3 = new QVBoxLayout();
+
+ // For testing custom surface format
+ QSurfaceFormat surfaceFormat;
+ surfaceFormat.setDepthBufferSize(24);
+ surfaceFormat.setSamples(8);
+
+ Q3DBars *widgetchart = new Q3DBars(&surfaceFormat);
+ QSize screenSize = widgetchart->screen()->size();
+
+ QWidget *container = QWidget::createWindowContainer(widgetchart);
+ container->setMinimumSize(QSize(screenSize.width() / 3, screenSize.height() / 3));
+ container->setMaximumSize(screenSize);
+ container->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ container->setFocusPolicy(Qt::StrongFocus);
+
+ widget->setWindowTitle(QStringLiteral("Average temperatures in Oulu, Finland (2006-2012)"));
+
+ hLayout->addWidget(container, 1);
+ hLayout->addLayout(vLayout);
+ hLayout->addLayout(vLayout2);
+ hLayout->addLayout(vLayout3);
+
+ QPushButton *addSeriesButton = new QPushButton(widget);
+ addSeriesButton->setText(QStringLiteral("Add / Remove a series"));
+ addSeriesButton->setEnabled(true);
+
+ QPushButton *addDataButton = new QPushButton(widget);
+ addDataButton->setText(QStringLiteral("Add a row of data"));
+ addDataButton->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"));
+ changeSingleDataButton->setEnabled(false);
+
+ QPushButton *changeRowButton = new QPushButton(widget);
+ changeRowButton->setText(QStringLiteral("Change selected row values"));
+ changeRowButton->setEnabled(false);
+
+ QPushButton *changeRowsButton = new QPushButton(widget);
+ changeRowsButton->setText(QStringLiteral("Change three rows from selected"));
+ changeRowsButton->setEnabled(false);
+
+ QPushButton *removeRowButton = new QPushButton(widget);
+ removeRowButton->setText(QStringLiteral("Remove selected row"));
+ removeRowButton->setEnabled(false);
+
+ QPushButton *removeRowsButton = new QPushButton(widget);
+ removeRowsButton->setText(QStringLiteral("Remove three rows before 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"));
+
+ QPushButton *labelButton = new QPushButton(widget);
+ labelButton->setText(QStringLiteral("Change label style"));
+
+ QPushButton *multiScaleButton = new QPushButton(widget);
+ multiScaleButton->setText(QStringLiteral("Change multiseries scaling"));
+
+ 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"));
+
+ 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 *insertRemoveTestButton = new QPushButton(widget);
+ insertRemoveTestButton->setText(QStringLiteral("Toggle insert/remove cycle"));
+ insertRemoveTestButton->setEnabled(true);
+
+ 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);
+
+ QPushButton *flipViewsButton = new QPushButton(widget);
+ flipViewsButton->setText(QStringLiteral("Flip views"));
+ flipViewsButton->setEnabled(true);
+
+ QPushButton *showFiveSeriesButton = new QPushButton(widget);
+ showFiveSeriesButton->setText(QStringLiteral("Try 5 series"));
+ showFiveSeriesButton->setEnabled(true);
+
+ QPushButton *changeColorStyleButton = new QPushButton(widget);
+ changeColorStyleButton->setText(QStringLiteral("Change color style"));
+ changeColorStyleButton->setEnabled(true);
+
+ QPushButton *ownThemeButton = new QPushButton(widget);
+ ownThemeButton->setText(QStringLiteral("Use own theme"));
+ ownThemeButton->setEnabled(true);
+
+ QPushButton *primarySeriesTestsButton = new QPushButton(widget);
+ primarySeriesTestsButton->setText(QStringLiteral("Test primary series"));
+ primarySeriesTestsButton->setEnabled(true);
+
+ QPushButton *toggleRotationButton = new QPushButton(widget);
+ toggleRotationButton->setText(QStringLiteral("Toggle rotation"));
+ toggleRotationButton->setEnabled(true);
+
+ QPushButton *logAxisButton = new QPushButton(widget);
+ logAxisButton->setText(QStringLiteral("Use Log Axis"));
+ logAxisButton->setEnabled(true);
+
+ QPushButton *testItemAndRowChangesButton = new QPushButton(widget);
+ testItemAndRowChangesButton->setText(QStringLiteral("Test Item/Row changing"));
+ testItemAndRowChangesButton->setEnabled(true);
+
+ QColorDialog *colorDialog = new QColorDialog(widget);
+
+ QLinearGradient grBtoY(0, 0, 100, 0);
+ 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(100, 24);
+ QPainter pmp(&pm);
+ pmp.setBrush(QBrush(grBtoY));
+ pmp.setPen(Qt::NoPen);
+ pmp.drawRect(0, 0, 100, 24);
+ QPushButton *gradientBtoYPB = new QPushButton(widget);
+ gradientBtoYPB->setIcon(QIcon(pm));
+ gradientBtoYPB->setIconSize(QSize(100, 24));
+
+ QLabel *fpsLabel = new QLabel(QStringLiteral(""));
+
+ QCheckBox *fpsCheckBox = new QCheckBox(widget);
+ fpsCheckBox->setText(QStringLiteral("Measure Fps"));
+ fpsCheckBox->setChecked(false);
+
+ QCheckBox *reverseValueAxisCheckBox = new QCheckBox(widget);
+ reverseValueAxisCheckBox->setText(QStringLiteral("Reverse value axis"));
+ reverseValueAxisCheckBox->setChecked(false);
+
+ 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);
+
+ QCheckBox *rotationCheckBox = new QCheckBox(widget);
+ rotationCheckBox->setText("Rotate with slider");
+
+ QCheckBox *staticCheckBox = new QCheckBox(widget);
+ staticCheckBox->setText("Use dynamic data");
+ staticCheckBox->setChecked(false);
+
+ QCheckBox *inputHandlerRotationCheckBox = new QCheckBox(widget);
+ inputHandlerRotationCheckBox->setText("IH: Allow rotation");
+ inputHandlerRotationCheckBox->setChecked(true);
+
+ QCheckBox *inputHandlerZoomCheckBox = new QCheckBox(widget);
+ inputHandlerZoomCheckBox->setText("IH: Allow zoom");
+ inputHandlerZoomCheckBox->setChecked(true);
+
+ QCheckBox *inputHandlerSelectionCheckBox = new QCheckBox(widget);
+ inputHandlerSelectionCheckBox->setText("IH: Allow selection");
+ inputHandlerSelectionCheckBox->setChecked(true);
+
+ QCheckBox *inputHandlerZoomAtTargetCheckBox = new QCheckBox(widget);
+ inputHandlerZoomAtTargetCheckBox->setText("IH: setZoomAtTarget");
+ inputHandlerZoomAtTargetCheckBox->setChecked(true);
+
+ 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 *ratioSlider = new QSlider(Qt::Horizontal, widget);
+ ratioSlider->setTickInterval(1);
+ ratioSlider->setMinimum(10);
+ ratioSlider->setValue(30);
+ ratioSlider->setMaximum(100);
+
+ QCheckBox *reflectionCheckBox = new QCheckBox(widget);
+ reflectionCheckBox->setText(QStringLiteral("Show reflections"));
+ reflectionCheckBox->setChecked(false);
+
+ QSlider *reflectivitySlider = new QSlider(Qt::Horizontal, widget);
+ reflectivitySlider->setMinimum(0);
+ reflectivitySlider->setValue(50);
+ reflectivitySlider->setMaximum(100);
+
+ QSlider *floorLevelSlider = new QSlider(Qt::Horizontal, widget);
+ floorLevelSlider->setMinimum(-50);
+ floorLevelSlider->setValue(0);
+ floorLevelSlider->setMaximum(50);
+
+ QPushButton *toggleCustomItemButton = new QPushButton(widget);
+ toggleCustomItemButton->setText(QStringLiteral("Toggle Custom Item"));
+
+ QSlider *spacingSliderX = new QSlider(Qt::Horizontal, widget);
+ spacingSliderX->setTickInterval(1);
+ spacingSliderX->setMinimum(0);
+ spacingSliderX->setValue(10);
+ spacingSliderX->setMaximum(200);
+ QSlider *spacingSliderZ = new QSlider(Qt::Horizontal, widget);
+ spacingSliderZ->setTickInterval(1);
+ spacingSliderZ->setMinimum(0);
+ spacingSliderZ->setValue(10);
+ spacingSliderZ->setMaximum(200);
+
+ QSlider *sampleSliderX = new QSlider(Qt::Horizontal, widget);
+ sampleSliderX->setTickInterval(1);
+ sampleSliderX->setMinimum(1);
+ sampleSliderX->setValue(21);
+ sampleSliderX->setMaximum(200);
+ sampleSliderX->setEnabled(false);
+ QSlider *sampleSliderZ = new QSlider(Qt::Horizontal, widget);
+ sampleSliderZ->setTickInterval(1);
+ sampleSliderZ->setMinimum(1);
+ sampleSliderZ->setValue(21);
+ sampleSliderZ->setMaximum(200);
+ sampleSliderZ->setEnabled(false);
+
+ QSlider *minSliderX = new QSlider(Qt::Horizontal, widget);
+ minSliderX->setTickInterval(10);
+ minSliderX->setTickPosition(QSlider::TicksBelow);
+ minSliderX->setMinimum(0);
+ minSliderX->setValue(0);
+ minSliderX->setMaximum(200);
+ minSliderX->setEnabled(false);
+ QSlider *minSliderZ = new QSlider(Qt::Horizontal, widget);
+ minSliderZ->setTickInterval(10);
+ minSliderZ->setTickPosition(QSlider::TicksAbove);
+ minSliderZ->setMinimum(0);
+ minSliderZ->setValue(0);
+ minSliderZ->setMaximum(200);
+ minSliderZ->setEnabled(false);
+ QSlider *minSliderY = new QSlider(Qt::Horizontal, widget);
+ minSliderY->setTickInterval(10);
+ minSliderY->setTickPosition(QSlider::TicksBelow);
+ minSliderY->setMinimum(-100);
+ minSliderY->setValue(0);
+ minSliderY->setMaximum(100);
+ minSliderY->setEnabled(false);
+ QSlider *maxSliderY = new QSlider(Qt::Horizontal, widget);
+ maxSliderY->setTickInterval(10);
+ maxSliderY->setTickPosition(QSlider::TicksAbove);
+ maxSliderY->setMinimum(-50);
+ maxSliderY->setValue(100);
+ maxSliderY->setMaximum(200);
+ maxSliderY->setEnabled(false);
+
+ QSlider *fontSizeSlider = new QSlider(Qt::Horizontal, widget);
+ fontSizeSlider->setTickInterval(1);
+ fontSizeSlider->setMinimum(1);
+ fontSizeSlider->setValue(20);
+ fontSizeSlider->setMaximum(100);
+
+ QFontComboBox *fontList = new QFontComboBox(widget);
+
+ 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);
+
+ QLineEdit *valueAxisFormatEdit = new QLineEdit(widget);
+ QLineEdit *logBaseEdit = new QLineEdit(widget);
+ QSpinBox *valueAxisSegmentsSpin = new QSpinBox(widget);
+ valueAxisSegmentsSpin->setMinimum(1);
+ valueAxisSegmentsSpin->setMaximum(100);
+ valueAxisSegmentsSpin->setValue(10);
+
+ QSlider *cameraTargetSliderX = new QSlider(Qt::Horizontal, widget);
+ cameraTargetSliderX->setTickInterval(1);
+ cameraTargetSliderX->setMinimum(-100);
+ cameraTargetSliderX->setValue(0);
+ cameraTargetSliderX->setMaximum(100);
+ QSlider *cameraTargetSliderY = new QSlider(Qt::Horizontal, widget);
+ cameraTargetSliderY->setTickInterval(1);
+ cameraTargetSliderY->setMinimum(-100);
+ cameraTargetSliderY->setValue(0);
+ cameraTargetSliderY->setMaximum(100);
+ QSlider *cameraTargetSliderZ = new QSlider(Qt::Horizontal, widget);
+ cameraTargetSliderZ->setTickInterval(1);
+ cameraTargetSliderZ->setMinimum(-100);
+ cameraTargetSliderZ->setValue(0);
+ cameraTargetSliderZ->setMaximum(100);
+
+ QSlider *marginSlider = new QSlider(Qt::Horizontal, widget);
+ marginSlider->setMinimum(-1);
+ marginSlider->setValue(-1);
+ marginSlider->setMaximum(100);
+
+ vLayout->addWidget(addSeriesButton, 0, Qt::AlignTop);
+ 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(showFiveSeriesButton, 0, Qt::AlignTop);
+ vLayout->addWidget(themeButton, 0, Qt::AlignTop);
+ vLayout->addWidget(labelButton, 0, Qt::AlignTop);
+ vLayout->addWidget(multiScaleButton, 0, Qt::AlignTop);
+ vLayout->addWidget(styleButton, 0, Qt::AlignTop);
+ vLayout->addWidget(cameraButton, 0, Qt::AlignTop);
+ vLayout->addWidget(selectionButton, 0, Qt::AlignTop);
+ vLayout->addWidget(setSelectedBarButton, 0, Qt::AlignTop);
+ vLayout->addWidget(swapAxisButton, 0, Qt::AlignTop);
+ vLayout->addWidget(insertRemoveTestButton, 0, Qt::AlignTop);
+ vLayout->addWidget(releaseAxesButton, 0, Qt::AlignTop);
+ vLayout->addWidget(releaseProxiesButton, 1, Qt::AlignTop);
+
+ vLayout2->addWidget(flipViewsButton, 0, Qt::AlignTop);
+ vLayout2->addWidget(changeColorStyleButton, 0, Qt::AlignTop);
+ vLayout2->addWidget(ownThemeButton, 0, Qt::AlignTop);
+ vLayout2->addWidget(primarySeriesTestsButton, 0, Qt::AlignTop);
+ vLayout2->addWidget(toggleRotationButton, 0, Qt::AlignTop);
+ vLayout2->addWidget(gradientBtoYPB, 0, Qt::AlignTop);
+ vLayout2->addWidget(logAxisButton, 0, Qt::AlignTop);
+ vLayout2->addWidget(testItemAndRowChangesButton, 0, 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(minSliderY, 0, Qt::AlignTop);
+ vLayout2->addWidget(maxSliderY, 1, Qt::AlignTop);
+
+ vLayout3->addWidget(fpsLabel, 0, Qt::AlignTop);
+ vLayout3->addWidget(fpsCheckBox, 0, Qt::AlignTop);
+ vLayout3->addWidget(reverseValueAxisCheckBox, 0, Qt::AlignTop);
+ vLayout3->addWidget(backgroundCheckBox, 0, Qt::AlignTop);
+ vLayout3->addWidget(gridCheckBox, 0, Qt::AlignTop);
+ vLayout3->addWidget(inputHandlerRotationCheckBox, 0, Qt::AlignTop);
+ vLayout3->addWidget(inputHandlerZoomCheckBox, 0, Qt::AlignTop);
+ vLayout3->addWidget(inputHandlerSelectionCheckBox, 0, Qt::AlignTop);
+ vLayout3->addWidget(inputHandlerZoomAtTargetCheckBox, 0, Qt::AlignTop);
+ vLayout3->addWidget(new QLabel(QStringLiteral("Adjust shadow quality")), 0, Qt::AlignTop);
+ vLayout3->addWidget(shadowQuality, 0, Qt::AlignTop);
+ vLayout3->addWidget(new QLabel(QStringLiteral("Change font")), 0, Qt::AlignTop);
+ vLayout3->addWidget(fontList, 0, Qt::AlignTop);
+ vLayout3->addWidget(new QLabel(QStringLiteral("Adjust font size")), 0, Qt::AlignTop);
+ vLayout3->addWidget(fontSizeSlider, 0, Qt::AlignTop);
+ vLayout3->addWidget(new QLabel(QStringLiteral("Value axis format")), 0, Qt::AlignTop);
+ vLayout3->addWidget(valueAxisFormatEdit, 0, Qt::AlignTop);
+ vLayout3->addWidget(new QLabel(QStringLiteral("Log axis base")), 0, Qt::AlignTop);
+ vLayout3->addWidget(logBaseEdit, 0, Qt::AlignTop);
+ vLayout3->addWidget(new QLabel(QStringLiteral("Value axis segments")), 0, Qt::AlignTop);
+ vLayout3->addWidget(valueAxisSegmentsSpin, 0, Qt::AlignTop);
+ vLayout3->addWidget(new QLabel(QStringLiteral("Camera target")), 0, Qt::AlignTop);
+ vLayout3->addWidget(cameraTargetSliderX, 0, Qt::AlignTop);
+ vLayout3->addWidget(cameraTargetSliderY, 0, Qt::AlignTop);
+ vLayout3->addWidget(cameraTargetSliderZ, 0, Qt::AlignTop);
+ vLayout3->addWidget(reflectionCheckBox, 0, Qt::AlignTop);
+ vLayout3->addWidget(reflectivitySlider, 0, Qt::AlignTop);
+ vLayout3->addWidget(toggleCustomItemButton, 0, Qt::AlignTop);
+ vLayout3->addWidget(new QLabel(QStringLiteral("Adjust floor level")), 0, Qt::AlignTop);
+ vLayout3->addWidget(floorLevelSlider, 0, Qt::AlignTop);
+ vLayout3->addWidget(new QLabel(QStringLiteral("Adjust margin")), 0, Qt::AlignTop);
+ vLayout3->addWidget(marginSlider, 1, Qt::AlignTop);
+
+ widget->show();
+
+ GraphModifier *modifier = new GraphModifier(widgetchart, colorDialog);
+
+ QObject::connect(rotationSliderX, &QSlider::valueChanged, modifier, &GraphModifier::rotateX);
+ QObject::connect(rotationSliderY, &QSlider::valueChanged, modifier, &GraphModifier::rotateY);
+
+ QObject::connect(ratioSlider, &QSlider::valueChanged, modifier, &GraphModifier::setSpecsRatio);
+
+ QObject::connect(spacingSliderX, &QSlider::valueChanged, modifier,
+ &GraphModifier::setSpacingSpecsX);
+ QObject::connect(spacingSliderZ, &QSlider::valueChanged, modifier,
+ &GraphModifier::setSpacingSpecsZ);
+
+ QObject::connect(sampleSliderX, &QSlider::valueChanged, modifier,
+ &GraphModifier::setSampleCountX);
+ QObject::connect(sampleSliderZ, &QSlider::valueChanged, modifier,
+ &GraphModifier::setSampleCountZ);
+ QObject::connect(minSliderX, &QSlider::valueChanged, modifier,
+ &GraphModifier::setMinX);
+ QObject::connect(minSliderZ, &QSlider::valueChanged, modifier,
+ &GraphModifier::setMinZ);
+ QObject::connect(minSliderY, &QSlider::valueChanged, modifier,
+ &GraphModifier::setMinY);
+ QObject::connect(maxSliderY, &QSlider::valueChanged, modifier,
+ &GraphModifier::setMaxY);
+ QObject::connect(cameraTargetSliderX, &QSlider::valueChanged, modifier,
+ &GraphModifier::setCameraTargetX);
+ QObject::connect(cameraTargetSliderY, &QSlider::valueChanged, modifier,
+ &GraphModifier::setCameraTargetY);
+ QObject::connect(cameraTargetSliderZ, &QSlider::valueChanged, modifier,
+ &GraphModifier::setCameraTargetZ);
+
+ QObject::connect(shadowQuality, SIGNAL(currentIndexChanged(int)), modifier,
+ SLOT(changeShadowQuality(int)));
+ QObject::connect(modifier, &GraphModifier::shadowQualityChanged, shadowQuality,
+ &QComboBox::setCurrentIndex);
+ QObject::connect(fontSizeSlider, &QSlider::valueChanged, modifier,
+ &GraphModifier::changeFontSize);
+ QObject::connect(valueAxisFormatEdit, &QLineEdit::textEdited, modifier,
+ &GraphModifier::changeValueAxisFormat);
+ QObject::connect(logBaseEdit, &QLineEdit::textEdited, modifier,
+ &GraphModifier::changeLogBase);
+ QObject::connect(valueAxisSegmentsSpin, SIGNAL(valueChanged(int)), modifier,
+ SLOT(changeValueAxisSegments(int)));
+
+ QObject::connect(multiScaleButton, &QPushButton::clicked, modifier,
+ &GraphModifier::toggleMultiseriesScaling);
+ QObject::connect(styleButton, &QPushButton::clicked, modifier, &GraphModifier::changeStyle);
+ QObject::connect(cameraButton, &QPushButton::clicked, modifier,
+ &GraphModifier::changePresetCamera);
+ QObject::connect(themeButton, &QPushButton::clicked, modifier, &GraphModifier::changeTheme);
+ QObject::connect(labelButton, &QPushButton::clicked, modifier,
+ &GraphModifier::changeLabelStyle);
+ QObject::connect(addDataButton, &QPushButton::clicked, modifier, &GraphModifier::addRow);
+ QObject::connect(addSeriesButton, &QPushButton::clicked, modifier, &GraphModifier::addRemoveSeries);
+ 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(showFiveSeriesButton, &QPushButton::clicked, modifier, &GraphModifier::showFiveSeries);
+ QObject::connect(selectionButton, &QPushButton::clicked, modifier,
+ &GraphModifier::changeSelectionMode);
+ QObject::connect(setSelectedBarButton, &QPushButton::clicked, modifier,
+ &GraphModifier::selectBar);
+ QObject::connect(swapAxisButton, &QPushButton::clicked, modifier,
+ &GraphModifier::swapAxis);
+ QObject::connect(insertRemoveTestButton, &QPushButton::clicked, modifier,
+ &GraphModifier::insertRemoveTestToggle);
+ QObject::connect(releaseAxesButton, &QPushButton::clicked, modifier,
+ &GraphModifier::releaseAxes);
+ QObject::connect(releaseProxiesButton, &QPushButton::clicked, modifier,
+ &GraphModifier::releaseSeries);
+
+ QObject::connect(flipViewsButton, &QPushButton::clicked, modifier,
+ &GraphModifier::flipViews);
+ QObject::connect(changeColorStyleButton, &QPushButton::clicked, modifier,
+ &GraphModifier::changeColorStyle);
+ QObject::connect(ownThemeButton, &QPushButton::clicked, modifier,
+ &GraphModifier::useOwnTheme);
+ QObject::connect(primarySeriesTestsButton, &QPushButton::clicked, modifier,
+ &GraphModifier::primarySeriesTest);
+ QObject::connect(toggleRotationButton, &QPushButton::clicked, modifier,
+ &GraphModifier::toggleRotation);
+ QObject::connect(logAxisButton, &QPushButton::clicked, modifier,
+ &GraphModifier::useLogAxis);
+ QObject::connect(testItemAndRowChangesButton, &QPushButton::clicked, modifier,
+ &GraphModifier::testItemAndRowChanges);
+ QObject::connect(colorDialog, &QColorDialog::currentColorChanged, modifier,
+ &GraphModifier::changeBaseColor);
+ QObject::connect(gradientBtoYPB, &QPushButton::clicked, modifier,
+ &GraphModifier::setGradient);
+
+ QObject::connect(fontList, &QFontComboBox::currentFontChanged, modifier,
+ &GraphModifier::changeFont);
+
+ QObject::connect(fpsCheckBox, &QCheckBox::stateChanged, modifier,
+ &GraphModifier::setFpsMeasurement);
+ QObject::connect(reverseValueAxisCheckBox, &QCheckBox::stateChanged, modifier,
+ &GraphModifier::reverseValueAxis);
+ QObject::connect(backgroundCheckBox, &QCheckBox::stateChanged, modifier,
+ &GraphModifier::setBackgroundEnabled);
+ QObject::connect(gridCheckBox, &QCheckBox::stateChanged, modifier,
+ &GraphModifier::setGridEnabled);
+ QObject::connect(inputHandlerRotationCheckBox, &QCheckBox::stateChanged, modifier,
+ &GraphModifier::setInputHandlerRotationEnabled);
+ QObject::connect(inputHandlerZoomCheckBox, &QCheckBox::stateChanged, modifier,
+ &GraphModifier::setInputHandlerZoomEnabled);
+ QObject::connect(inputHandlerSelectionCheckBox, &QCheckBox::stateChanged, modifier,
+ &GraphModifier::setInputHandlerSelectionEnabled);
+ QObject::connect(inputHandlerZoomAtTargetCheckBox, &QCheckBox::stateChanged, modifier,
+ &GraphModifier::setInputHandlerZoomAtTargetEnabled);
+ QObject::connect(rotationCheckBox, &QCheckBox::stateChanged, modifier,
+ &GraphModifier::setUseNullInputHandler);
+
+ 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);
+
+ QObject::connect(reflectionCheckBox, &QCheckBox::stateChanged, modifier,
+ &GraphModifier::setReflection);
+ QObject::connect(reflectivitySlider, &QSlider::valueChanged, modifier,
+ &GraphModifier::setReflectivity);
+ QObject::connect(floorLevelSlider, &QSlider::valueChanged, modifier,
+ &GraphModifier::setFloorLevel);
+ QObject::connect(marginSlider, &QSlider::valueChanged, modifier,
+ &GraphModifier::setGraphMargin);
+ QObject::connect(toggleCustomItemButton, &QPushButton::clicked, modifier,
+ &GraphModifier::toggleCustomItem);
+
+ QObject::connect(staticCheckBox, &QCheckBox::stateChanged, addDataButton,
+ &QPushButton::setEnabled);
+ QObject::connect(staticCheckBox, &QCheckBox::stateChanged, addMultiDataButton,
+ &QPushButton::setEnabled);
+ QObject::connect(staticCheckBox, &QCheckBox::stateChanged, insertDataButton,
+ &QPushButton::setEnabled);
+ QObject::connect(staticCheckBox, &QCheckBox::stateChanged, insertMultiDataButton,
+ &QPushButton::setEnabled);
+ QObject::connect(staticCheckBox, &QCheckBox::stateChanged, changeSingleDataButton,
+ &QPushButton::setEnabled);
+ QObject::connect(staticCheckBox, &QCheckBox::stateChanged, changeRowButton,
+ &QPushButton::setEnabled);
+ QObject::connect(staticCheckBox, &QCheckBox::stateChanged, changeRowsButton,
+ &QPushButton::setEnabled);
+ QObject::connect(staticCheckBox, &QCheckBox::stateChanged, removeRowButton,
+ &QPushButton::setEnabled);
+ QObject::connect(staticCheckBox, &QCheckBox::stateChanged, removeRowsButton,
+ &QPushButton::setEnabled);
+ QObject::connect(staticCheckBox, &QCheckBox::stateChanged, massiveArrayButton,
+ &QPushButton::setEnabled);
+ QObject::connect(staticCheckBox, &QCheckBox::stateChanged, sampleSliderX,
+ &QSlider::setEnabled);
+ QObject::connect(staticCheckBox, &QCheckBox::stateChanged, sampleSliderZ,
+ &QSlider::setEnabled);
+ QObject::connect(staticCheckBox, &QCheckBox::stateChanged, minSliderX,
+ &QSlider::setEnabled);
+ QObject::connect(staticCheckBox, &QCheckBox::stateChanged, minSliderZ,
+ &QSlider::setEnabled);
+ QObject::connect(staticCheckBox, &QCheckBox::stateChanged, minSliderY,
+ &QSlider::setEnabled);
+ QObject::connect(staticCheckBox, &QCheckBox::stateChanged, maxSliderY,
+ &QSlider::setEnabled);
+ QObject::connect(staticCheckBox, &QCheckBox::stateChanged, swapAxisButton,
+ &QSlider::setEnabled);
+ QObject::connect(staticCheckBox, &QCheckBox::stateChanged, modifier, &GraphModifier::restart);
+
+ modifier->setFpsLabel(fpsLabel);
+
+ modifier->start();
+
+ return app.exec();
+}
diff --git a/tests/manual/barstest/shuttle.obj b/tests/manual/barstest/shuttle.obj
new file mode 100644
index 00000000..e872228d
--- /dev/null
+++ b/tests/manual/barstest/shuttle.obj
@@ -0,0 +1,6349 @@
+# Blender v2.66 (sub 0) OBJ File: ''
+# www.blender.org
+v -0.290924 -0.416888 -3.733797
+v -0.033253 -0.399965 -3.916942
+v 0.098892 -0.335648 -4.014968
+v 0.110144 -0.419894 -4.016005
+v -0.014627 -0.351984 -3.919619
+v -0.003375 -0.436229 -3.920655
+v 0.077510 -0.338845 -3.987319
+v 0.088762 -0.423090 -3.988356
+v 0.268419 -0.311615 -4.127978
+v 0.279672 -0.395861 -4.129015
+v -0.216945 -0.357152 -3.636585
+v -0.442480 -0.421494 -3.440589
+v 0.040557 -0.350366 -3.819523
+v -0.366883 -0.356351 -3.352865
+v -0.059636 -0.414591 -3.440213
+v 0.195164 -0.388461 -3.624492
+v -0.508658 -0.419445 -3.066802
+v -0.205255 -0.426666 -3.173799
+v -0.446409 -0.327120 -2.985436
+v -0.301084 -0.444031 -2.817294
+v 0.151449 -0.262081 -3.165398
+v 0.405315 -0.264481 -3.348743
+v 0.818570 -0.244023 -3.649532
+v 0.829822 -0.328268 -3.650568
+v 0.438945 -0.298561 -3.337861
+v 0.450197 -0.382806 -3.338897
+v 0.010751 -0.257630 -2.926187
+v 0.476024 -0.294278 -3.283418
+v 0.487276 -0.378524 -3.284455
+v 0.893196 -0.234640 -3.602006
+v 0.904448 -0.318886 -3.603042
+v -0.575146 -0.405155 -2.358083
+v -0.526846 -0.291701 -2.296914
+v -0.123567 -0.205514 -2.586394
+v -0.401501 -0.443667 -2.166967
+v 0.438519 -0.375468 -2.805563
+v 0.688118 -0.342410 -2.991890
+v 0.304996 -0.393955 -2.597466
+v -0.651696 -0.393273 -1.762192
+v -0.615966 -0.265853 -1.716287
+v -0.263638 -0.153966 -1.992210
+v 0.143186 -0.430595 -2.279088
+v -0.512839 -0.438185 -1.613670
+v -0.710028 -0.388098 -1.448538
+v -0.679965 -0.261349 -1.410043
+v -0.813314 -0.388657 -1.206769
+v 0.751287 -0.156495 -2.401505
+v 0.998622 -0.165467 -2.585768
+v -0.031714 -0.447371 -1.755604
+v -0.583894 -0.434779 -1.325088
+v -0.408965 -0.117462 -1.482493
+v -0.790573 -0.268054 -1.169135
+v 0.625851 -0.150158 -2.234187
+v -1.051885 -0.397310 -0.885646
+v -1.031232 -0.284379 -0.851625
+v -0.707410 -0.437077 -1.088477
+v -1.334166 -0.408930 -0.570468
+v 0.404917 -0.087146 -1.938298
+v -0.498689 -0.116097 -1.212783
+v -1.314745 -0.307881 -0.538558
+v -0.959224 -0.446984 -0.774490
+v 1.798825 0.967755 -3.015114
+v 2.046406 0.986555 -3.209870
+v 1.795686 1.006585 -3.015357
+v 2.043267 1.025386 -3.210112
+v 1.806945 0.929656 -3.008470
+v 2.054526 0.948456 -3.203225
+v 1.797665 1.044451 -3.009186
+v 2.045245 1.063251 -3.203941
+v -0.218636 -0.452499 -1.294639
+v -0.644958 -0.132219 -0.977335
+v 1.804675 1.079696 -2.996872
+v 2.052256 1.098496 -3.191627
+v -1.248682 -0.457011 -0.466167
+v 1.840314 0.837931 -2.974904
+v 2.087895 0.856731 -3.169660
+v 1.646588 -0.144702 -2.733368
+v 1.657840 -0.228948 -2.734405
+v 1.737599 -0.131659 -2.805524
+v 1.748852 -0.215905 -2.806561
+v 1.819258 1.148577 -2.971684
+v 1.033279 0.836881 -2.319959
+v 1.031777 0.970096 -2.298396
+v 1.060381 0.758531 -2.296534
+v -0.899523 -0.158764 -0.676483
+v 0.945538 0.814187 -2.200939
+v 0.170080 -0.031614 -1.496071
+v 1.043881 1.032762 -2.270612
+v 0.966443 0.743790 -2.180778
+v 0.952423 0.936921 -2.181507
+v 1.858652 1.239977 -2.912781
+v -0.317238 -0.452926 -1.060344
+v -1.192492 -0.196285 -0.374663
+v 1.856681 0.583228 -2.822182
+v 2.018811 -0.094129 -2.886386
+v 0.967854 0.995533 -2.156932
+v 1.272977 -0.200327 -2.268122
+v 1.284228 -0.284573 -2.269158
+v 1.076506 1.117039 -2.211863
+v -0.484562 -0.458987 -0.834904
+v 1.848687 0.788896 -2.757349
+v 2.078178 -0.164712 -2.848704
+v 1.967059 0.229003 -2.794663
+v 1.967832 0.643840 -2.831535
+v 2.215413 0.662641 -3.026290
+v 0.936685 0.816251 -2.042840
+v 2.039912 0.250063 -2.839813
+v 1.003257 1.074974 -2.104949
+v 1.164321 0.598239 -2.181823
+v 0.950019 0.768391 -2.028775
+v 0.943810 0.900014 -2.031005
+v 2.521226 0.390336 -3.213021
+v 1.936351 1.129229 -2.824698
+v 2.183932 1.148030 -3.019454
+v 2.568967 0.404915 -3.250601
+v 1.055366 0.603082 -2.081103
+v 0.869869 0.465058 -1.923758
+v 0.936491 -0.173930 -1.917023
+v 2.705161 0.067033 -3.318110
+v 2.096944 0.264363 -2.850901
+v 1.957182 0.386704 -2.747152
+v 2.029313 0.077472 -2.774992
+v 0.955724 0.940103 -2.015164
+v 1.928438 1.372002 -2.811322
+v -0.765050 -0.471609 -0.536370
+v 2.030367 0.402476 -2.793896
+v 2.100080 0.103611 -2.820803
+v 2.514476 0.522913 -3.173254
+v 2.574949 0.263657 -3.196595
+v 2.562289 0.536088 -3.211256
+v 2.622122 0.279579 -3.234349
+v 2.598488 0.409527 -3.214962
+v -0.064938 0.006053 -1.100592
+v 2.088244 0.403277 -2.809050
+v 2.151782 0.130884 -2.833575
+v 2.199769 1.159790 -2.964559
+v 2.193588 1.233527 -2.965299
+v 2.221596 1.161935 -2.979915
+v 2.215481 1.234891 -2.980646
+v 2.136538 0.271664 -2.829406
+v 1.137830 1.220917 -2.137315
+v 0.872108 0.654248 -1.875077
+v 0.961190 -0.247342 -1.861737
+v 2.739614 0.051854 -3.275776
+v -2.850674 0.163164 1.082772
+v -2.774223 -0.444295 1.078949
+v -2.508742 -0.433973 0.871016
+v -2.566129 0.205717 0.857016
+v 0.982043 0.994775 -1.981001
+v -1.069794 -0.481435 -0.242789
+v 2.592936 0.518564 -3.182256
+v 2.642673 0.305340 -3.201453
+v -2.926099 0.145051 1.155134
+v -2.869277 -0.451273 1.165592
+v 1.009718 0.673075 -1.961110
+v 2.235091 1.170649 -2.961918
+v 1.045386 1.162465 -2.033586
+v 2.230007 1.231294 -2.962527
+v 2.325998 0.322675 -2.951759
+v 1.972627 1.185781 -2.753756
+v 2.129131 0.389939 -2.793774
+v 2.183229 0.158016 -2.814654
+v 2.227766 1.099078 -2.934829
+v 1.117407 -0.306283 -1.939579
+v 1.981589 1.144577 -2.746340
+v 1.973910 1.228192 -2.748031
+v 2.249297 1.101867 -2.950499
+v 2.210880 1.300532 -2.936848
+v 1.886303 0.951739 -2.651532
+v 2.165588 -0.207364 -2.762840
+v 1.360371 -0.269775 -2.128519
+v 2.232590 1.301186 -2.952497
+v 2.160973 0.274542 -2.798066
+v 0.937019 0.410104 -1.852872
+v 0.960798 0.265444 -1.858128
+v 2.041237 1.191461 -2.784518
+v 2.048705 1.157124 -2.778339
+v 2.042305 1.226803 -2.779748
+v 2.258118 1.120717 -2.937466
+v 2.320933 0.422137 -2.921925
+v 2.366302 0.227636 -2.939436
+v 1.976683 1.431691 -2.744228
+v 2.244230 1.286403 -2.939127
+v -3.086442 -0.474834 1.379359
+v 1.999431 1.110853 -2.726914
+v 1.985242 1.265353 -2.730038
+v -3.023720 -0.458462 1.334241
+v -3.024019 0.109883 1.282283
+v -2.844489 0.344693 1.122684
+v -2.737176 -0.511595 1.117650
+v -2.469550 -0.506414 0.908517
+v -2.551327 0.395732 0.889431
+v 1.000046 -0.329019 -1.811242
+v 2.154800 0.373104 -2.768372
+v 2.199881 0.179835 -2.785773
+v -2.914064 0.322285 1.189905
+v -2.834171 -0.518740 1.204847
+v 1.179604 1.267508 -2.087104
+v 2.051748 1.257770 -2.764754
+v 2.063573 1.129020 -2.762150
+v 2.080589 1.195258 -2.775463
+v -0.196284 0.002337 -0.889996
+v 1.013546 1.060481 -1.927888
+v -3.072142 -0.445996 1.396327
+v 2.603875 0.637948 -3.126857
+v 2.707508 0.193661 -3.166857
+v 2.085482 1.172761 -2.771414
+v 2.081289 1.218414 -2.772337
+v 1.075555 1.201415 -1.986324
+v 2.002330 0.508317 -2.645192
+v 2.127263 -0.027287 -2.693413
+v 2.556508 0.625865 -3.087951
+v 2.661251 0.176820 -3.128379
+v 2.074001 0.520013 -2.695353
+v 2.194747 0.002364 -2.741958
+v 1.000951 0.830916 -1.880131
+v 2.095224 1.154349 -2.760807
+v 2.087476 1.238703 -2.762513
+v 2.023438 1.089743 -2.698434
+v 2.004898 1.291606 -2.702516
+v -3.122983 -0.461461 1.459483
+v -3.158215 -0.041663 1.448402
+v -2.497997 0.004146 0.929450
+v -2.509563 0.149734 0.925099
+v 1.003036 0.858653 -1.877204
+v 2.270079 1.067661 -2.884072
+v 1.005703 0.814744 -1.874867
+v 2.291162 1.070783 -2.900280
+v 2.128013 0.510403 -2.719236
+v 2.238064 0.038604 -2.761713
+v 2.068128 1.279648 -2.741818
+v 2.083579 1.111428 -2.738417
+v 2.247011 1.342852 -2.886831
+v 2.268338 1.343057 -2.903010
+v -2.993610 -0.524459 1.373357
+v -2.994892 0.277606 1.300703
+v 2.627505 0.603237 -3.112099
+v 2.713651 0.233920 -3.145348
+v 2.292918 1.094878 -2.895721
+v 1.006938 0.871768 -1.872413
+v 2.105035 1.197866 -2.757530
+v 2.093582 1.187722 -2.747088
+v 2.092232 1.203828 -2.747250
+v 2.273946 1.321208 -2.897990
+v 0.912103 0.803812 -1.788658
+v 1.019079 -0.292614 -1.771378
+v 2.804159 0.046327 -3.194257
+v 2.107537 1.186366 -2.755460
+v 2.105394 1.209702 -2.755932
+v 2.245164 0.292374 -2.778011
+v 0.747334 -0.381459 -1.545246
+v 2.108331 1.142823 -2.745258
+v 2.098208 1.253036 -2.747486
+v 2.099697 1.174463 -2.740594
+v 2.096009 1.218463 -2.741035
+v 2.112516 1.176954 -2.750038
+v 2.108556 1.220074 -2.750911
+v 1.015678 0.889476 -1.861661
+v 2.162992 0.481149 -2.717304
+v 2.256692 0.079446 -2.753470
+v 1.035607 1.090416 -1.893256
+v 2.119216 1.171063 -2.742090
+v 2.114042 1.227400 -2.743229
+v -3.036469 -0.488219 1.432582
+v 1.026486 0.781917 -1.851175
+v 2.241119 0.356951 -2.758555
+v 2.270656 0.230325 -2.769956
+v -0.400720 -0.022989 -0.663568
+v 2.108939 1.167601 -2.729508
+v 2.352467 0.499374 -2.857929
+v 2.431048 0.162488 -2.888259
+v 2.103901 1.227706 -2.730110
+v 2.078094 0.869479 -2.669583
+v 2.325675 0.888279 -2.864338
+v 2.049954 1.084459 -2.665236
+v 2.029886 1.302955 -2.669655
+v 2.105674 1.107026 -2.710752
+v 2.088951 1.289105 -2.714434
+v 2.107442 1.198835 -2.720560
+v 2.122808 1.139938 -2.727132
+v 2.111851 1.259233 -2.729544
+v 2.126617 1.169588 -2.732825
+v 2.121016 1.230568 -2.734058
+v 2.126010 1.200245 -2.735167
+v 2.126854 1.200309 -2.735831
+v -3.255541 -0.463337 1.614298
+v -3.256979 -0.068785 1.579187
+v -3.090151 -0.525402 1.492390
+v -3.140838 0.071873 1.477060
+v 2.183017 0.449113 -2.704647
+v 2.261101 0.114361 -2.734786
+v 1.025626 0.910940 -1.843900
+v 2.118830 1.168976 -2.716800
+v 2.113792 1.229081 -2.717403
+v 2.133590 1.172756 -2.723654
+v 2.128416 1.229093 -2.724793
+v -2.405642 -0.551479 0.981773
+v -2.505313 0.545503 0.958747
+v 1.032741 0.920593 -1.832253
+v 2.139077 1.180082 -2.715972
+v 2.135116 1.223202 -2.716844
+v 2.126722 1.178219 -2.705876
+v 2.123034 1.222219 -2.706317
+v 2.136451 1.146135 -2.709190
+v 2.126328 1.256348 -2.711419
+v 2.142239 1.190453 -2.710951
+v 2.140096 1.213790 -2.711423
+v 2.330166 1.100055 -2.847870
+v 2.130499 1.192853 -2.699662
+v 2.129149 1.208959 -2.699824
+v 2.142597 1.202290 -2.709353
+v 2.311194 1.326385 -2.850139
+v -0.678415 -0.058034 -0.389918
+v 2.126498 1.116483 -2.683367
+v 2.111047 1.284703 -2.686769
+v 2.335972 1.077011 -2.842714
+v 2.315368 1.073955 -2.825890
+v 2.297923 0.301154 -2.738834
+v 2.313149 1.349285 -2.845444
+v -3.224716 -0.523658 1.644234
+v -3.228977 0.037748 1.596002
+v 2.259607 0.406750 -2.716804
+v 2.310765 0.187427 -2.736550
+v 2.292301 1.349146 -2.828649
+v 1.051190 0.836263 -1.810548
+v 2.074942 1.095809 -2.632374
+v 2.056402 1.297672 -2.636457
+v 1.051411 0.836718 -1.810222
+v 1.051764 0.833314 -1.810103
+v 2.147183 1.160469 -2.694164
+v 2.139435 1.244822 -2.695870
+v 1.051937 0.833724 -1.809843
+v 1.051832 0.835286 -1.809826
+v 1.052011 0.834070 -1.809716
+v 1.052027 0.833906 -1.809712
+v 1.051999 0.834825 -1.809658
+v 1.051961 0.835391 -1.809651
+v 1.052122 0.834297 -1.809553
+v 2.289008 0.296555 -2.724424
+v 1.946327 1.084103 -2.529010
+v 2.264997 -0.237532 -2.656099
+v -3.146048 -0.468059 1.586396
+v 2.295856 0.334163 -2.728890
+v 2.310954 0.269436 -2.734717
+v 2.287534 0.325511 -2.715739
+v 2.300741 0.268886 -2.720837
+v 2.153370 1.180757 -2.684340
+v 2.149177 1.226410 -2.685263
+v -2.995660 -0.411552 1.480706
+v 1.055648 0.923143 -1.800017
+v 2.154070 1.203913 -2.681214
+v -0.987628 -0.106173 -0.106669
+v -3.134648 -0.466717 1.601017
+v 2.142878 1.138361 -2.660432
+v 2.131053 1.267111 -2.663036
+v 2.305306 0.359619 -2.707547
+v 2.331457 0.247507 -2.717641
+v 2.296714 0.347997 -2.697108
+v 2.319591 0.249920 -2.705938
+v 2.094598 1.122062 -2.604852
+v 2.080408 1.276562 -2.607976
+v 0.470274 -0.415629 -1.195124
+v 2.682583 0.683203 -3.020018
+v 2.802250 0.170184 -3.066206
+v 2.692932 0.640855 -3.023288
+v 2.792405 0.214405 -3.061682
+v 2.636060 0.671604 -2.979968
+v 2.757006 0.153092 -3.026651
+v 2.359883 1.134861 -2.806733
+v 2.152321 1.169328 -2.645438
+v 2.145921 1.239007 -2.646847
+v 2.345995 1.300547 -2.808394
+v 2.153390 1.204670 -2.640668
+v 2.412149 0.533689 -2.776916
+v 2.502886 0.144687 -2.811939
+v 0.970224 0.925229 -1.686331
+v 1.091354 -0.325301 -1.665935
+v 2.881699 0.045075 -3.095805
+v 2.371721 1.118882 -2.793227
+v 2.351501 1.116275 -2.775872
+v -3.112347 -0.464090 1.629621
+v 2.105930 1.159222 -2.586859
+v 2.098250 1.242837 -2.588550
+v 2.355013 1.318201 -2.795225
+v 2.334614 1.317729 -2.777893
+v 2.314089 0.357987 -2.673523
+v 2.340505 0.244738 -2.683719
+v 1.104303 1.101391 -1.798523
+v 2.090404 0.561258 -2.516102
+v 2.159124 0.571179 -2.570591
+v 2.234664 -0.057203 -2.571783
+v 2.205596 0.557038 -2.605525
+v 2.229047 0.520855 -2.620486
+v 2.238063 0.482200 -2.623966
+v 2.298549 -0.026551 -2.624406
+v 2.332671 0.012252 -2.654572
+v 2.295672 0.428428 -2.663943
+v 2.328226 0.095662 -2.658767
+v 2.337243 0.057009 -2.662247
+v 2.319328 0.300003 -2.670594
+v 2.323741 0.370700 -2.680527
+v 2.354745 0.175176 -2.686744
+v 2.343450 0.307384 -2.690079
+v 2.353938 0.241245 -2.692182
+v 1.085896 0.905799 -1.761274
+v 2.107213 1.201633 -2.581135
+v 1.172914 1.208536 -1.853034
+v -3.524472 -0.463065 1.962955
+v -3.542270 -0.167984 1.949735
+v 2.374104 1.189970 -2.783334
+v 2.369021 1.250615 -2.783942
+v 1.303689 1.278820 -1.940955
+v -2.749923 0.604098 1.287890
+v -2.601352 -0.583194 1.281085
+v -2.331104 -0.584296 1.070484
+v -2.444929 0.666788 1.044342
+v 2.335002 0.352805 -2.651304
+v 2.357880 0.254727 -2.660134
+v -2.812832 0.575628 1.346300
+v -2.702155 -0.590712 1.367115
+v 2.388829 1.185178 -2.765078
+v 2.382714 1.258133 -2.765809
+v 2.346222 0.364438 -2.655067
+v 2.372374 0.252327 -2.665161
+v 2.368793 1.183281 -2.747422
+v 2.362612 1.257019 -2.748161
+v -3.502416 -0.514638 1.987533
+v -3.528153 -0.092777 1.968860
+v -2.930290 -0.491180 1.547024
+v 2.066685 0.851305 -2.470213
+v -3.080119 -0.460294 1.670958
+v 2.353852 0.333838 -2.636405
+v 2.367060 0.277213 -2.641503
+v 2.140192 0.869385 -2.515599
+v -2.873451 -0.595312 1.528083
+v -2.875654 0.517249 1.427634
+v 2.123721 1.449962 -2.555544
+v 2.366726 0.342510 -2.637991
+v 2.381824 0.277783 -2.643818
+v 2.365586 0.306170 -2.632818
+v 0.180044 -0.433739 -0.860263
+v 2.390810 0.196854 -2.633883
+v 2.339653 0.416178 -2.614137
+v 2.379757 0.310792 -2.633873
+v -2.972414 -0.594417 1.632153
+v -3.043199 0.236465 1.611041
+v 2.197619 0.881876 -2.526829
+v 1.155619 0.140929 -1.644002
+v 2.061041 1.010198 -2.426111
+v 2.124709 0.698580 -2.447134
+v 2.629037 1.066507 -2.869623
+v 2.771686 0.621339 -2.939622
+v 2.857832 0.252023 -2.972872
+v 2.676305 1.087418 -2.904726
+v 2.483987 0.515887 -2.700598
+v 2.562568 0.179001 -2.730927
+v 2.134736 1.022953 -2.472975
+v 2.196270 0.721780 -2.493294
+v -3.115630 -0.588979 1.772415
+v -3.122642 0.192029 1.706162
+v 2.305190 0.463503 -2.547947
+v 2.383274 0.128751 -2.578085
+v 2.026136 1.180204 -2.395136
+v 2.372061 -0.253901 -2.533144
+v 0.043832 -0.439397 -0.700086
+v -2.331525 -0.123197 1.132486
+v 2.610039 1.166097 -2.837585
+v 2.673477 0.969915 -2.869029
+v 2.777325 0.659725 -2.919367
+v 2.880958 0.215439 -2.959367
+v 2.657509 1.185952 -2.873027
+v 2.720273 0.991850 -2.904138
+v 2.379762 0.373280 -2.580731
+v 2.409298 0.246654 -2.592131
+v 2.731814 0.647876 -2.878239
+v 2.836558 0.198831 -2.918667
+v -3.039373 -0.455495 1.723220
+v 2.192646 1.021841 -2.487980
+v 2.248729 0.747345 -2.506499
+v 2.309599 0.498417 -2.529263
+v 2.403300 0.096714 -2.565429
+v 2.237351 0.888547 -2.505383
+v -0.183302 -0.450597 -0.489896
+v 2.405254 0.311230 -2.572676
+v 1.043932 1.013192 -1.572568
+v 1.174857 -0.343976 -1.550015
+v 2.968846 0.048153 -2.984724
+v 2.704206 1.090705 -2.868940
+v 1.193313 1.053879 -1.685613
+v 2.300203 0.530684 -2.498384
+v 2.410253 0.058885 -2.540860
+v -2.870028 -0.379944 1.617982
+v -0.502937 -0.466927 -0.212460
+v 2.262925 0.542265 -2.453038
+v 2.383671 0.024616 -2.499642
+v 2.688581 1.172611 -2.842590
+v 2.740755 1.011263 -2.868450
+v 2.233117 1.007717 -2.472307
+v 2.280868 0.774003 -2.488075
+v -2.681424 0.688036 1.389168
+v -2.372814 0.754289 1.142473
+v -2.249194 -0.603433 1.170773
+v 2.433319 0.963376 -2.621027
+v -2.742923 0.657642 1.444079
+v 2.197806 0.531341 -2.394472
+v 2.322739 -0.004263 -2.442693
+v -3.420844 -0.571247 2.087621
+v -3.456852 0.016609 2.061712
+v 2.261785 0.891425 -2.474043
+v -0.828435 -0.477984 0.061043
+v 2.548733 0.450740 -2.649420
+v 2.594102 0.256238 -2.666930
+v 2.619376 1.253520 -2.777794
+v 2.736592 0.891025 -2.835893
+v 2.666746 1.272449 -2.813868
+v 2.782720 0.913795 -2.871353
+v -2.802757 0.594778 1.513184
+v 2.842664 0.549920 -2.883518
+v 2.892401 0.336695 -2.902714
+v 2.419066 1.038090 -2.596991
+v 2.466659 0.890910 -2.620581
+v 2.366409 0.398028 -2.496960
+v 2.411491 0.204759 -2.514360
+v -3.768498 -0.285858 2.351028
+v -3.754395 -0.436849 2.353898
+v -2.979417 0.290761 1.695520
+v 2.258257 0.990733 -2.446479
+v 2.298049 0.795972 -2.459619
+v -3.744207 -0.468465 2.368351
+v -3.763825 -0.250991 2.363676
+v -2.991889 -0.449902 1.784124
+v 2.589037 0.355701 -2.637096
+v -3.058914 0.242857 1.779885
+v 2.405318 0.303321 -2.484666
+v 2.886850 0.445733 -2.870009
+v 2.109286 1.132686 -2.326646
+v 2.219562 0.592947 -2.363060
+v 2.696261 1.244513 -2.793414
+v 2.792664 0.946380 -2.841198
+v 1.301631 1.132067 -1.690738
+v 2.383062 0.419848 -2.468079
+v 2.437160 0.187925 -2.488959
+v 2.181364 1.141334 -2.376844
+v 2.287943 0.619687 -2.412037
+v 2.862712 0.573808 -2.851874
+v 2.922544 0.317299 -2.874968
+v 2.818116 0.561038 -2.810024
+v 2.878590 0.301782 -2.833364
+v 2.426071 1.103677 -2.552133
+v 2.514010 0.831724 -2.595722
+v 2.235144 1.129736 -2.400364
+v 2.332283 0.654296 -2.432440
+v 2.346390 0.907367 -2.454136
+v -3.411176 0.052851 2.120724
+v 2.429752 0.306199 -2.453326
+v 2.269301 1.099582 -2.397708
+v 2.352008 0.694778 -2.425019
+v 2.386485 0.438404 -2.426523
+v 2.450023 0.166012 -2.451047
+v 2.915866 0.448472 -2.835623
+v 2.344078 0.972432 -2.436077
+v 2.370150 0.844828 -2.444686
+v 2.871840 0.434359 -2.793598
+v -2.786263 -0.483209 1.702896
+v 1.459973 1.193063 -1.759240
+v -3.703011 -0.503725 2.422886
+v -3.730082 -0.199896 2.416091
+v 2.655625 1.315469 -2.699349
+v 2.808775 0.841848 -2.775261
+v 2.702611 1.333742 -2.736255
+v 2.854139 0.865139 -2.811362
+v 2.288410 1.067288 -2.384314
+v 2.357333 0.729951 -2.407073
+v 2.357592 0.441017 -2.374193
+v 2.427305 0.142152 -2.401100
+v 1.807099 1.188967 -2.008747
+v -3.783568 -0.334437 2.490638
+v -3.776477 -0.407414 2.491810
+v 2.122243 1.235844 -2.255761
+v 2.482100 -0.255753 -2.399353
+v 2.726073 1.295463 -2.728897
+v 2.852031 0.905933 -2.791331
+v 2.295756 0.426582 -2.312892
+v 2.367887 0.117350 -2.340733
+v -2.939741 -0.443760 1.851008
+v -3.781106 -0.318610 2.496646
+v -3.771103 -0.424172 2.498541
+v 2.441322 0.304925 -2.409196
+v 2.453266 1.150154 -2.493283
+v 2.568163 0.794829 -2.550234
+v 1.130007 1.063856 -1.452342
+v 1.265938 -0.347821 -1.428686
+v 3.061789 0.055427 -2.865868
+v -2.602579 0.736106 1.497157
+v -2.292120 0.804178 1.248855
+v -2.434953 -0.604050 1.489534
+v -2.163494 -0.608053 1.278256
+v -2.664054 0.704644 1.549387
+v -2.539160 -0.611934 1.572914
+v 2.399283 0.915534 -2.415008
+v -3.707198 -0.182800 2.448233
+v 2.363834 1.022590 -2.395347
+v 2.408991 0.801573 -2.410258
+v -2.722515 -0.616791 1.721958
+v -2.725142 0.639161 1.608672
+v -2.829179 -0.615824 1.810674
+v -2.909245 0.322942 1.786891
+v 2.392228 0.914706 -2.400276
+v 2.398101 0.948794 -2.405777
+v 2.411428 0.883567 -2.410178
+v -2.983486 -0.609514 1.936485
+v -2.991769 0.272910 1.861910
+v 2.388079 0.936458 -2.393279
+v 2.401934 0.893610 -2.400146
+v 1.266405 1.148829 -1.537915
+v 1.276485 1.330618 -1.562468
+v 1.301959 1.399716 -1.588675
+v 1.829089 1.191557 -1.980541
+v 2.385908 3.043540 -2.584738
+v 2.432531 3.084452 -2.624845
+v 2.484531 3.138930 -2.670390
+v 2.555058 3.180480 -2.729192
+v 2.587869 1.699016 -2.618729
+v 2.897153 3.208163 -2.998451
+v 2.950947 3.055532 -3.026375
+v 2.946595 3.189529 -3.035288
+v 2.959600 3.134547 -3.040378
+v 2.417759 0.294566 -2.355182
+v -3.764574 -0.295328 2.521762
+v -3.750702 -0.443027 2.524510
+v 2.358011 0.275051 -2.293223
+v -3.320640 -0.590025 2.214050
+v -3.361390 0.074490 2.184798
+v 2.390117 0.955552 -2.380219
+v 2.415719 0.876379 -2.392909
+v 2.408200 0.974432 -2.384957
+v 2.431282 0.861455 -2.392579
+v -3.753472 -0.287501 2.537197
+v 2.398036 0.969083 -2.363085
+v 2.431485 0.865638 -2.379665
+v -3.651074 -0.516133 2.490283
+v -3.681587 -0.172421 2.482510
+v 2.311849 1.347830 -2.326247
+v -3.741101 -0.282712 2.553676
+v -3.725441 -0.449869 2.556817
+v 2.175858 1.240742 -2.187508
+v 1.176857 1.068079 -1.392566
+v 1.312589 -0.342230 -1.368881
+v -2.560177 0.739860 1.551322
+v -2.121265 -0.602981 1.332435
+v -2.249778 0.807875 1.303072
+v -2.622366 0.708349 1.602724
+v -2.686267 0.642614 1.658664
+v -2.872984 0.326449 1.833357
+v -2.958486 0.276123 1.904730
+v -3.335886 0.076990 2.217503
+v -3.668144 -0.171074 2.499706
+v -3.734634 -0.282056 2.561952
+v -3.734566 -0.369723 2.570150
+v -2.150712 -0.249451 1.324240
+v 1.267079 0.010084 -1.364303
+v 1.704978 -0.191159 -1.687236
+v 2.198494 1.185947 -2.198470
+v 2.267581 1.192809 -2.252964
+v 2.325830 0.562710 -2.240516
+v 2.313725 1.176653 -2.287457
+v 2.336207 1.139528 -2.301576
+v 2.434129 0.098705 -2.282343
+v 2.390649 0.590464 -2.293602
+v 2.344165 1.100576 -2.304204
+v 2.425891 0.627661 -2.324495
+v 2.423750 0.711053 -2.330483
+v 2.431708 0.672101 -2.333111
+v 2.400364 1.044399 -2.342861
+v 2.410625 0.974989 -2.344487
+v 2.420496 0.915260 -2.346699
+v 2.426872 0.985581 -2.358127
+v 2.452506 0.789191 -2.360079
+v 2.446831 0.863022 -2.362433
+v 2.444856 0.921557 -2.366269
+v 2.453526 0.855127 -2.366929
+v 2.496511 1.170443 -2.429398
+v 2.620876 0.785842 -2.491042
+v 2.713268 1.342514 -2.614195
+v 2.759644 1.360499 -2.652004
+v 2.773482 1.317705 -2.658864
+v 2.879037 0.829869 -2.696361
+v 2.909818 0.896081 -2.726441
+v 2.923656 0.853286 -2.733300
+v 2.434469 0.098745 -2.281906
+v -2.120000 -0.602832 1.334057
+v 1.313986 -0.342065 -1.367090
+v 2.435135 0.098824 -2.281052
+v 2.435757 0.098897 -2.280254
+v 2.436307 0.098962 -2.279548
+v 2.436763 0.099016 -2.278964
+v 2.436999 0.099043 -2.278662
+v -2.885212 -0.437337 1.920949
+v -2.717870 -0.356682 1.785125
+v -3.728000 -0.281169 2.570479
+v -3.712341 -0.448326 2.573620
+v -0.735546 -0.053125 0.219066
+v -0.406216 0.000394 -0.041418
+v -0.100273 0.040739 -0.281944
+v 0.172417 0.073341 -0.495491
+v 2.335518 1.350617 -2.295889
+v 0.354290 0.083209 -0.634777
+v -3.623852 -0.512926 2.525198
+v -3.654365 -0.169215 2.517424
+v 2.425971 0.972373 -2.327255
+v 2.459421 0.868929 -2.343834
+v 0.696977 0.054076 -0.892441
+v 2.948120 3.214165 -2.933081
+v 2.606057 3.186486 -2.663780
+v 2.997989 3.195582 -2.969370
+v 2.536222 3.145018 -2.604090
+v 3.012064 3.140727 -2.973088
+v 2.485188 3.090654 -2.557307
+v 1.046458 0.007453 -1.152257
+v -3.714744 -0.282939 2.586870
+v 2.439279 3.049827 -2.516283
+v 3.004908 3.061887 -2.957164
+v 2.449116 0.979252 -2.332477
+v 2.472199 0.866275 -2.340099
+v 1.368491 -0.052711 -1.393705
+v 1.717894 -0.070445 -1.662515
+v 1.478573 -0.058668 -1.476762
+v 2.441737 0.961632 -2.314012
+v 2.467338 0.882459 -2.326701
+v -3.309670 0.080582 2.251135
+v -3.268919 -0.583933 2.280387
+v 2.410137 0.281190 -2.226363
+v -3.701911 -0.287948 2.602134
+v -3.688039 -0.435647 2.604882
+v 2.482991 0.302250 -2.271514
+v 2.455522 0.944402 -2.306774
+v 2.469378 0.901553 -2.313642
+v -2.915858 -0.601549 2.023225
+v -2.924141 0.280876 1.948650
+v 2.468971 0.957141 -2.314878
+v 2.482299 0.891914 -2.319279
+v 2.465229 0.923305 -2.306645
+v -2.755682 -0.607167 1.904943
+v -2.835748 0.331599 1.881160
+v -2.646201 0.648459 1.709923
+v -2.643573 -0.607493 1.823210
+v 2.443879 1.032018 -2.292681
+v 2.489036 0.811001 -2.307592
+v -3.626724 -0.173321 2.551450
+v 2.481117 0.925173 -2.310048
+v -2.579668 0.714584 1.657621
+v -2.454774 -0.601995 1.681149
+v -2.516832 0.746206 1.607137
+v -2.349206 -0.593950 1.599513
+v -2.206373 0.814278 1.358835
+v -2.077747 -0.597953 1.388236
+v 2.667233 1.708364 -2.516935
+v 1.224686 1.075007 -1.330905
+v 1.360617 -0.336670 -1.307250
+v 3.156468 0.066579 -2.744432
+v 2.549224 1.161456 -2.370206
+v 2.664121 0.806131 -2.427157
+v 2.540023 0.316550 -2.282602
+v 1.385180 1.409518 -1.481935
+v -3.679715 -0.306668 2.626691
+v -3.669712 -0.412230 2.628586
+v 1.360989 1.340571 -1.454082
+v 2.400261 0.438891 -2.178853
+v 2.472391 0.129659 -2.206693
+v 2.831269 1.307854 -2.593973
+v 2.957226 0.918323 -2.656406
+v 2.230447 1.248588 -2.116977
+v 2.590304 -0.243009 -2.260568
+v 1.354370 1.159190 -1.425091
+v 1.917054 1.201918 -1.867717
+v -3.673127 -0.321429 2.632291
+v -3.666035 -0.394406 2.633464
+v -2.830682 -0.430915 1.990889
+v 2.473447 0.454663 -2.225597
+v 2.543159 0.155798 -2.252504
+v 2.410583 1.081677 -2.227614
+v 2.479506 0.744341 -2.250373
+v 3.001074 0.449623 -2.628313
+v 2.829160 1.348647 -2.573941
+v 2.980689 0.880044 -2.649048
+v 2.783530 1.330534 -2.535297
+v 2.936681 0.856913 -2.611208
+v 3.051332 0.464469 -2.662340
+v -3.572802 -0.488389 2.589894
+v -3.599872 -0.184558 2.583099
+v 1.591093 1.208507 -1.591064
+v 2.482720 0.988763 -2.258252
+v 2.508792 0.861158 -2.266861
+v 2.531323 0.455464 -2.240752
+v 2.594861 0.183071 -2.265276
+v 2.415908 1.116850 -2.209669
+v 2.498616 0.712046 -2.236978
+v 2.579618 0.323851 -2.261107
+v -2.645182 -0.466535 1.885712
+v 1.939045 1.204508 -1.839511
+v -3.258276 0.070860 2.316835
+v 2.506480 0.926224 -2.248802
+v 2.992383 0.581606 -2.586979
+v 3.052857 0.322350 -2.610320
+v 2.407334 1.150018 -2.179512
+v 2.504473 0.674577 -2.211588
+v 3.042733 0.595054 -2.621444
+v 3.102565 0.338545 -2.644537
+v 2.603378 1.124561 -2.324717
+v 2.691316 0.852608 -2.368305
+v 3.078396 0.468329 -2.624718
+v 2.370287 1.163586 -2.134528
+v 2.476867 0.641940 -2.169721
+v 2.572210 0.442126 -2.225475
+v 2.626308 0.210203 -2.246356
+v 1.491168 1.154391 -1.447635
+v 2.890636 1.267406 -2.544106
+v 2.987040 0.969274 -2.591890
+v 2.788228 0.379194 -2.381967
+v 2.304762 1.155709 -2.075926
+v 2.415038 0.615971 -2.112340
+v 2.604052 0.326729 -2.229767
+v -2.858987 0.266405 2.036315
+v -3.533523 -0.443650 2.638577
+v -3.553141 -0.226176 2.633901
+v 2.469866 1.015657 -2.175067
+v 2.509659 0.820896 -2.188207
+v -2.762138 0.316353 1.974206
+v -2.778535 -0.424773 2.057773
+v 3.071249 0.576878 -2.590723
+v 3.120985 0.363654 -2.609920
+v 2.781708 0.478212 -2.350957
+v 2.827077 0.283710 -2.368468
+v -3.539008 -0.258828 2.645375
+v -3.524905 -0.409819 2.648245
+v 2.597879 0.425291 -2.200073
+v 2.642961 0.232022 -2.217474
+v 2.650729 1.065375 -2.299858
+v 2.698322 0.918196 -2.323448
+v -2.569382 0.622266 1.812512
+v 2.900579 1.299991 -2.513951
+v 3.016554 0.941337 -2.571435
+v 2.855713 1.281357 -2.474664
+v 2.972929 0.918862 -2.532765
+v 2.506130 0.920204 -2.160643
+v -3.173446 -0.542107 2.404937
+v -3.209453 0.045748 2.379028
+v 2.445409 0.560504 -2.076893
+v 2.570342 0.024900 -2.125114
+v -2.493455 0.687025 1.764050
+v 2.684069 0.992910 -2.299412
+v -2.427931 0.717893 1.714301
+v -2.119321 0.784146 1.467606
+v -1.995701 -0.573576 1.495906
+v 2.487048 1.037626 -2.146613
+v 2.534799 0.803912 -2.162379
+v 2.942544 1.202524 -2.516853
+v 2.994718 1.041175 -2.542714
+v 2.517081 0.572200 -2.127054
+v 2.637826 0.054551 -2.173658
+v 2.571093 0.562590 -2.150938
+v 2.681143 0.090791 -2.193414
+v 1.466306 1.086034 -1.335468
+v 2.979094 1.123082 -2.516365
+v -0.568604 -0.447372 0.394570
+v 1.323830 1.046159 -1.213567
+v 1.454755 -0.311009 -1.191014
+v 3.248744 0.081120 -2.625723
+v 2.688243 0.344561 -2.209711
+v -2.593169 -0.347277 1.974947
+v 3.029114 0.682935 -2.497393
+v 3.133857 0.233890 -2.537821
+v 2.530565 0.923082 -2.129303
+v -0.224107 -0.434065 0.145862
+v 3.079074 0.695309 -2.532807
+v 3.182707 0.251022 -2.572807
+v 2.606071 0.533336 -2.149005
+v 2.699770 0.131633 -2.185170
+v 2.490887 1.056969 -2.105453
+v 2.546971 0.782472 -2.123972
+v 2.684199 0.409138 -2.190257
+v 2.713735 0.282512 -2.201657
+v 2.963027 1.221936 -2.481166
+v 3.025790 1.027834 -2.512276
+v 2.918829 1.202466 -2.441528
+v 2.982266 1.006286 -2.472972
+v -2.731051 -0.419180 2.118678
+v 2.346020 1.217882 -1.984849
+v 2.691945 -0.216224 -2.122858
+v 2.626097 0.501300 -2.136348
+v 2.704180 0.166548 -2.166486
+v 2.809263 0.554231 -2.283747
+v 2.887846 0.217345 -2.314077
+v -2.799153 0.230131 2.121073
+v -2.792140 -0.550877 2.187326
+v 0.122037 -0.414552 -0.095656
+v 3.101457 0.660216 -2.517043
+v 3.187603 0.290900 -2.550293
+v 2.461960 1.061494 -2.053272
+v 2.523494 0.760321 -2.073591
+v 3.006995 1.126368 -2.480578
+v 2.963268 1.105875 -2.440934
+v 2.399616 1.050076 -1.991851
+v 2.463283 0.738458 -2.012874
+v 2.541997 0.922437 -2.085123
+v -2.620849 -0.553009 2.083075
+v -2.691633 0.277873 2.061963
+v 0.380138 -0.399580 -0.262083
+v 2.741003 0.353341 -2.170536
+v 2.702686 0.458937 -2.148505
+v 2.753845 0.239614 -2.168251
+v 2.735783 0.349782 -2.158101
+v 2.738935 0.386350 -2.160591
+v 2.754033 0.321623 -2.166418
+v 2.501059 1.494406 -2.071566
+v -2.498046 0.561724 1.911958
+v -2.495843 -0.550836 2.012409
+v 2.518039 0.913888 -2.030968
+v 2.733885 0.378609 -2.149074
+v 2.747093 0.321983 -2.154171
+v 2.457638 0.897352 -1.968773
+v -2.690304 -0.414381 2.170940
+v -3.127855 -0.045628 2.482288
+v -3.102117 -0.467490 2.500962
+v 2.770798 1.227046 -2.232150
+v 2.748385 0.411806 -2.139249
+v 2.774536 0.299695 -2.149342
+v 2.764617 1.300784 -2.232889
+v 2.792626 1.229192 -2.247504
+v -2.409183 0.623172 1.864025
+v -2.298506 -0.543169 1.884841
+v 2.786510 1.302148 -2.248235
+v 2.741907 0.400740 -2.129507
+v 2.764784 0.302663 -2.138337
+v -2.529794 -0.443952 2.062569
+v -2.339763 0.652407 1.813967
+v -2.191192 -0.534884 1.807161
+v -1.920944 -0.535987 1.596561
+v -2.034769 0.715099 1.570418
+v -1.970078 -0.080625 1.596081
+v 1.720073 1.327862 -1.406896
+v 0.572047 -0.387414 -0.352526
+v 2.806120 1.237906 -2.229508
+v 2.801037 1.298551 -2.230116
+v -3.088440 -0.411708 2.522214
+v -3.106239 -0.116627 2.508994
+v 1.609069 1.259907 -1.293617
+v 2.543657 1.253039 -2.021345
+v 1.525799 0.957611 -1.197050
+v 2.757700 0.410246 -2.104644
+v 2.784117 0.296996 -2.114841
+v 2.533483 0.613445 -1.947803
+v 2.602202 0.623366 -2.002292
+v 2.677744 -0.005017 -2.003484
+v 2.648675 0.609224 -2.037226
+v 2.672127 0.573042 -2.052187
+v 2.681143 0.534388 -2.055668
+v 2.741627 0.025636 -2.056106
+v 2.775750 0.064439 -2.086273
+v 2.738751 0.480616 -2.095645
+v 2.771306 0.147849 -2.090468
+v 2.780322 0.109196 -2.093948
+v 2.762407 0.352190 -2.102295
+v 2.766821 0.422887 -2.112228
+v 2.797824 0.227363 -2.118445
+v 2.786530 0.359571 -2.121780
+v 2.797017 0.293432 -2.123883
+v 1.548968 1.153765 -1.228190
+v 2.798795 1.166335 -2.202419
+v 2.552618 1.211834 -2.013930
+v 2.544939 1.295449 -2.015621
+v 2.863513 0.586883 -2.198347
+v 2.954250 0.197881 -2.233369
+v 2.820327 1.169125 -2.218088
+v 2.781909 1.367789 -2.204438
+v 2.803619 1.368443 -2.220086
+v 1.423109 0.978571 -1.105456
+v 1.544240 -0.271959 -1.085059
+v 3.334585 0.098417 -2.514929
+v 1.554716 0.187936 -1.132116
+v 2.612265 1.258718 -2.052108
+v 3.101424 0.726458 -2.383560
+v 3.222370 0.207946 -2.430242
+v -2.658075 -0.410585 2.212276
+v 3.150617 0.738370 -2.420182
+v 3.270283 0.225352 -2.466369
+v 3.160928 0.696012 -2.423422
+v 3.260400 0.269561 -2.461816
+v 2.619734 1.224381 -2.045928
+v 2.613334 1.294060 -2.047338
+v 2.829147 1.187974 -2.205056
+v 2.815259 1.353660 -2.206717
+v 2.570461 1.178110 -1.994503
+v 2.556271 1.332609 -1.997628
+v 2.777033 0.404579 -2.081148
+v 2.799910 0.306502 -2.089978
+v 2.789302 0.416625 -2.086768
+v 2.815452 0.304514 -2.096862
+v 2.634603 1.196277 -2.029740
+v 2.622778 1.325027 -2.032343
+v 2.651619 1.262515 -2.043053
+v 1.554142 0.981857 -1.160642
+v 2.656512 1.240018 -2.039004
+v 2.652319 1.285671 -2.039927
+v -2.635774 -0.407958 2.240880
+v 2.794724 0.385259 -2.065313
+v 2.807933 0.328634 -2.070411
+v 2.809805 0.394697 -2.069692
+v 2.824903 0.329970 -2.075520
+v 2.806035 0.357461 -2.061383
+v -2.489068 -0.351828 2.132329
+v 2.463909 1.145066 -1.865152
+v 2.782581 -0.176570 -1.992240
+v 1.570340 0.895334 -1.144881
+v 1.570297 0.896443 -1.144827
+v 1.570363 0.895879 -1.144798
+v 1.570504 0.894974 -1.144707
+v 1.570489 0.895138 -1.144709
+v 1.570444 0.896371 -1.144649
+v 1.570624 0.894816 -1.144569
+v 2.666254 1.221606 -2.028398
+v 2.658506 1.305960 -2.030103
+v 1.570869 0.894455 -1.144293
+v 1.570594 0.897869 -1.144312
+v 2.594467 1.157000 -1.966023
+v 2.575927 1.358863 -1.970106
+v 1.570894 0.897475 -1.143969
+v 2.833890 0.249041 -2.065584
+v 2.782731 0.468365 -2.045837
+v -2.701300 -0.462008 2.315575
+v -2.705561 0.099398 2.267342
+v 2.841108 1.134918 -2.151662
+v -0.479044 -0.046272 0.545593
+v 2.862191 1.138039 -2.167869
+v 2.822836 0.362979 -2.065575
+v 2.654608 1.178685 -2.006007
+v 2.639158 1.346905 -2.009409
+v -2.624374 -0.406615 2.255502
+v 2.818040 1.410109 -2.154421
+v 2.839368 1.410315 -2.170599
+v 2.863947 1.162135 -2.163311
+v 2.676065 1.265123 -2.025119
+v 2.664612 1.254980 -2.014677
+v 2.663261 1.271085 -2.014839
+v 0.971816 -0.356390 -0.546463
+v 2.844975 1.388465 -2.165580
+v 2.678566 1.253623 -2.023050
+v 2.676423 1.276959 -2.023522
+v 2.679361 1.210080 -2.012848
+v 2.669238 1.320294 -2.015076
+v 2.670727 1.241720 -2.008183
+v 2.667038 1.285720 -2.008625
+v 2.683546 1.244211 -2.017628
+v 2.679586 1.287331 -2.018500
+v 1.579791 0.985026 -1.130600
+v -1.956412 0.610154 1.662774
+v -1.856740 -0.486828 1.685802
+v 2.690246 1.238319 -2.009680
+v 2.685071 1.294657 -2.010819
+v 2.679968 1.234858 -1.997098
+v 2.674930 1.294963 -1.997700
+v -0.132362 0.006287 0.310615
+v 1.590120 0.977428 -1.119874
+v 2.748270 0.515690 -1.979648
+v 2.826352 0.180938 -2.009786
+v -2.571993 0.138873 2.206668
+v -2.521306 -0.458402 2.221998
+v -2.685403 -0.396185 2.345565
+v -2.686840 -0.001633 2.310453
+v 2.620983 1.151716 -1.932826
+v 2.600915 1.370211 -1.937245
+v 2.676704 1.174282 -1.978342
+v 2.659981 1.356362 -1.982024
+v 2.678470 1.266092 -1.988150
+v 2.693838 1.207195 -1.994723
+v 2.682881 1.326489 -1.997135
+v 2.697646 1.236845 -2.000415
+v 2.692045 1.297825 -2.001648
+v 2.697040 1.267502 -2.002758
+v 2.651196 0.936979 -1.934514
+v 2.898778 0.955779 -2.129270
+v 2.929918 0.567420 -2.117638
+v 3.008498 0.230534 -2.147968
+v 2.689859 1.236233 -1.984390
+v 2.684821 1.296338 -1.984993
+v 2.822841 0.425467 -2.012432
+v 2.852378 0.298841 -2.023833
+v 1.608781 0.850501 -1.104316
+v 2.704620 1.240012 -1.991243
+v 2.699446 1.296350 -1.992383
+v 1.624309 1.159754 -1.138181
+v 2.752678 0.550604 -1.960964
+v 2.846378 0.148901 -1.997130
+v 1.606690 0.959087 -1.103622
+v 2.710106 1.247339 -1.983562
+v 2.706145 1.290459 -1.984434
+v 2.697752 1.245476 -1.973465
+v 2.694063 1.289476 -1.973907
+v 2.707481 1.213392 -1.976781
+v 2.697358 1.323606 -1.979010
+v -2.445962 -0.418610 2.191836
+v 3.233725 0.674674 -2.334944
+v 3.319870 0.305357 -2.368193
+v 2.848333 0.363417 -2.004377
+v 2.713269 1.257710 -1.978540
+v 2.711125 1.281046 -1.979012
+v 1.518181 0.875199 -1.011295
+v 1.625158 -0.221229 -0.994015
+v 3.410238 0.117713 -2.416893
+v 2.901195 1.167312 -2.115460
+v 2.701529 1.260111 -1.967251
+v 2.700178 1.276216 -1.967413
+v 2.713626 1.269547 -1.976943
+v 1.616466 0.943560 -1.090626
+v 2.882224 1.393643 -2.117728
+v -2.383910 0.349570 2.084356
+v -2.382627 -0.452496 2.157011
+v 2.697528 1.183740 -1.950957
+v 2.682078 1.351960 -1.954359
+v 2.907001 1.144267 -2.110304
+v 2.886398 1.141212 -2.093480
+v 2.743282 0.582871 -1.930085
+v 2.853333 0.111072 -1.972562
+v 1.623579 0.887518 -1.082372
+v 0.198902 0.047648 0.105888
+v 1.621282 0.931471 -1.084234
+v 2.884178 1.416542 -2.113034
+v 2.863331 1.416404 -2.096239
+v -2.503361 -0.388481 2.254219
+v -2.538594 0.031317 2.243138
+v -1.878374 0.077127 1.724185
+v -1.889940 0.222714 1.719833
+v 2.645971 1.163066 -1.899965
+v 2.627431 1.364929 -1.904047
+v 2.718213 1.227726 -1.961754
+v 2.710466 1.312080 -1.963460
+v 1.626047 0.904541 -1.078374
+v 3.189935 0.700514 -2.275981
+v 3.294679 0.251469 -2.316409
+v 3.238191 0.712702 -2.313742
+v 3.341825 0.268415 -2.353742
+v 2.706004 0.594452 -1.884739
+v 2.826750 0.076803 -1.931343
+v 2.640884 0.583528 -1.826173
+v 2.765818 0.047924 -1.874394
+v 1.714162 1.276631 -1.167239
+v 2.724400 1.248014 -1.951930
+v 2.720207 1.293667 -1.952853
+v 1.654904 1.136021 -1.105274
+v 2.725100 1.271170 -1.948805
+v 2.713907 1.205618 -1.928023
+v 2.702083 1.334368 -1.930626
+v 1.831320 1.344269 -1.251206
+v -2.260945 0.399211 2.027604
+v -2.181051 -0.441814 2.042546
+v 2.809488 0.450216 -1.928661
+v 2.854570 0.256946 -1.946061
+v -2.423567 -0.369548 2.230060
+v -2.180836 0.422861 1.973894
+v -2.073524 -0.433428 1.968859
+v -1.805897 -0.428247 1.759726
+v -1.887675 0.473899 1.740641
+v -2.358199 -0.380076 2.187846
+v -2.358499 0.188271 2.135889
+v 2.990686 0.501054 -2.063247
+v 3.036054 0.306554 -2.080758
+v 2.665627 1.189319 -1.872442
+v 2.651437 1.343818 -1.875567
+v 2.648270 1.510792 -1.882843
+v 2.930912 1.202118 -2.074323
+v 2.723351 1.236585 -1.913028
+v 2.716951 1.306264 -1.914438
+v 2.917024 1.367804 -2.075984
+v 1.384653 -0.306314 -0.725204
+v 2.724420 1.271928 -1.908258
+v 1.621186 0.490687 -0.975352
+v 1.644965 0.346027 -0.980608
+v 0.465380 0.080433 -0.036070
+v 2.848397 0.355508 -1.916368
+v -2.408185 -0.394890 2.251162
+v 2.942750 1.186138 -2.060817
+v 2.578963 1.033323 -1.763117
+v 2.858250 -0.125781 -1.874424
+v 2.922529 1.183532 -2.043463
+v 2.676959 1.226479 -1.854450
+v 2.669279 1.310094 -1.856141
+v 2.926042 1.385458 -2.062815
+v 2.826142 0.472035 -1.899780
+v 2.880239 0.240111 -1.920660
+v 2.905643 1.384987 -2.045482
+v 3.029535 0.405571 -2.049749
+v 3.300344 0.601920 -2.275317
+v 3.350079 0.388695 -2.294513
+v 2.678242 1.268890 -1.848725
+v 2.945134 1.257227 -2.050923
+v 1.755731 1.246131 -1.122488
+v 1.720327 0.756772 -1.049674
+v 2.940050 1.317871 -2.051532
+v -2.214680 0.228844 2.067608
+v -2.157859 -0.367480 2.078067
+v 1.704158 1.079827 -1.054807
+v -2.127781 0.248308 2.009962
+v -2.051331 -0.359151 2.006140
+v -1.843236 0.290860 1.784206
+v -1.785848 -0.348829 1.798208
+v 1.604892 0.740558 -0.935201
+v 1.693974 -0.161033 -0.921860
+v 3.472397 0.138163 -2.335899
+v 1.873536 1.307570 -1.193691
+v 2.872832 0.358386 -1.885027
+v 2.959859 1.252435 -2.032667
+v 2.953743 1.325390 -2.033399
+v 3.342932 0.497244 -2.260519
+v 2.939822 1.250538 -2.015012
+v 2.829564 0.490591 -1.858224
+v 2.893102 0.218199 -1.882748
+v 2.933641 1.324275 -2.015751
+v 1.701154 -0.246228 -0.905127
+v -0.334995 -0.394882 0.699940
+v 3.318333 0.625178 -2.242012
+v 3.378166 0.368670 -2.265106
+v 3.270936 0.612055 -2.203483
+v 3.331410 0.352798 -2.226824
+v 2.870384 0.194339 -1.832802
+v 2.800672 0.493204 -1.805894
+v 2.706330 1.463624 -1.813588
+v 1.735438 1.031940 -1.015094
+v 2.096574 -0.183066 -1.184359
+v 2.738836 0.478769 -1.744593
+v 2.810966 0.169537 -1.772433
+v 1.857375 -0.219119 -0.990222
+v 2.884402 0.357112 -1.840897
+v 3.369567 0.499255 -2.224210
+v 0.704277 0.096803 -0.109143
+v 3.322719 0.484781 -2.185490
+v 1.668063 0.559071 -0.899985
+v 1.734685 -0.079917 -0.893249
+v 3.503355 0.161047 -2.294336
+v 1.853604 0.697100 -1.057274
+v 0.023839 -0.378671 0.476160
+v 2.742703 1.224204 -1.790460
+v 2.990285 1.243004 -1.985215
+v 1.751320 0.995124 -0.995284
+v 1.762367 0.864072 -0.986848
+v 1.978204 0.694100 -1.137927
+v 1.821889 1.171394 -1.054962
+v 2.860838 0.346753 -1.786883
+v 1.768391 0.914212 -0.976082
+v 2.800102 0.741867 -1.764054
+v 3.047683 0.760667 -1.958810
+v 2.801089 0.327237 -1.724923
+v 2.686153 0.887537 -1.683203
+v 2.915644 -0.066074 -1.774558
+v 1.939461 1.218681 -1.105028
+v 0.380965 -0.356962 0.277840
+v 2.157984 -0.096145 -1.130609
+v 2.171539 -0.180007 -1.133476
+v 1.870303 1.101825 -0.999439
+v 2.768902 0.690672 -1.652155
+v 2.931033 0.013315 -1.716360
+v 2.798614 1.350688 -1.707175
+v 1.895380 1.047986 -0.972059
+v -0.263286 -0.086843 0.817096
+v 1.915261 0.855545 -0.963812
+v 1.995518 1.144847 -1.050030
+v 1.923295 0.929349 -0.946858
+v 0.639411 -0.340042 0.173318
+v 2.048910 0.874962 -1.028633
+v 2.024876 1.087065 -1.024636
+v 0.098227 -0.041243 0.603403
+v 1.153992 0.084424 -0.229250
+v 2.057853 0.957558 -1.005829
+v 2.853774 1.270425 -1.644800
+v 2.691514 -0.001160 -1.386453
+v 2.705070 -0.085024 -1.389320
+v 2.781930 0.015918 -1.458515
+v 2.795485 -0.067945 -1.461382
+v 2.889620 0.961520 -1.629051
+v 3.137201 0.980321 -1.823807
+v 2.880562 1.206416 -1.616926
+v 3.128144 1.225217 -1.811681
+v 2.893827 1.173559 -1.603234
+v 3.141408 1.192360 -1.797990
+v -0.165990 -0.329480 0.922774
+v 2.905606 1.059058 -1.599313
+v 3.153188 1.077859 -1.794069
+v 2.902644 1.136966 -1.595558
+v 3.150226 1.155766 -1.790314
+v 2.906628 1.098234 -1.594232
+v 3.154210 1.117035 -1.788988
+v 0.450756 -0.003152 0.428413
+v 0.893967 -0.321301 0.137348
+v 0.203261 -0.310043 0.717218
+v -0.125580 -0.167821 0.986626
+v 0.712336 0.026704 0.345760
+v -0.090811 -0.262476 1.024542
+v 1.652963 0.059929 -0.335038
+v 0.245682 -0.133976 0.786321
+v 0.568430 -0.286725 0.550539
+v 0.283133 -0.240046 0.827356
+v 2.000346 0.011962 -0.463845
+v 0.611741 -0.102875 0.629863
+v 0.998399 0.048451 0.327453
+v 0.827128 -0.268380 0.491359
+v 1.390944 -0.279641 0.074489
+v 2.438757 0.004155 -0.738633
+v 0.652016 -0.215986 0.675288
+v 2.198852 0.014020 -0.544254
+v 0.870584 -0.078559 0.583979
+v 0.910831 -0.196982 0.637049
+v 1.127571 -0.244822 0.495289
+v 1.185795 -0.053488 0.599517
+v 1.535993 0.058149 0.320863
+v 1.947252 -0.218027 0.037437
+v 1.232465 -0.171199 0.659405
+v 2.293159 -0.159573 -0.040558
+v 2.769338 -0.097283 -0.322594
+v 1.695832 -0.196471 0.528473
+v 2.530709 -0.129037 -0.121828
+v 2.157723 0.063260 0.342121
+v 1.776927 -0.020207 0.662777
+v 1.833764 -0.121263 0.736990
+v 3.351091 0.073201 -0.443243
+v 3.364646 -0.010661 -0.446110
+v 2.948324 -0.003291 -0.110055
+v 2.961879 -0.087154 -0.112922
+v 2.992015 0.002089 -0.060870
+v 3.005570 -0.081773 -0.063737
+v 2.525032 0.038738 0.306061
+v 3.379430 0.074900 -0.358922
+v 3.392986 -0.008964 -0.361790
+v 3.036570 0.045434 0.026135
+v 2.796513 0.049478 0.227779
+v 2.357571 -0.130808 0.595337
+v 2.473462 0.016867 0.762129
+v 2.725617 -0.081249 0.592239
+v 2.544662 -0.059737 0.852031
+v 3.261550 -0.027300 0.308389
+v 3.022995 -0.051504 0.513873
+v 2.851826 0.022984 0.782891
+v 3.407963 0.046255 0.499554
+v 2.923753 -0.024800 0.883847
+v 3.168214 0.041578 0.705848
+v 3.711371 0.106264 0.292980
+v 3.724926 0.022401 0.290113
+v 3.531985 0.072015 0.446671
+v 3.545540 -0.011849 0.443804
+v 3.445588 0.055512 0.520889
+v 3.459143 -0.028351 0.518022
+v 3.563503 0.077601 0.432271
+v 3.577058 -0.006262 0.429404
+v 3.488101 0.014784 0.599486
+v 3.249111 0.000073 0.806963
+vt 0.592295 0.226200
+vt 0.597451 0.733993
+vt 0.582117 0.735152
+vt 0.578489 0.226600
+vt 0.583926 0.737917
+vt 0.580317 0.227579
+vt 0.553525 0.740642
+vt 0.440791 0.740508
+vt 0.450875 0.228401
+vt 0.552974 0.228523
+vt 0.390668 0.737686
+vt 0.405291 0.227370
+vt 0.388859 0.734922
+vt 0.403463 0.226391
+vt 0.371983 0.733724
+vt 0.388098 0.225956
+vt 0.619772 0.907170
+vt 0.592331 0.999817
+vt 0.601330 0.999666
+vt 0.610146 0.909999
+vt 0.574598 0.999907
+vt 0.590330 0.911915
+vt 0.553091 0.999969
+vt 0.566105 0.913419
+vt 0.528748 1.000000
+vt 0.538531 0.914447
+vt 0.502634 1.000000
+vt 0.478247 0.914918
+vt 0.475889 0.999968
+vt 0.508812 0.914955
+vt 0.449684 0.999906
+vt 0.448173 0.914340
+vt 0.425163 0.999816
+vt 0.419902 0.913245
+vt 0.403398 0.999703
+vt 0.394672 0.911681
+vt 0.385339 0.999570
+vt 0.373584 0.909717
+vt 0.375862 0.999397
+vt 0.362094 0.906863
+vt 0.605465 0.740602
+vt 0.597205 0.739049
+vt 0.491046 0.731144
+vt 0.490016 0.901745
+vt 0.489949 0.901745
+vt 0.579978 0.737974
+vt 0.489821 0.901745
+vt 0.558870 0.737116
+vt 0.489665 0.901745
+vt 0.534804 0.736510
+vt 0.489489 0.901745
+vt 0.508831 0.736184
+vt 0.489301 0.901744
+vt 0.482087 0.736152
+vt 0.489205 0.901744
+vt 0.455740 0.736416
+vt 0.430942 0.736963
+vt 0.408777 0.737770
+vt 0.390214 0.738801
+vt 0.379997 0.740333
+vt 0.353656 0.886514
+vt 0.378904 0.730193
+vt 0.361705 0.880889
+vt 0.395023 0.727499
+vt 0.380234 0.876591
+vt 0.415254 0.725377
+vt 0.403440 0.873201
+vt 0.438713 0.723920
+vt 0.430309 0.870869
+vt 0.464376 0.723192
+vt 0.459668 0.869695
+vt 0.477566 0.723232
+vt 0.474742 0.869751
+vt 0.491120 0.723224
+vt 0.490232 0.869731
+vt 0.517777 0.724015
+vt 0.520667 0.870977
+vt 0.543181 0.725530
+vt 0.549643 0.873375
+vt 0.566223 0.727704
+vt 0.575892 0.876824
+vt 0.585895 0.730440
+vt 0.598267 0.881171
+vt 0.611334 0.886821
+vt 0.514919 0.001808
+vt 0.498936 0.000000
+vt 0.513858 0.001846
+vt 0.529721 0.013570
+vt 0.531965 0.013618
+vt 0.556734 0.062512
+vt 0.561107 0.062168
+vt 0.573935 0.111992
+vt 0.579743 0.111218
+vt 0.580242 0.134938
+vt 0.586574 0.134186
+vt 0.586077 0.152110
+vt 0.592909 0.152041
+vt 0.591813 0.178477
+vt 0.599157 0.177963
+vt 0.593139 0.193428
+vt 0.600618 0.192699
+vt 0.592908 0.232476
+vt 0.600324 0.231459
+vt 0.496437 0.231529
+vt 0.508654 0.001888
+vt 0.518859 0.013502
+vt 0.535963 0.062914
+vt 0.546664 0.112914
+vt 0.550579 0.135830
+vt 0.554180 0.152166
+vt 0.557666 0.179076
+vt 0.558422 0.194288
+vt 0.558268 0.233688
+vt 0.501777 0.001902
+vt 0.504546 0.013460
+vt 0.508707 0.063079
+vt 0.510973 0.113312
+vt 0.511780 0.136212
+vt 0.512489 0.152160
+vt 0.513077 0.179318
+vt 0.513104 0.194651
+vt 0.512986 0.234213
+vt 0.498076 0.001898
+vt 0.496856 0.013450
+vt 0.494097 0.063062
+vt 0.491870 0.113289
+vt 0.491019 0.136187
+vt 0.490190 0.152133
+vt 0.489240 0.179289
+vt 0.488883 0.194622
+vt 0.488765 0.234184
+vt 0.490954 0.001867
+vt 0.482078 0.013458
+vt 0.466079 0.062831
+vt 0.455287 0.112805
+vt 0.451272 0.135711
+vt 0.447516 0.152039
+vt 0.443646 0.178940
+vt 0.442563 0.194150
+vt 0.442409 0.233550
+vt 0.485218 0.001812
+vt 0.470208 0.013499
+vt 0.443661 0.062377
+vt 0.426084 0.111816
+vt 0.419558 0.134746
+vt 0.413491 0.151904
+vt 0.407324 0.178257
+vt 0.405675 0.193204
+vt 0.405444 0.232252
+vt 0.483722 0.001771
+vt 0.467140 0.013541
+vt 0.437940 0.062021
+vt 0.418694 0.111026
+vt 0.411548 0.133977
+vt 0.404917 0.151817
+vt 0.398200 0.177723
+vt 0.396421 0.192455
+vt 0.396126 0.231215
+vt 0.482807 0.001091
+vt 0.465246 0.012218
+vt 0.434231 0.060860
+vt 0.413722 0.112734
+vt 0.406278 0.130880
+vt 0.397753 0.154535
+vt 0.390718 0.172336
+vt 0.388811 0.184259
+vt 0.483894 0.000866
+vt 0.467479 0.011696
+vt 0.438359 0.060674
+vt 0.419010 0.113922
+vt 0.412060 0.130257
+vt 0.403381 0.155615
+vt 0.396772 0.170695
+vt 0.394947 0.181718
+vt 0.394122 0.224712
+vt 0.489100 0.000562
+vt 0.478265 0.010987
+vt 0.458692 0.060437
+vt 0.445446 0.115578
+vt 0.440842 0.129428
+vt 0.433493 0.157124
+vt 0.429012 0.168469
+vt 0.427688 0.178256
+vt 0.426709 0.223032
+vt 0.492401 0.000471
+vt 0.485112 0.010775
+vt 0.471652 0.060373
+vt 0.462347 0.116094
+vt 0.459225 0.129185
+vt 0.452993 0.157597
+vt 0.449873 0.167802
+vt 0.448880 0.177211
+vt 0.447853 0.222532
+vt 0.495979 0.000427
+vt 0.492542 0.010672
+vt 0.485745 0.060349
+vt 0.480752 0.116370
+vt 0.479235 0.129074
+vt 0.474359 0.157853
+vt 0.472721 0.167476
+vt 0.472093 0.176692
+vt 0.471042 0.222291
+vt 0.497803 0.000430
+vt 0.496333 0.010680
+vt 0.492949 0.060359
+vt 0.490171 0.116373
+vt 0.489471 0.129091
+vt 0.485358 0.157859
+vt 0.484479 0.167501
+vt 0.484040 0.176724
+vt 0.482990 0.222314
+vt 0.499680 0.000431
+vt 0.500232 0.010681
+vt 0.500355 0.060366
+vt 0.499854 0.116392
+vt 0.499996 0.129099
+vt 0.496658 0.157879
+vt 0.496558 0.167505
+vt 0.496314 0.176721
+vt 0.495264 0.222320
+vt 0.503340 0.000484
+vt 0.507844 0.010802
+vt 0.514842 0.060424
+vt 0.518821 0.116161
+vt 0.520601 0.129259
+vt 0.518915 0.157676
+vt 0.520341 0.167887
+vt 0.520484 0.177297
+vt 0.519458 0.222618
+vt 0.506801 0.000583
+vt 0.515045 0.011031
+vt 0.528575 0.060520
+vt 0.536823 0.115687
+vt 0.540149 0.129546
+vt 0.540157 0.157251
+vt 0.543032 0.168605
+vt 0.543547 0.178394
+vt 0.542568 0.223170
+vt 0.512534 0.000900
+vt 0.526992 0.011767
+vt 0.551432 0.060809
+vt 0.566860 0.114099
+vt 0.572744 0.130449
+vt 0.575967 0.155821
+vt 0.581260 0.170915
+vt 0.582411 0.181941
+vt 0.581586 0.224936
+vt 0.514004 0.001128
+vt 0.530070 0.012295
+vt 0.557398 0.061007
+vt 0.574770 0.112926
+vt 0.581304 0.131089
+vt 0.585745 0.154759
+vt 0.591675 0.172575
+vt 0.593008 0.184503
+vt 0.500194 0.123038
+vt 0.538682 0.145632
+vt 0.499355 0.147686
+vt 0.567425 0.437987
+vt 0.495309 0.437689
+vt 0.572058 0.485965
+vt 0.494594 0.485885
+vt 0.579203 0.530428
+vt 0.494130 0.530571
+vt 0.588071 0.564595
+vt 0.493832 0.570346
+vt 0.603460 0.591429
+vt 0.494064 0.596672
+vt 0.634825 0.640783
+vt 0.495158 0.646017
+vt 0.673396 0.693624
+vt 0.496679 0.696159
+vt 0.692678 0.734348
+vt 0.497801 0.742533
+vt 0.702762 0.758051
+vt 0.498113 0.758399
+vt 0.701606 0.793564
+vt 0.498079 0.793255
+vt 0.493311 0.794017
+vt 0.530328 0.123074
+vt 0.571363 0.144013
+vt 0.627653 0.438535
+vt 0.636786 0.486372
+vt 0.650275 0.530678
+vt 0.666763 0.560227
+vt 0.694688 0.587480
+vt 0.750987 0.636789
+vt 0.820060 0.691789
+vt 0.854194 0.727752
+vt 0.872335 0.757923
+vt 0.870198 0.793953
+vt 0.555251 0.123104
+vt 0.591748 0.143109
+vt 0.665577 0.439237
+vt 0.677585 0.487036
+vt 0.695058 0.531278
+vt 0.716302 0.557996
+vt 0.751975 0.585509
+vt 0.823559 0.634725
+vt 0.911312 0.690971
+vt 0.954422 0.723886
+vt 0.977512 0.758039
+vt 0.974704 0.794354
+vt 0.570653 0.123123
+vt 0.596282 0.143062
+vt 0.674482 0.439878
+vt 0.687203 0.487720
+vt 0.705580 0.531920
+vt 0.727870 0.558106
+vt 0.765162 0.585722
+vt 0.839794 0.634825
+vt 0.931229 0.691232
+vt 0.975934 0.723388
+vt 1.000000 0.758335
+vt 0.996949 0.794648
+vt 0.404437 0.142964
+vt 0.426515 0.122951
+vt 0.573874 0.123126
+vt 0.323231 0.439478
+vt 0.310002 0.487319
+vt 0.291306 0.531610
+vt 0.269108 0.558029
+vt 0.232259 0.585436
+vt 0.158605 0.634392
+vt 0.068392 0.690386
+vt 0.024123 0.722737
+vt 0.000000 0.757160
+vt 0.002277 0.793454
+vt 0.408288 0.143022
+vt 0.329678 0.438833
+vt 0.316870 0.486617
+vt 0.298892 0.530832
+vt 0.277591 0.557845
+vt 0.242362 0.585244
+vt 0.172141 0.634290
+vt 0.086185 0.690163
+vt 0.044209 0.723323
+vt 0.021216 0.756939
+vt 0.023503 0.793219
+vt 0.429735 0.122954
+vt 0.428009 0.143973
+vt 0.365185 0.438218
+vt 0.354927 0.486047
+vt 0.340715 0.530335
+vt 0.323958 0.560190
+vt 0.296482 0.587348
+vt 0.241975 0.636524
+vt 0.175315 0.691197
+vt 0.142962 0.727426
+vt 0.125096 0.757073
+vt 0.126941 0.793066
+vt 0.445138 0.122973
+vt 0.460221 0.145670
+vt 0.423771 0.437812
+vt 0.417791 0.485792
+vt 0.409775 0.530252
+vt 0.400446 0.564744
+vt 0.385513 0.591511
+vt 0.356231 0.640793
+vt 0.320514 0.693380
+vt 0.303405 0.734406
+vt 0.293784 0.757604
+vt 0.294807 0.793079
+vt 0.470061 0.123002
+vt 0.584118 0.143846
+vt 0.652512 0.440323
+vt 0.663585 0.488333
+vt 0.679561 0.533226
+vt 0.698964 0.560878
+vt 0.731472 0.587869
+vt 0.796494 0.637100
+vt 0.876085 0.692426
+vt 0.914822 0.726015
+vt 0.935707 0.758515
+vt 0.932883 0.794633
+vt 0.564354 0.123115
+vt 0.557453 0.145374
+vt 0.603941 0.440767
+vt 0.611404 0.489119
+vt 0.622180 0.535513
+vt 0.635332 0.566338
+vt 0.657480 0.591977
+vt 0.701732 0.641506
+vt 0.755840 0.694578
+vt 0.781940 0.731416
+vt 0.796061 0.758682
+vt 0.793893 0.794463
+vt 0.543740 0.123090
+vt 0.520898 0.147383
+vt 0.537164 0.441133
+vt 0.539680 0.489942
+vt 0.543358 0.538385
+vt 0.547975 0.573543
+vt 0.555980 0.597337
+vt 0.571895 0.647283
+vt 0.591287 0.697315
+vt 0.600266 0.738659
+vt 0.605208 0.758809
+vt 0.604010 0.794167
+vt 0.515597 0.123057
+vt 0.480790 0.147467
+vt 0.463733 0.441064
+vt 0.460823 0.489897
+vt 0.456750 0.538466
+vt 0.452065 0.573899
+vt 0.444570 0.597554
+vt 0.429485 0.647493
+vt 0.410904 0.697284
+vt 0.401280 0.738907
+vt 0.396151 0.758578
+vt 0.396067 0.793912
+vt 0.484791 0.123020
+vt 0.444068 0.145371
+vt 0.396343 0.440538
+vt 0.388469 0.488901
+vt 0.377334 0.535405
+vt 0.364191 0.566484
+vt 0.342521 0.591951
+vt 0.299133 0.641406
+vt 0.245883 0.694154
+vt 0.219396 0.731230
+vt 0.205038 0.757996
+vt 0.206019 0.793754
+vt 0.456648 0.122986
+vt 0.417060 0.143778
+vt 0.346645 0.439977
+vt 0.335120 0.487990
+vt 0.318813 0.532980
+vt 0.299476 0.560871
+vt 0.267422 0.587665
+vt 0.203316 0.636772
+vt 0.124729 0.691714
+vt 0.085988 0.725511
+vt 0.064911 0.757495
+vt 0.066727 0.793592
+vt 0.436035 0.122962
+vt 0.495260 0.736170
+vt 0.500696 0.234197
+vt 0.536496 0.234045
+vt 0.577350 0.233157
+vt 0.495655 0.736171
+vt 0.501053 0.234197
+vt 0.464891 0.233960
+vt 0.422300 0.232972
+vt 0.408534 0.223769
+vt 0.563583 0.223955
+vt 0.367604 0.795692
+vt 0.344548 0.863566
+vt 0.343493 0.862334
+vt 0.368659 0.796923
+vt 0.344327 0.876900
+vt 0.343272 0.875668
+vt 0.145143 0.856433
+vt 0.144088 0.855201
+vt 0.144487 0.796170
+vt 0.143432 0.794939
+vt 0.132013 0.795411
+vt 0.130679 0.853014
+vt 0.129623 0.851782
+vt 0.133068 0.796642
+vt 0.006462 0.836828
+vt 0.005407 0.835597
+vt 0.003936 0.813497
+vt 0.002882 0.812266
+vt 0.005457 0.809612
+vt 0.004402 0.808380
+vt 0.004946 0.796489
+vt 0.003891 0.795258
+vt 0.854563 0.797672
+vt 0.853823 0.852194
+vt 0.854872 0.853763
+vt 0.853514 0.796103
+vt 0.978631 0.836386
+vt 0.979680 0.837955
+vt 0.982018 0.813180
+vt 0.983067 0.814749
+vt 0.980641 0.809310
+vt 0.981690 0.810879
+vt 0.981636 0.796256
+vt 0.982685 0.797825
+vt 0.618972 0.797391
+vt 0.639573 0.862183
+vt 0.640622 0.863752
+vt 0.617923 0.795822
+vt 0.639302 0.875450
+vt 0.640350 0.877019
+vt 0.839233 0.855561
+vt 0.840281 0.857130
+vt 0.842114 0.795606
+vt 0.843162 0.797175
+vt 0.341429 0.892018
+vt 0.354422 0.771751
+vt 0.371180 0.771906
+vt 0.361304 0.757630
+vt 0.375583 0.756290
+vt 0.376061 0.747099
+vt 0.386704 0.746114
+vt 0.396022 0.741918
+vt 0.399519 0.741536
+vt 0.406939 0.741656
+vt 0.407021 0.741651
+vt 0.362783 0.891001
+vt 0.382518 0.772090
+vt 0.385281 0.755640
+vt 0.393806 0.745632
+vt 0.401875 0.741347
+vt 0.407053 0.741648
+vt 0.377126 0.890562
+vt 0.415783 0.773053
+vt 0.413937 0.755087
+vt 0.414119 0.745184
+vt 0.408737 0.741153
+vt 0.407022 0.741639
+vt 0.418673 0.890604
+vt 0.457357 0.774594
+vt 0.449912 0.755475
+vt 0.439090 0.745395
+vt 0.417274 0.741201
+vt 0.406885 0.741627
+vt 0.367889 0.778452
+vt 0.364200 0.897177
+vt 0.470167 0.891713
+vt 0.370122 0.761446
+vt 0.381736 0.748731
+vt 0.398612 0.742335
+vt 0.406817 0.741630
+vt 0.341083 0.776828
+vt 0.346977 0.760159
+vt 0.366096 0.747919
+vt 0.393148 0.742062
+vt 0.406985 0.741639
+vt 0.330950 0.895375
+vt 0.334983 0.775889
+vt 0.341985 0.759566
+vt 0.362746 0.747620
+vt 0.391920 0.741975
+vt 0.407026 0.741643
+vt 0.322792 0.894560
+vt 0.337783 0.774019
+vt 0.345386 0.758625
+vt 0.365129 0.747299
+vt 0.392543 0.741914
+vt 0.407019 0.741650
+vt 0.324143 0.893295
+vt 0.342886 0.773061
+vt 0.350401 0.758202
+vt 0.368571 0.747202
+vt 0.393616 0.741910
+vt 0.406994 0.741653
+vt 0.329152 0.892735
+vt 0.606943 0.892335
+vt 0.578997 0.772154
+vt 0.598183 0.772042
+vt 0.576236 0.756530
+vt 0.592545 0.757906
+vt 0.567870 0.746331
+vt 0.580039 0.747342
+vt 0.558973 0.741727
+vt 0.562967 0.742117
+vt 0.553477 0.741826
+vt 0.553572 0.741831
+vt 0.582516 0.891263
+vt 0.566609 0.772310
+vt 0.565670 0.755855
+vt 0.560098 0.745830
+vt 0.556401 0.741531
+vt 0.553436 0.741823
+vt 0.566831 0.890789
+vt 0.533400 0.773194
+vt 0.537139 0.755234
+vt 0.539725 0.745333
+vt 0.549548 0.741322
+vt 0.553438 0.741813
+vt 0.525261 0.890731
+vt 0.494395 0.774638
+vt 0.503451 0.755539
+vt 0.516203 0.745487
+vt 0.541534 0.741350
+vt 0.553540 0.741802
+vt 0.599293 0.897457
+vt 0.597789 0.778726
+vt 0.476853 0.891721
+vt 0.595602 0.761715
+vt 0.582464 0.748970
+vt 0.563094 0.742531
+vt 0.553620 0.741805
+vt 0.620315 0.777161
+vt 0.614992 0.760479
+vt 0.595561 0.748192
+vt 0.567681 0.742270
+vt 0.553478 0.741814
+vt 0.627351 0.895729
+vt 0.624397 0.776234
+vt 0.618175 0.759896
+vt 0.597681 0.747900
+vt 0.568493 0.742185
+vt 0.553449 0.741818
+vt 0.633134 0.894930
+vt 0.618307 0.774354
+vt 0.611745 0.758943
+vt 0.593228 0.747572
+vt 0.567181 0.742122
+vt 0.553475 0.741825
+vt 0.628051 0.893657
+vt 0.611697 0.773381
+vt 0.605318 0.758506
+vt 0.588819 0.747464
+vt 0.565791 0.742115
+vt 0.553508 0.741827
+vt 0.621374 0.893083
+vt 0.467142 0.741480
+vt 0.460043 0.823727
+vt 0.466255 0.823734
+vt 0.491990 0.741510
+vt 0.491102 0.823764
+vt 0.497314 0.823771
+vt 0.459387 0.936839
+vt 0.481806 0.936865
+vt 0.442062 0.996371
+vt 0.457305 0.996390
+vt 0.441061 0.998017
+vt 0.455880 0.998035
+vt 0.440376 0.996388
+vt 0.454893 0.996405
+vt 0.440171 0.989270
+vt 0.454568 0.989287
+vt 0.440732 0.939254
+vt 0.455138 0.939271
+vt 0.441300 0.928768
+vt 0.455901 0.928785
+vt 0.442019 0.920921
+vt 0.456893 0.920939
+vt 0.442564 0.913924
+vt 0.457640 0.913942
+vt 0.463957 0.747884
+vt 0.487465 0.747912
+vt 0.464844 0.743833
+vt 0.488714 0.743862
+vt 0.549439 0.921434
+vt 0.548851 0.918488
+vt 0.544157 0.921323
+vt 0.551271 0.945406
+vt 0.533127 0.945025
+vt 0.552776 0.983628
+vt 0.528590 0.983120
+vt 0.552915 0.990499
+vt 0.528985 0.989997
+vt 0.552488 0.989209
+vt 0.532597 0.988792
+vt 0.540100 0.920799
+vt 0.519194 0.943227
+vt 0.510019 0.980723
+vt 0.510611 0.987626
+vt 0.517323 0.986820
+vt 0.538358 0.920003
+vt 0.513207 0.940494
+vt 0.502039 0.977080
+vt 0.502715 0.984021
+vt 0.510760 0.983824
+vt 0.539395 0.919149
+vt 0.516770 0.937557
+vt 0.506788 0.973165
+vt 0.507415 0.980148
+vt 0.514666 0.980605
+vt 0.542934 0.918463
+vt 0.528929 0.935204
+vt 0.522994 0.970029
+vt 0.523449 0.977045
+vt 0.527995 0.978025
+vt 0.548028 0.918132
+vt 0.546424 0.934066
+vt 0.546314 0.968512
+vt 0.546522 0.975543
+vt 0.547174 0.976777
+vt 0.553310 0.918243
+vt 0.564569 0.934446
+vt 0.570500 0.969019
+vt 0.570451 0.976045
+vt 0.567066 0.977194
+vt 0.557366 0.918766
+vt 0.578501 0.936245
+vt 0.589071 0.971416
+vt 0.588825 0.978417
+vt 0.582340 0.979166
+vt 0.559110 0.919562
+vt 0.584488 0.938978
+vt 0.597051 0.975059
+vt 0.596721 0.982022
+vt 0.588903 0.982162
+vt 0.558072 0.920417
+vt 0.580925 0.941915
+vt 0.592302 0.978974
+vt 0.592022 0.985895
+vt 0.584996 0.985382
+vt 0.554533 0.921102
+vt 0.568767 0.944267
+vt 0.576096 0.982110
+vt 0.575988 0.988998
+vt 0.571668 0.987961
+vt 0.424145 0.921277
+vt 0.423693 0.918338
+vt 0.418870 0.920933
+vt 0.423822 0.945229
+vt 0.405702 0.944048
+vt 0.421388 0.983437
+vt 0.397235 0.981863
+vt 0.420772 0.990308
+vt 0.396875 0.988751
+vt 0.420346 0.989024
+vt 0.400481 0.987729
+vt 0.414819 0.920239
+vt 0.391787 0.941664
+vt 0.378687 0.978685
+vt 0.378524 0.985607
+vt 0.385227 0.985116
+vt 0.413078 0.919381
+vt 0.385807 0.938716
+vt 0.370716 0.974756
+vt 0.370638 0.981719
+vt 0.378671 0.981884
+vt 0.414113 0.918588
+vt 0.389363 0.935994
+vt 0.375457 0.971128
+vt 0.375328 0.978129
+vt 0.382570 0.978900
+vt 0.417648 0.918074
+vt 0.401504 0.934227
+vt 0.391639 0.968773
+vt 0.391339 0.975799
+vt 0.395879 0.976963
+vt 0.422734 0.917975
+vt 0.418975 0.933889
+vt 0.414927 0.968321
+vt 0.414380 0.975353
+vt 0.415032 0.976592
+vt 0.428009 0.918319
+vt 0.437095 0.935070
+vt 0.439080 0.969896
+vt 0.438277 0.976910
+vt 0.434897 0.977887
+vt 0.432060 0.919013
+vt 0.451010 0.937454
+vt 0.457627 0.973073
+vt 0.456628 0.980054
+vt 0.450151 0.980500
+vt 0.433801 0.919872
+vt 0.456990 0.940402
+vt 0.465599 0.977003
+vt 0.464515 0.983942
+vt 0.456707 0.983732
+vt 0.432766 0.920664
+vt 0.453434 0.943124
+vt 0.460858 0.980631
+vt 0.459824 0.987532
+vt 0.452808 0.986716
+vt 0.429231 0.921178
+vt 0.441293 0.944891
+vt 0.444676 0.982987
+vt 0.443813 0.989862
+vt 0.439499 0.988653
+vt 0.489178 0.904955
+vt 0.478920 0.903724
+vt 0.488659 0.905860
+vt 0.513457 0.924223
+vt 0.511674 0.927332
+vt 0.523738 0.959386
+vt 0.521362 0.963531
+vt 0.522949 0.966121
+vt 0.520598 0.970220
+vt 0.515067 0.966111
+vt 0.513113 0.969519
+vt 0.486649 0.906626
+vt 0.504771 0.929961
+vt 0.512160 0.967035
+vt 0.511494 0.973688
+vt 0.505545 0.972402
+vt 0.483455 0.907135
+vt 0.493798 0.931710
+vt 0.497535 0.969367
+vt 0.497023 0.975995
+vt 0.493517 0.974319
+vt 0.479562 0.907310
+vt 0.480427 0.932313
+vt 0.479712 0.970170
+vt 0.479389 0.976790
+vt 0.478859 0.974980
+vt 0.475564 0.907126
+vt 0.466693 0.931678
+vt 0.461405 0.969323
+vt 0.461277 0.975952
+vt 0.463802 0.974284
+vt 0.472068 0.906608
+vt 0.454687 0.929901
+vt 0.445402 0.966955
+vt 0.445442 0.973609
+vt 0.450640 0.972336
+vt 0.469608 0.905838
+vt 0.446236 0.927254
+vt 0.434137 0.963426
+vt 0.434297 0.970118
+vt 0.441375 0.969434
+vt 0.468558 0.904931
+vt 0.442627 0.924138
+vt 0.429327 0.959274
+vt 0.429538 0.966009
+vt 0.437419 0.966018
+vt 0.469077 0.904026
+vt 0.444410 0.921030
+vt 0.431703 0.955130
+vt 0.431889 0.961909
+vt 0.439374 0.962610
+vt 0.471086 0.903260
+vt 0.451313 0.918400
+vt 0.440904 0.951625
+vt 0.440993 0.958442
+vt 0.446941 0.959728
+vt 0.474281 0.902751
+vt 0.462285 0.916651
+vt 0.455530 0.949294
+vt 0.455463 0.956135
+vt 0.458970 0.957810
+vt 0.478174 0.902575
+vt 0.475656 0.916048
+vt 0.473353 0.948490
+vt 0.473097 0.955340
+vt 0.473628 0.957150
+vt 0.482172 0.902760
+vt 0.489391 0.916684
+vt 0.491660 0.949337
+vt 0.491210 0.956177
+vt 0.488685 0.957846
+vt 0.485667 0.903278
+vt 0.501397 0.918460
+vt 0.507663 0.951705
+vt 0.507044 0.958521
+vt 0.501847 0.959794
+vt 0.488128 0.904048
+vt 0.509848 0.921108
+vt 0.518928 0.955234
+vt 0.518190 0.962012
+vt 0.511111 0.962696
+vt 0.490402 0.906636
+vt 0.478826 0.907307
+vt 0.488446 0.905821
+vt 0.501508 0.904625
+vt 0.497682 0.903031
+vt 0.513572 0.898392
+vt 0.507734 0.895959
+vt 0.520474 0.898400
+vt 0.513468 0.895480
+vt 0.527756 0.896328
+vt 0.519527 0.892898
+vt 0.532641 0.890349
+vt 0.523612 0.886586
+vt 0.534751 0.880504
+vt 0.525409 0.876611
+vt 0.483918 0.905221
+vt 0.488823 0.901856
+vt 0.494212 0.894166
+vt 0.497242 0.893329
+vt 0.500470 0.890372
+vt 0.502703 0.883814
+vt 0.503775 0.873743
+vt 0.478030 0.904996
+vt 0.477305 0.901416
+vt 0.476632 0.893495
+vt 0.476145 0.892524
+vt 0.475691 0.889426
+vt 0.475516 0.882776
+vt 0.475646 0.872669
+vt 0.472360 0.905207
+vt 0.466213 0.901829
+vt 0.459702 0.894125
+vt 0.455830 0.893280
+vt 0.451831 0.890314
+vt 0.449337 0.883750
+vt 0.448558 0.873677
+vt 0.468427 0.905797
+vt 0.458520 0.902984
+vt 0.447960 0.895887
+vt 0.441739 0.895394
+vt 0.435282 0.892798
+vt 0.431179 0.886476
+vt 0.429771 0.876497
+vt 0.467286 0.906609
+vt 0.456287 0.904571
+vt 0.444552 0.898310
+vt 0.437650 0.898301
+vt 0.430478 0.896212
+vt 0.425909 0.890222
+vt 0.424318 0.880373
+vt 0.469241 0.907423
+vt 0.460112 0.906165
+vt 0.450390 0.900743
+vt 0.444656 0.901221
+vt 0.438707 0.899641
+vt 0.434938 0.893984
+vt 0.433660 0.884266
+vt 0.473770 0.908024
+vt 0.468971 0.907340
+vt 0.463912 0.902535
+vt 0.460882 0.903372
+vt 0.457764 0.902168
+vt 0.455847 0.896756
+vt 0.455294 0.887134
+vt 0.479658 0.908248
+vt 0.480490 0.907779
+vt 0.481492 0.903207
+vt 0.481979 0.904178
+vt 0.482542 0.903114
+vt 0.483033 0.897794
+vt 0.483423 0.888208
+vt 0.485328 0.908037
+vt 0.491581 0.907367
+vt 0.498422 0.902577
+vt 0.502294 0.903422
+vt 0.506403 0.902226
+vt 0.509212 0.896820
+vt 0.510510 0.887200
+vt 0.489260 0.907447
+vt 0.499275 0.906212
+vt 0.510164 0.900814
+vt 0.516385 0.901307
+vt 0.522952 0.899742
+vt 0.527370 0.894095
+vt 0.529298 0.884380
+vt 0.435164 0.921226
+vt 0.423586 0.921892
+vt 0.433212 0.920281
+vt 0.446278 0.919232
+vt 0.442459 0.917382
+vt 0.458366 0.913050
+vt 0.452538 0.910227
+vt 0.465268 0.913058
+vt 0.458275 0.909671
+vt 0.472557 0.911003
+vt 0.464343 0.907025
+vt 0.477464 0.905073
+vt 0.468453 0.900708
+vt 0.479612 0.895309
+vt 0.470288 0.890792
+vt 0.428687 0.919585
+vt 0.433606 0.916021
+vt 0.439025 0.908150
+vt 0.442059 0.907178
+vt 0.445298 0.904097
+vt 0.447556 0.897496
+vt 0.448667 0.887469
+vt 0.422799 0.919325
+vt 0.422089 0.915513
+vt 0.421447 0.907374
+vt 0.420965 0.906248
+vt 0.420524 0.903004
+vt 0.420375 0.896296
+vt 0.420542 0.886228
+vt 0.417129 0.919572
+vt 0.410995 0.915994
+vt 0.404515 0.908109
+vt 0.400647 0.907129
+vt 0.396659 0.904039
+vt 0.394191 0.897432
+vt 0.393450 0.887403
+vt 0.413194 0.920257
+vt 0.403297 0.917335
+vt 0.392764 0.910156
+vt 0.386546 0.909585
+vt 0.380099 0.906924
+vt 0.376020 0.900598
+vt 0.374650 0.890678
+vt 0.412048 0.921199
+vt 0.401056 0.919178
+vt 0.389345 0.912967
+vt 0.382443 0.912959
+vt 0.375279 0.910887
+vt 0.370733 0.904945
+vt 0.369179 0.895177
+vt 0.414000 0.922144
+vt 0.404875 0.921027
+vt 0.395173 0.915790
+vt 0.389436 0.916346
+vt 0.383493 0.914865
+vt 0.379745 0.909310
+vt 0.378503 0.899693
+vt 0.418526 0.922840
+vt 0.413728 0.922388
+vt 0.408686 0.917867
+vt 0.405652 0.918839
+vt 0.402538 0.917793
+vt 0.400641 0.912523
+vt 0.400124 0.903017
+vt 0.424413 0.923099
+vt 0.425245 0.922896
+vt 0.426264 0.918643
+vt 0.426745 0.919770
+vt 0.427312 0.918886
+vt 0.427823 0.913722
+vt 0.428249 0.904258
+vt 0.430084 0.922854
+vt 0.436339 0.922415
+vt 0.443196 0.917909
+vt 0.447065 0.918889
+vt 0.451177 0.917851
+vt 0.454007 0.912586
+vt 0.455341 0.903083
+vt 0.434019 0.922168
+vt 0.444037 0.921074
+vt 0.454947 0.915862
+vt 0.461165 0.916432
+vt 0.467738 0.914966
+vt 0.472177 0.909421
+vt 0.474141 0.899807
+vt 0.560322 0.921376
+vt 0.548743 0.922041
+vt 0.558370 0.920430
+vt 0.571436 0.919381
+vt 0.567617 0.917532
+vt 0.583524 0.913199
+vt 0.577696 0.910376
+vt 0.590426 0.913208
+vt 0.583432 0.909820
+vt 0.597715 0.911152
+vt 0.589501 0.907174
+vt 0.602622 0.905222
+vt 0.593610 0.900857
+vt 0.604770 0.895458
+vt 0.595446 0.890942
+vt 0.553844 0.919735
+vt 0.558764 0.916170
+vt 0.564183 0.908299
+vt 0.567217 0.907327
+vt 0.570456 0.904246
+vt 0.572714 0.897645
+vt 0.573824 0.887618
+vt 0.547957 0.919475
+vt 0.547247 0.915662
+vt 0.546605 0.907524
+vt 0.546123 0.906397
+vt 0.545682 0.903153
+vt 0.545532 0.896446
+vt 0.545700 0.886378
+vt 0.542286 0.919721
+vt 0.536153 0.916144
+vt 0.529672 0.908258
+vt 0.525804 0.907278
+vt 0.521817 0.904188
+vt 0.519348 0.897581
+vt 0.518608 0.887552
+vt 0.538351 0.920406
+vt 0.528455 0.917485
+vt 0.517922 0.910305
+vt 0.511704 0.909735
+vt 0.505256 0.907073
+vt 0.501178 0.900747
+vt 0.499808 0.890828
+vt 0.537206 0.921348
+vt 0.526215 0.919327
+vt 0.514503 0.913117
+vt 0.507601 0.913109
+vt 0.500437 0.911036
+vt 0.495891 0.905095
+vt 0.494337 0.895326
+vt 0.539158 0.922293
+vt 0.530033 0.921176
+vt 0.520331 0.915940
+vt 0.514594 0.916496
+vt 0.508651 0.915014
+vt 0.504902 0.909460
+vt 0.503661 0.899843
+vt 0.543684 0.922989
+vt 0.538886 0.922537
+vt 0.533844 0.918017
+vt 0.530810 0.918989
+vt 0.527696 0.917942
+vt 0.525799 0.912672
+vt 0.525282 0.903166
+vt 0.549571 0.923249
+vt 0.550403 0.923045
+vt 0.551422 0.918792
+vt 0.551903 0.919919
+vt 0.552470 0.919035
+vt 0.552980 0.913871
+vt 0.553407 0.904407
+vt 0.555241 0.923003
+vt 0.561497 0.922564
+vt 0.568354 0.918058
+vt 0.572222 0.919038
+vt 0.576335 0.918000
+vt 0.579165 0.912735
+vt 0.580499 0.903232
+vt 0.559177 0.922317
+vt 0.569195 0.921223
+vt 0.580104 0.916011
+vt 0.586323 0.916581
+vt 0.592896 0.915115
+vt 0.597334 0.909570
+vt 0.599299 0.899957
+vt 0.559044 0.903560
+vt 0.555560 0.904061
+vt 0.557240 0.903502
+vt 0.562383 0.902441
+vt 0.558853 0.902327
+vt 0.565998 0.899330
+vt 0.560611 0.899155
+vt 0.568167 0.890833
+vt 0.561703 0.890623
+vt 0.555180 0.903480
+vt 0.554825 0.902283
+vt 0.554462 0.899089
+vt 0.554324 0.890544
+vt 0.553180 0.903497
+vt 0.550910 0.902317
+vt 0.548487 0.899141
+vt 0.547155 0.890606
+vt 0.551541 0.903552
+vt 0.547705 0.902423
+vt 0.543596 0.899303
+vt 0.541285 0.890801
+vt 0.550515 0.903635
+vt 0.545699 0.902586
+vt 0.540533 0.899551
+vt 0.537609 0.891098
+vt 0.550258 0.903734
+vt 0.545195 0.902780
+vt 0.539764 0.899847
+vt 0.536687 0.891453
+vt 0.550808 0.903834
+vt 0.546272 0.902975
+vt 0.541408 0.900146
+vt 0.538658 0.891812
+vt 0.552082 0.903920
+vt 0.548764 0.903143
+vt 0.545212 0.900402
+vt 0.543224 0.892119
+vt 0.553886 0.903978
+vt 0.552293 0.903257
+vt 0.550598 0.900576
+vt 0.549688 0.892329
+vt 0.555946 0.904000
+vt 0.556322 0.903301
+vt 0.556747 0.900643
+vt 0.557066 0.892408
+vt 0.557947 0.903983
+vt 0.560237 0.903267
+vt 0.562722 0.900591
+vt 0.564236 0.892346
+vt 0.559585 0.903929
+vt 0.563441 0.903161
+vt 0.567613 0.900428
+vt 0.570106 0.892151
+vt 0.560611 0.903845
+vt 0.565448 0.902998
+vt 0.570676 0.900181
+vt 0.573781 0.891854
+vt 0.560868 0.903746
+vt 0.565951 0.902804
+vt 0.571445 0.899885
+vt 0.574704 0.891499
+vt 0.560318 0.903646
+vt 0.564875 0.902609
+vt 0.569802 0.899586
+vt 0.572732 0.891140
+vt 0.397743 0.903368
+vt 0.394259 0.903868
+vt 0.395939 0.903310
+vt 0.401082 0.902248
+vt 0.397553 0.902134
+vt 0.404697 0.899137
+vt 0.399311 0.898963
+vt 0.406867 0.890641
+vt 0.400403 0.890431
+vt 0.393880 0.903288
+vt 0.393524 0.902090
+vt 0.393162 0.898897
+vt 0.393024 0.890351
+vt 0.391879 0.903305
+vt 0.389610 0.902124
+vt 0.387187 0.898948
+vt 0.385854 0.890414
+vt 0.390241 0.903359
+vt 0.386405 0.902231
+vt 0.382296 0.899111
+vt 0.379985 0.890608
+vt 0.389215 0.903442
+vt 0.384398 0.902393
+vt 0.379233 0.899359
+vt 0.376309 0.890906
+vt 0.388958 0.903541
+vt 0.383895 0.902587
+vt 0.378464 0.899655
+vt 0.375387 0.891261
+vt 0.389508 0.903641
+vt 0.384971 0.902783
+vt 0.380107 0.899953
+vt 0.377358 0.891619
+vt 0.390782 0.903727
+vt 0.387464 0.902951
+vt 0.383912 0.900209
+vt 0.381923 0.891927
+vt 0.392586 0.903786
+vt 0.390993 0.903065
+vt 0.389298 0.900384
+vt 0.388387 0.892136
+vt 0.394645 0.903808
+vt 0.395022 0.903108
+vt 0.395447 0.900450
+vt 0.395766 0.892216
+vt 0.396646 0.903790
+vt 0.398936 0.903074
+vt 0.401422 0.900398
+vt 0.402936 0.892153
+vt 0.398285 0.903736
+vt 0.402141 0.902968
+vt 0.406313 0.900236
+vt 0.408806 0.891959
+vt 0.399310 0.903653
+vt 0.404148 0.902806
+vt 0.409376 0.899988
+vt 0.412481 0.891661
+vt 0.399568 0.903554
+vt 0.404651 0.902612
+vt 0.410145 0.899692
+vt 0.413404 0.891306
+vt 0.399017 0.903454
+vt 0.403575 0.902416
+vt 0.408502 0.899393
+vt 0.411432 0.890948
+vt 0.560050 0.895619
+vt 0.598903 0.933649
+vt 0.559659 0.931810
+vt 0.626960 0.931921
+vt 0.632743 0.931121
+vt 0.633550 0.930793
+vt 0.633940 0.894602
+vt 0.632944 0.930462
+vt 0.633334 0.894271
+vt 0.630952 0.930143
+vt 0.631342 0.893951
+vt 0.627661 0.929849
+vt 0.589170 0.929516
+vt 0.589561 0.893325
+vt 0.398164 0.895426
+vt 0.363809 0.933369
+vt 0.397773 0.931617
+vt 0.330560 0.931567
+vt 0.322401 0.930751
+vt 0.321016 0.894228
+vt 0.320625 0.930420
+vt 0.320649 0.893898
+vt 0.320258 0.930089
+vt 0.321706 0.893582
+vt 0.321316 0.929773
+vt 0.323752 0.929486
+vt 0.361788 0.893053
+vt 0.361398 0.929244
+vt 0.559656 0.902097
+vt 0.555589 0.901346
+vt 0.557317 0.902165
+vt 0.573965 0.927557
+vt 0.563255 0.927865
+vt 0.573734 0.930613
+vt 0.563137 0.930918
+vt 0.570621 0.930463
+vt 0.561812 0.930717
+vt 0.554520 0.902163
+vt 0.550449 0.927858
+vt 0.550467 0.930911
+vt 0.551280 0.930711
+vt 0.552015 0.902093
+vt 0.538979 0.927538
+vt 0.539119 0.930594
+vt 0.541846 0.930447
+vt 0.550473 0.901973
+vt 0.531919 0.926990
+vt 0.532133 0.930052
+vt 0.536040 0.929997
+vt 0.550307 0.901836
+vt 0.531159 0.926362
+vt 0.531382 0.929430
+vt 0.535415 0.929480
+vt 0.551562 0.901718
+vt 0.536905 0.925821
+vt 0.537067 0.928895
+vt 0.540141 0.929035
+vt 0.553901 0.901651
+vt 0.547615 0.925513
+vt 0.547664 0.928591
+vt 0.548949 0.928782
+vt 0.556698 0.901652
+vt 0.560422 0.925520
+vt 0.560334 0.928598
+vt 0.559482 0.928788
+vt 0.559203 0.901723
+vt 0.571891 0.925841
+vt 0.571682 0.928915
+vt 0.568915 0.929052
+vt 0.560745 0.901842
+vt 0.578951 0.926388
+vt 0.578668 0.929457
+vt 0.574722 0.929502
+vt 0.560911 0.901979
+vt 0.579711 0.927017
+vt 0.579419 0.930079
+vt 0.575346 0.930019
+vt 0.398356 0.901905
+vt 0.394289 0.901154
+vt 0.396017 0.901972
+vt 0.412665 0.927365
+vt 0.401954 0.927673
+vt 0.412434 0.930421
+vt 0.401837 0.930726
+vt 0.409321 0.930271
+vt 0.400512 0.930524
+vt 0.394258 0.903992
+vt 0.393220 0.901971
+vt 0.389148 0.927666
+vt 0.389167 0.930719
+vt 0.389979 0.930518
+vt 0.390714 0.901901
+vt 0.377679 0.927345
+vt 0.377819 0.930402
+vt 0.380546 0.930255
+vt 0.389172 0.901781
+vt 0.370618 0.926798
+vt 0.370833 0.929860
+vt 0.374739 0.929804
+vt 0.389006 0.901644
+vt 0.369859 0.926169
+vt 0.370082 0.929238
+vt 0.374115 0.929287
+vt 0.390261 0.901526
+vt 0.375605 0.925629
+vt 0.375767 0.928703
+vt 0.378840 0.928843
+vt 0.392601 0.901458
+vt 0.386315 0.925321
+vt 0.386364 0.928398
+vt 0.387649 0.928590
+vt 0.395398 0.901460
+vt 0.399121 0.925328
+vt 0.399034 0.928406
+vt 0.398181 0.928596
+vt 0.397903 0.901530
+vt 0.410591 0.925648
+vt 0.410382 0.928723
+vt 0.407615 0.928859
+vt 0.399445 0.901650
+vt 0.417651 0.926196
+vt 0.417368 0.929265
+vt 0.413422 0.929310
+vt 0.399611 0.901787
+vt 0.418410 0.926824
+vt 0.418119 0.929886
+vt 0.414046 0.929826
+vn 0.011353 0.401349 0.915830
+vn 0.382275 0.411969 -0.827082
+vn -0.579608 0.385968 -0.717673
+vn -0.581500 0.379101 -0.719810
+vn -0.578936 0.391400 -0.715262
+vn -0.587512 0.353526 -0.727866
+vn -0.281625 0.919126 -0.275399
+vn 0.057253 0.984527 0.165563
+vn 0.071383 0.980926 0.180639
+vn -0.296457 0.908780 -0.293558
+vn 0.474380 0.596789 0.647114
+vn 0.491165 0.565630 0.662404
+vn 0.513932 0.515061 0.685965
+vn 0.517106 0.508774 0.688223
+vn 0.275857 0.401013 -0.873531
+vn -0.191260 0.288827 -0.938047
+vn -0.394971 -0.383221 0.834925
+vn 0.387310 -0.917112 0.094089
+vn 0.623280 0.340129 0.704123
+vn 0.167821 -0.764855 0.621906
+vn 0.346049 -0.937437 -0.037507
+vn 0.028108 -0.899045 0.436933
+vn 0.351848 -0.931425 -0.092898
+vn -0.021699 -0.935636 0.352214
+vn 0.354595 -0.925047 -0.135960
+vn -0.066134 -0.957091 0.282022
+vn 0.350780 -0.921049 -0.169012
+vn 0.518418 -0.764580 -0.382855
+vn 0.338420 -0.920835 -0.193701
+vn 0.202460 -0.979156 -0.015046
+vn 0.316080 -0.924802 -0.211646
+vn 0.010743 -0.996918 -0.077364
+vn 0.282449 -0.932432 -0.225257
+vn -0.263527 -0.963652 0.043672
+vn 0.235603 -0.942106 -0.238563
+vn -0.338664 -0.940489 -0.026948
+vn 0.130589 -0.939299 -0.317209
+vn -0.497787 -0.838588 -0.221198
+vn -0.419324 0.243233 -0.874599
+vn -0.876553 -0.425245 0.225349
+vn 0.628407 0.047426 -0.776421
+vn 0.780297 -0.115146 -0.614673
+vn 0.783563 0.069918 -0.617328
+vn -0.748405 -0.260353 0.609973
+vn -0.749504 -0.261116 0.608264
+vn 0.753014 -0.055422 -0.655629
+vn -0.749474 -0.261025 0.608386
+vn 0.758538 -0.024628 -0.651143
+vn -0.749535 -0.261055 0.608264
+vn 0.767571 -0.000092 -0.640919
+vn -0.749565 -0.261055 0.608234
+vn 0.611438 -0.665090 -0.428663
+vn -0.751213 -0.254250 0.609088
+vn 0.407697 -0.867550 -0.284768
+vn -0.752129 -0.255257 0.607532
+vn 0.356670 -0.868801 -0.343394
+vn 0.296243 -0.863887 -0.407300
+vn 0.220618 -0.847133 -0.483383
+vn 0.021393 -0.758263 -0.651570
+vn -0.141331 -0.391461 -0.909268
+vn -0.187475 -0.241737 0.952055
+vn 0.837397 0.084780 -0.539933
+vn -0.023103 -0.413434 0.910215
+vn 0.824702 0.075686 -0.560442
+vn -0.095370 -0.585253 0.805200
+vn 0.812677 0.068239 -0.578692
+vn -0.154118 -0.691580 0.705618
+vn 0.800623 0.065004 -0.595599
+vn -0.233772 -0.776574 0.584979
+vn 0.788965 0.064425 -0.611011
+vn -0.333689 -0.831782 0.443556
+vn 0.785150 0.052644 -0.617023
+vn -0.415937 -0.817103 0.399091
+vn 0.779382 0.063265 -0.623310
+vn -0.437086 -0.843745 0.311441
+vn 0.767327 0.061159 -0.638295
+vn -0.553789 -0.813898 0.175604
+vn 0.753685 0.061495 -0.654317
+vn -0.658071 -0.750481 0.060671
+vn 0.738456 0.065859 -0.671041
+vn -0.748985 -0.661794 -0.031587
+vn 0.720969 0.071505 -0.689230
+vn -0.847560 -0.510117 -0.146214
+vn -0.934355 -0.298257 -0.194861
+vn -0.388806 -0.092868 0.916593
+vn -0.783807 -0.067476 0.617298
+vn -0.417402 -0.324046 0.848964
+vn 0.045289 -0.536576 0.842616
+vn 0.101627 -0.139500 0.984985
+vn 0.268532 -0.648549 0.712180
+vn 0.342967 -0.179662 0.921964
+vn 0.327982 -0.690237 0.644917
+vn 0.425520 -0.197241 0.883145
+vn 0.333811 -0.702963 0.627979
+vn 0.428297 -0.209754 0.878933
+vn 0.353496 -0.704642 0.615192
+vn 0.454268 -0.208472 0.866115
+vn 0.400616 -0.719047 0.567858
+vn 0.518052 -0.221412 0.826167
+vn 0.455519 -0.674062 0.581439
+vn 0.540757 -0.377819 0.751518
+vn -0.056063 -0.389721 0.919187
+vn -0.071047 -0.408887 0.909787
+vn -0.799554 -0.060579 0.597491
+vn -0.499863 -0.502060 0.705710
+vn -0.068178 -0.820673 0.567278
+vn 0.131443 -0.908658 0.396252
+vn 0.175726 -0.927091 0.331004
+vn 0.185553 -0.931791 0.311930
+vn 0.202643 -0.933988 0.294198
+vn 0.229926 -0.937773 0.260079
+vn 0.249245 -0.927580 0.278268
+vn -0.605335 -0.408643 0.683035
+vn -0.580706 -0.562334 0.588610
+vn -0.185675 -0.914670 0.358959
+vn 0.015992 -0.980255 0.196997
+vn 0.065188 -0.986755 0.148350
+vn 0.079196 -0.987762 0.134129
+vn 0.098361 -0.988250 0.116916
+vn 0.122410 -0.988006 0.093783
+vn 0.182073 -0.973327 0.139500
+vn -0.653920 -0.466628 0.595477
+vn -0.661611 -0.570849 0.486160
+vn -0.310678 -0.929106 0.200537
+vn -0.097995 -0.993866 0.051149
+vn -0.037843 -0.999146 0.014679
+vn -0.021607 -0.999725 0.005341
+vn 0.000305 -0.999939 -0.008972
+vn 0.045381 -0.998901 0.010651
+vn 0.056917 0.996734 0.057009
+vn -0.761834 -0.063967 0.644581
+vn -0.760979 -0.529954 0.374187
+vn -0.492935 -0.869564 0.028474
+vn -0.268410 -0.956328 -0.115513
+vn -0.190405 -0.971160 -0.143376
+vn -0.172277 -0.974181 -0.145756
+vn -0.149602 -0.976074 -0.157720
+vn -0.080416 -0.988525 -0.127750
+vn 0.157567 0.963073 0.218177
+vn -0.774438 -0.080844 0.627430
+vn -0.895108 -0.376080 0.239387
+vn -0.758873 -0.626179 -0.178747
+vn -0.565905 -0.744591 -0.353954
+vn -0.478896 -0.784600 -0.393689
+vn -0.462539 -0.795160 -0.392071
+vn -0.446303 -0.797143 -0.406629
+vn -0.383801 -0.811182 -0.441176
+vn -0.569842 -0.402722 -0.716269
+vn -0.867214 -0.482040 -0.124546
+vn -0.972625 -0.160802 0.167699
+vn -0.913907 -0.254952 -0.315836
+vn -0.789666 -0.307993 -0.530595
+vn -0.731681 -0.333262 -0.594592
+vn -0.719108 -0.343425 -0.604053
+vn -0.711142 -0.341990 -0.614215
+vn -0.645924 -0.361064 -0.672597
+vn -0.589465 -0.359386 -0.723411
+vn -0.558916 -0.355724 -0.749016
+vn -0.984649 -0.017029 0.173559
+vn -0.950407 0.063387 -0.304422
+vn -0.841395 0.103824 -0.530290
+vn -0.806238 0.117710 -0.579699
+vn -0.796869 0.065188 -0.600574
+vn -0.815058 0.082797 -0.573412
+vn -0.747459 0.052217 -0.662221
+vn -0.662618 0.054933 -0.746910
+vn -0.946440 0.184942 0.264534
+vn -0.901151 0.405866 -0.152165
+vn -0.791284 0.484329 -0.373119
+vn -0.758507 0.497940 -0.420301
+vn -0.832942 0.412763 -0.368511
+vn -0.853053 0.386303 -0.350780
+vn -0.759667 0.372906 -0.532762
+vn -0.660024 0.386639 -0.644063
+vn -0.246498 0.354472 -0.901975
+vn -0.869778 0.307108 0.386151
+vn -0.768059 0.638356 0.050264
+vn -0.649892 0.745659 -0.146855
+vn -0.625477 0.757378 -0.187414
+vn -0.755150 0.653676 -0.049348
+vn -0.807489 0.588000 -0.046693
+vn -0.708548 0.652181 -0.269387
+vn -0.584002 0.694327 -0.420484
+vn -0.127415 0.687521 -0.714866
+vn -0.815638 0.347392 0.462600
+vn -0.668355 0.719535 0.188513
+vn -0.535874 0.844081 0.017426
+vn -0.510453 0.859676 -0.017945
+vn -0.661184 0.738060 0.134465
+vn -0.726676 0.668844 0.156682
+vn -0.613208 0.788659 -0.044343
+vn -0.469069 0.859127 -0.204505
+vn -0.005982 0.836024 -0.548601
+vn -0.769311 0.368267 0.521989
+vn -0.581652 0.755638 0.301035
+vn -0.433180 0.887845 0.155126
+vn -0.404614 0.905606 0.127018
+vn -0.570086 0.773553 0.276742
+vn -0.631184 0.706412 0.320200
+vn -0.491775 0.855464 0.162236
+vn -0.328074 0.944578 0.010163
+vn 0.136052 0.927732 -0.347453
+vn -0.751610 0.359294 0.553117
+vn -0.543962 0.760521 0.354472
+vn -0.385083 0.896725 0.218116
+vn -0.352306 0.916196 0.190802
+vn -0.517808 0.788629 0.331462
+vn -0.585437 0.710044 0.391247
+vn -0.428938 0.866573 0.255043
+vn -0.254402 0.960753 0.110477
+vn 0.239692 0.931913 -0.272164
+vn -0.726463 0.373699 0.576678
+vn -0.501083 0.765160 0.404187
+vn -0.335337 0.899319 0.280557
+vn -0.301431 0.917936 0.257851
+vn -0.474563 0.785058 0.398083
+vn -0.523942 0.719474 0.455824
+vn -0.352763 0.870785 0.342387
+vn -0.173925 0.962493 0.208197
+vn -0.035707 0.993988 0.103244
+vn -0.678487 0.364696 0.637684
+vn -0.410749 0.749992 0.518418
+vn -0.224158 0.880764 0.417066
+vn -0.182409 0.898740 0.398663
+vn -0.354961 0.774987 0.522843
+vn -0.385052 0.709708 0.589892
+vn -0.180914 0.837123 0.516190
+vn -0.016968 0.917447 0.397443
+vn -0.462996 0.684591 0.562975
+vn -0.612934 0.339244 0.713553
+vn -0.294046 0.693960 0.657216
+vn -0.084872 0.811884 0.577593
+vn -0.034639 0.826319 0.562120
+vn -0.180486 0.720573 0.669454
+vn -0.199011 0.655660 0.728324
+vn 0.022217 0.734397 0.678335
+vn 0.145665 0.812983 0.563738
+vn -0.714560 0.223823 0.662770
+vn -0.504288 0.240455 0.829341
+vn -0.113254 0.500290 0.858394
+vn 0.119724 0.592853 0.796319
+vn 0.180761 0.608966 0.772301
+vn 0.118778 0.528459 0.840571
+vn 0.082675 0.500137 0.861965
+vn 0.284463 0.498032 0.819147
+vn 0.422620 0.516312 0.744835
+vn 0.035096 0.318186 0.947356
+vn -0.410077 0.052370 0.910520
+vn 0.049562 0.183081 0.981842
+vn 0.291269 0.239875 0.926054
+vn 0.358043 0.252937 0.898770
+vn 0.362987 0.210150 0.907773
+vn 0.343822 0.221992 0.912381
+vn 0.442213 0.193243 0.875820
+vn 0.550554 0.199133 0.810663
+vn -0.318186 0.933988 0.162420
+vn -0.200354 0.971496 0.126591
+vn -0.223548 0.970855 0.086062
+vn -0.066347 0.990966 0.116398
+vn -0.139744 0.989990 0.019105
+vn -0.061495 0.991150 0.117496
+vn -0.134465 0.990814 0.013977
+vn -0.061037 0.991882 0.111362
+vn -0.123630 0.992309 0.003357
+vn -0.057009 0.994201 0.090915
+vn -0.100101 0.994812 -0.016938
+vn -0.012268 0.998962 0.043367
+vn -0.037477 0.996979 -0.067965
+vn 0.029817 0.999237 -0.024323
+vn 0.018677 0.993408 -0.112918
+vn 0.065371 0.994415 -0.082797
+vn 0.053926 0.989196 -0.136113
+vn 0.033235 0.996521 -0.076144
+vn 0.028626 0.992889 -0.115299
+vn -0.016511 0.998688 -0.048128
+vn -0.013733 0.996429 -0.083041
+vn 0.529496 0.712210 -0.460829
+vn 0.523026 0.708579 -0.473617
+vn 0.789056 -0.011536 -0.614185
+vn -0.302988 0.938353 0.166265
+vn -0.265389 0.938994 0.218726
+vn 0.008972 0.974334 0.224860
+vn 0.017914 0.971709 0.235389
+vn 0.009888 0.967406 0.252937
+vn -0.025452 0.968108 0.249153
+vn -0.026399 0.977172 0.210669
+vn -0.000336 0.993500 0.113742
+vn 0.030061 0.999298 0.021210
+vn 0.023957 0.999512 -0.018830
+vn -0.017853 0.999817 0.001221
+vn 0.536332 0.721305 -0.438215
+vn -0.298685 0.932981 0.200690
+vn -0.114658 -0.798791 -0.590564
+vn -0.370708 -0.526780 -0.764885
+vn -0.291025 -0.616688 -0.731407
+vn -0.143254 -0.625172 -0.767205
+vn 0.027223 -0.640553 -0.767418
+vn 0.111332 -0.662038 -0.741111
+vn 0.135563 -0.740410 -0.658315
+vn 0.095309 -0.862575 -0.496811
+vn 0.031892 -0.950316 -0.309610
+vn -0.117801 -0.895688 -0.428724
+vn 0.703726 0.085910 -0.705222
+vn 0.140812 -0.988342 -0.057833
+vn -0.176916 0.112217 -0.977783
+vn -0.463820 -0.000244 -0.885922
+vn -0.396466 0.495773 -0.772637
+vn -0.251259 0.629933 -0.734855
+vn -0.082247 0.613941 -0.785028
+vn 0.062685 0.432813 -0.899289
+vn 0.114200 0.360729 -0.925626
+vn 0.067263 0.509629 -0.857723
+vn -0.147404 0.666036 -0.731162
+vn -0.333659 0.761101 -0.556200
+vn -0.153478 0.913327 -0.377148
+vn -0.370403 -0.745903 -0.553514
+vn -0.117374 0.990661 0.069308
+vn -0.045228 -0.997101 0.061098
+vn -0.457808 -0.775109 -0.435408
+vn -0.716849 -0.364360 -0.594409
+vn -0.842647 0.257424 -0.472915
+vn -0.742363 -0.635609 -0.211829
+vn -0.978973 -0.126621 -0.159734
+vn -0.920560 0.370373 -0.124027
+vn -0.685263 -0.714591 -0.140477
+vn -0.822535 0.452986 -0.343791
+vn -0.424726 0.841395 -0.334086
+vn 0.104862 -0.938810 0.328043
+vn -0.146855 0.961974 -0.230232
+vn -0.592578 0.640126 -0.488907
+vn -0.615009 0.631336 -0.472365
+vn -0.672750 0.632954 -0.383038
+vn -0.732994 0.635304 -0.243019
+vn -0.733726 0.657796 -0.169988
+vn -0.650349 0.747856 -0.133000
+vn -0.509659 0.849849 -0.133976
+vn -0.374187 0.917051 -0.137638
+vn -0.261879 0.943449 -0.203101
+vn -0.750603 0.280526 0.598193
+vn -0.264351 0.961669 0.072787
+vn -0.292032 0.955870 -0.031159
+vn -0.329691 0.920103 -0.211402
+vn -0.339793 0.915555 -0.215125
+vn -0.354900 0.915159 -0.190985
+vn -0.364147 0.919675 -0.146916
+vn -0.327921 0.934049 -0.141392
+vn -0.236305 0.962859 -0.130497
+vn -0.132908 0.981079 -0.140751
+vn -0.095737 0.987732 -0.123142
+vn -0.095767 0.990448 -0.099002
+vn 0.488937 0.717917 -0.495499
+vn -0.306192 0.943205 0.128666
+vn -0.249184 0.966887 0.054659
+vn -0.214362 0.973754 -0.076144
+vn -0.213904 0.973327 -0.082614
+vn -0.208258 0.974456 -0.083956
+vn -0.190619 0.978057 -0.083712
+vn -0.134281 0.983673 -0.119694
+vn -0.065127 0.987915 -0.140446
+vn -0.005676 0.987548 -0.157170
+vn -0.010773 0.991577 -0.128971
+vn -0.047334 0.995025 -0.087466
+vn 0.511277 0.710990 -0.482742
+vn -0.317698 0.934355 0.161168
+vn 0.115726 -0.988556 0.096622
+vn 0.137333 -0.978088 0.156377
+vn 0.149754 -0.969787 0.192450
+vn 0.113804 -0.975402 0.188665
+vn 0.085177 -0.975860 0.201056
+vn 0.090030 -0.983673 0.155797
+vn 0.118778 -0.991150 0.058962
+vn 0.183233 -0.982940 -0.013886
+vn 0.138249 -0.988586 0.059420
+vn 0.134892 -0.989990 0.041383
+vn 0.729453 -0.456862 -0.509049
+vn -0.047090 -0.987243 0.151891
+vn 0.017121 -0.989441 0.143895
+vn 0.119480 -0.983428 0.136174
+vn 0.126865 -0.983886 0.125919
+vn 0.118809 -0.985748 0.119053
+vn 0.100009 -0.988037 0.117252
+vn 0.092471 -0.989349 0.112217
+vn 0.103183 -0.991180 0.082858
+vn 0.137211 -0.989776 0.038453
+vn 0.148564 -0.988800 0.012665
+vn 0.133518 -0.990966 0.011872
+vn 0.619343 -0.669668 -0.409772
+vn -0.082308 -0.983306 0.162206
+vn -0.013428 -0.993072 0.116581
+vn 0.076205 -0.994476 0.071780
+vn 0.089877 -0.994110 0.060427
+vn 0.092868 -0.994140 0.054903
+vn 0.089145 -0.994568 0.053194
+vn 0.092318 -0.994537 0.048616
+vn 0.110874 -0.993408 0.028413
+vn 0.147404 -0.989044 -0.005463
+vn 0.164617 -0.986053 -0.024293
+vn 0.148503 -0.988769 -0.015656
+vn 0.615223 -0.670400 -0.414716
+vn -0.095187 -0.981842 0.163976
+vn -0.030366 -0.994903 0.096072
+vn 0.037080 -0.999023 0.022736
+vn 0.052431 -0.998535 0.012757
+vn 0.059267 -0.998169 0.011414
+vn 0.060518 -0.998016 0.015534
+vn 0.066469 -0.997681 0.014222
+vn 0.091372 -0.995788 0.001312
+vn 0.133305 -0.990692 -0.027131
+vn 0.154118 -0.987274 -0.039003
+vn 0.143284 -0.989319 -0.026276
+vn 0.612751 -0.670492 -0.418226
+vn -0.094028 -0.983001 0.157659
+vn -0.057375 -0.996307 0.063570
+vn -0.016144 -0.999237 -0.034730
+vn -0.002991 -0.999207 -0.039277
+vn 0.003479 -0.999542 -0.030030
+vn 0.002014 -0.999908 -0.012177
+vn 0.004822 -0.999969 -0.002655
+vn 0.037202 -0.999268 -0.006897
+vn 0.092563 -0.995239 -0.029878
+vn 0.117161 -0.992523 -0.033509
+vn 0.112613 -0.993439 -0.018281
+vn 0.609699 -0.669759 -0.423841
+vn -0.078555 -0.987610 0.135685
+vn -0.137303 -0.990387 -0.015900
+vn -0.142460 -0.977447 -0.155675
+vn -0.135044 -0.979888 -0.146733
+vn -0.135533 -0.984924 -0.107364
+vn -0.147191 -0.987518 -0.055879
+vn -0.153020 -0.987945 -0.022248
+vn -0.097934 -0.995117 -0.011658
+vn -0.015992 -0.999634 -0.021455
+vn 0.047945 -0.998474 -0.026307
+vn 0.066897 -0.997559 -0.018983
+vn 0.600665 -0.671346 -0.434065
+vn -0.027772 -0.995697 0.088137
+vn 0.090670 -0.995666 0.019135
+vn 0.090579 -0.995697 0.019044
+vn 0.188879 -0.970733 0.148198
+vn 0.334513 -0.875454 0.348735
+vn 0.092196 -0.995514 0.021088
+vn 0.092257 -0.995483 0.021180
+vn -0.010163 -0.994171 -0.107089
+vn -0.175970 -0.935575 -0.306040
+vn -0.539750 0.570238 -0.619221
+vn 0.411664 0.682363 0.604022
+vn -0.004852 -0.012940 0.999878
+vn 0.696249 0.084201 0.712821
+vn -0.004883 -0.012940 0.999878
+vn 0.990326 0.131718 0.043519
+vn 0.050478 0.019013 -0.998535
+vn -0.983367 -0.129765 -0.126957
+vn -0.108615 -0.026734 0.993713
+vn 0.991089 0.132176 0.014832
+vn 0.062136 0.020569 -0.997833
+vn -0.673421 -0.080905 -0.734764
+vn -0.673421 -0.080905 -0.734794
+vn -0.689810 -0.083254 -0.719169
+vn -0.689810 -0.083285 -0.719169
+vn -0.981964 -0.129429 -0.137730
+vn -0.979644 -0.153935 -0.128636
+vn 0.215613 0.068148 -0.974090
+vn 0.972839 0.151250 0.175115
+vn 0.549547 0.060335 0.833247
+vn 0.530747 0.056856 0.845607
+vn -0.095462 -0.049409 0.994201
+vn -0.961516 -0.147496 -0.231666
+vn -0.523148 -0.055483 -0.850398
+vn 0.187872 0.063875 -0.980102
+vn 0.970794 0.150517 0.186682
+vn -0.106113 -0.051088 0.993011
+vn -0.567309 0.638081 -0.520554
+vn -0.672536 0.613269 -0.414167
+vn -0.600604 0.726829 -0.333079
+vn -0.865627 0.485733 -0.121220
+vn -0.821436 0.567125 -0.059572
+vn -0.932096 0.276009 0.234443
+vn -0.919126 0.294443 0.261635
+vn -0.874447 0.076205 0.479049
+vn -0.883908 0.053224 0.464583
+vn -0.603076 0.791742 0.096896
+vn -0.825739 -0.022523 0.563585
+vn -0.512680 0.740440 -0.434584
+vn -0.416974 0.906156 -0.070406
+vn -0.663503 0.732475 0.152409
+vn -0.827845 0.397473 0.395764
+vn -0.848079 0.094943 0.521256
+vn -0.826167 -0.037660 0.562120
+vn -0.333415 0.927396 -0.169500
+vn -0.134648 0.947172 0.290994
+vn -0.400525 0.795190 0.455214
+vn -0.672384 0.449507 0.588031
+vn -0.789911 0.101962 0.604633
+vn -0.920225 -0.098300 0.378765
+vn -0.052156 0.977294 0.205359
+vn 0.416059 0.251076 0.873959
+vn 0.175665 0.154698 0.972198
+vn -0.109897 -0.090121 0.989837
+vn -0.221870 -0.384716 0.895932
+vn 0.825556 -0.543962 0.150029
+vn 0.010590 -0.999908 0.005737
+vn 0.058046 -0.998260 -0.008972
+vn 0.495163 0.283273 0.821284
+vn -0.225318 -0.960570 0.162877
+vn -0.348491 -0.769860 0.534623
+vn -0.290658 -0.581988 0.759453
+vn 0.808496 -0.539659 0.234657
+vn -0.564837 -0.555742 -0.609973
+vn -0.793847 -0.511612 -0.328593
+vn -0.928495 -0.333506 0.163152
+vn -0.862911 -0.147649 0.483230
+vn 0.801141 0.079134 -0.593188
+vn -0.487472 -0.583026 -0.649922
+vn -0.719382 -0.151708 -0.677816
+vn -0.918424 -0.140019 -0.369945
+vn -0.987701 -0.086550 0.129978
+vn -0.884121 -0.044404 0.465102
+vn 0.804407 0.067415 -0.590197
+vn -0.601794 -0.283303 -0.746666
+vn -0.756035 0.248848 -0.605335
+vn -0.935301 0.212775 -0.282632
+vn -0.976867 0.133824 0.166753
+vn -0.877590 0.049898 0.476791
+vn 0.810999 0.054262 -0.582507
+vn -0.590533 0.500595 -0.632954
+vn -0.717277 0.486373 -0.498917
+vn -0.895657 0.404645 -0.184393
+vn -0.943510 0.251595 0.215583
+vn -0.863338 0.100070 0.494583
+vn 0.816828 0.033052 -0.575884
+vn -0.622181 0.495407 -0.606128
+vn 0.305063 0.740837 0.598376
+vn 0.108097 0.810297 0.575915
+vn 0.178533 0.713523 0.677450
+vn -0.196326 0.640767 0.742180
+vn -0.140599 0.571123 0.808710
+vn -0.506272 0.343059 0.791162
+vn -0.481643 0.329081 0.812220
+vn -0.671957 0.078188 0.736412
+vn -0.685629 0.098453 0.721244
+vn -0.746391 -0.013153 0.665365
+vn -0.312754 0.825800 0.469253
+vn 0.226600 0.827509 0.513627
+vn -0.115696 0.941649 0.316019
+vn -0.376385 0.766289 0.520676
+vn -0.622211 0.421674 0.659536
+vn -0.721458 0.109836 0.683645
+vn -0.743767 -0.027955 0.667837
+vn -0.001251 0.966521 0.256508
+vn -0.398022 0.916166 -0.046754
+vn -0.608875 0.770653 0.187964
+vn -0.773766 0.437574 0.458022
+vn -0.788141 0.102176 0.606922
+vn -0.584918 -0.058779 0.808954
+vn -0.297617 0.948363 -0.109470
+vn -0.762291 0.112308 -0.637410
+vn -0.908078 0.027039 -0.417859
+vn -0.974181 -0.191931 -0.118686
+vn -0.885250 -0.462874 0.045076
+vn 0.108097 -0.628437 -0.770287
+vn 0.111484 -0.991974 0.059542
+vn 0.085665 -0.991058 0.102023
+vn -0.694693 0.143132 -0.704886
+vn -0.127873 -0.949065 0.287851
+vn -0.533952 -0.791681 0.296762
+vn -0.753136 -0.636464 0.166173
+vn -0.002838 -0.644154 -0.764885
+vn 0.497726 -0.430586 0.752861
+vn 0.165593 -0.398602 0.902036
+vn -0.357982 -0.266305 0.894925
+vn -0.666982 -0.124607 0.734550
+vn 0.763817 0.074709 -0.641072
+vn 0.557848 -0.459914 0.690817
+vn 0.489090 -0.009369 0.872158
+vn 0.141697 -0.015137 0.989776
+vn -0.362529 -0.012940 0.931852
+vn -0.663869 -0.018494 0.747581
+vn 0.762780 0.062502 -0.643605
+vn 0.596301 -0.142186 0.790033
+vn 0.374584 0.382000 0.844813
+vn 0.022004 0.325541 0.945250
+vn -0.414838 0.200018 0.887631
+vn -0.681906 0.072970 0.727775
+vn 0.758141 0.048006 -0.650288
+vn 0.419935 0.619617 0.663076
+vn 0.260475 0.601550 0.755150
+vn -0.079928 0.500717 0.861873
+vn -0.464095 0.308054 0.830470
+vn -0.699973 0.119327 0.704093
+vn 0.755120 0.025727 -0.655049
+vn 0.386670 0.614246 0.687857
+vn -0.797174 -0.603107 -0.026521
+vn -0.244301 -0.755242 -0.608173
+vn 0.250954 -0.962004 -0.107303
+vn -0.112033 -0.515458 0.849513
+vn 0.600024 -0.644642 0.473647
+vn 0.108371 -0.565691 -0.817438
+vn 0.871578 -0.463698 0.159001
+vn 0.153172 -0.253609 -0.955077
+vn 0.984649 -0.136814 0.108341
+vn 0.192694 -0.028748 -0.980804
+vn 0.995270 0.083193 0.049776
+vn 0.059358 0.501267 -0.863247
+vn 0.796503 0.598743 0.084140
+vn -0.371776 0.692984 -0.617664
+vn 0.433210 0.798486 0.417951
+vn -0.580859 0.677633 -0.450972
+vn 0.224006 0.783013 0.580218
+vn -0.743370 0.583178 -0.327494
+vn 0.075320 0.691855 0.718070
+vn -0.787133 0.522355 -0.327952
+vn 0.071963 0.637623 0.766930
+vn -0.818659 0.513230 -0.257607
+vn -0.003662 0.622639 0.782464
+vn -0.911527 0.376415 -0.165441
+vn -0.102359 0.487228 0.867244
+vn -0.980560 0.178625 -0.081088
+vn -0.182897 0.289376 0.939573
+vn -0.523942 -0.729637 0.439375
+vn -0.776849 -0.229896 0.586200
+vn -0.699820 -0.676443 0.229469
+vn -0.117740 -0.979553 0.162999
+vn -0.408979 -0.893521 -0.185186
+vn 0.164525 -0.985473 -0.041627
+vn -0.152776 -0.891842 -0.425672
+vn 0.689962 -0.561754 -0.456435
+vn 0.454360 -0.492691 -0.742149
+vn 0.777703 0.233924 -0.583453
+vn -0.864254 -0.495743 0.085330
+vn -0.681845 -0.595752 -0.424390
+vn -0.450972 -0.565142 -0.690786
+vn 0.231727 -0.250313 -0.940001
+vn -0.972015 -0.229987 0.047243
+vn -0.859523 -0.156987 -0.486312
+vn -0.646535 -0.082919 -0.758324
+vn 0.085025 0.109104 -0.990356
+vn -0.990478 0.048311 0.128666
+vn -0.887539 0.300302 -0.349345
+vn -0.679220 0.417493 -0.603565
+vn 0.060488 0.482131 -0.873989
+vn -0.915403 0.260872 0.306497
+vn -0.761162 0.646199 -0.054811
+vn -0.543809 0.792535 -0.275918
+vn 0.161473 0.760338 -0.629109
+vn -0.769860 0.352367 0.532090
+vn -0.521287 0.792932 0.315378
+vn -0.284402 0.949736 0.130772
+vn 0.353923 0.876370 -0.326548
+vn -0.592029 0.299966 0.747978
+vn -0.230628 0.706900 0.668630
+vn 0.032563 0.856044 0.515854
+vn 0.588946 0.807154 -0.040101
+vn -0.427168 0.113987 0.896939
+vn 0.038881 0.404797 0.913541
+vn 0.329691 0.528428 0.782311
+vn 0.810205 0.564165 0.158971
+vn 0.777703 0.233955 -0.583422
+vn -0.320933 -0.157964 0.933805
+vn 0.213782 -0.038301 0.976104
+vn 0.524552 0.045381 0.850154
+vn 0.956145 0.204260 0.209815
+vn -0.304483 -0.437086 0.846278
+vn 0.242317 -0.495590 0.834040
+vn 0.557573 -0.454939 0.694327
+vn 0.981292 -0.168584 0.092654
+vn -0.379955 -0.644246 0.663717
+vn 0.119327 -0.837092 0.533830
+vn 0.423261 -0.829066 0.365337
+vn 0.881680 -0.446150 -0.153417
+vn -0.488205 -0.725425 0.485153
+vn -0.733879 -0.224799 0.640980
+vn -0.678182 -0.676565 0.286843
+vn -0.099948 -0.977447 0.185858
+vn -0.414655 -0.898648 -0.143132
+vn 0.167852 -0.985076 -0.037324
+vn -0.175298 -0.899380 -0.400403
+vn 0.661214 -0.565142 -0.493301
+vn 0.406384 -0.501968 -0.763451
+vn 0.734886 0.228889 -0.638356
+vn -0.853175 -0.499100 0.151402
+vn -0.705008 -0.606250 -0.367931
+vn -0.492904 -0.578600 -0.649770
+vn 0.169286 -0.264016 -0.949522
+vn -0.965056 -0.234626 0.116550
+vn -0.889401 -0.169530 -0.424482
+vn -0.695791 -0.098636 -0.711417
+vn 0.017121 0.093722 -0.995422
+vn -0.979827 0.044832 0.194708
+vn -0.911100 0.289743 -0.293100
+vn -0.721244 0.404004 -0.562609
+vn -0.001923 0.468429 -0.883480
+vn 0.734916 0.228889 -0.638356
+vn -0.894284 0.260659 0.363689
+vn -0.767388 0.641011 -0.013215
+vn -0.566454 0.784967 -0.250771
+vn 0.113529 0.751061 -0.650380
+vn -0.734428 0.356548 0.577441
+vn -0.504013 0.794977 0.337565
+vn -0.281198 0.950102 0.134922
+vn 0.325205 0.873012 -0.363384
+vn -0.542070 0.308603 0.781579
+vn -0.189550 0.716208 0.671590
+vn 0.061708 0.864345 0.499069
+vn 0.579547 0.809656 -0.092471
+vn 0.734886 0.228858 -0.638356
+vn -0.366283 0.125919 0.921934
+vn 0.097873 0.419568 0.902402
+vn 0.378338 0.542711 0.749840
+vn 0.815332 0.571123 0.094913
+vn -0.255989 -0.144780 0.955748
+vn 0.279550 -0.021516 0.959868
+vn 0.580523 0.061892 0.811853
+vn 0.966765 0.212897 0.141392
+vn -0.243629 -0.425153 0.871670
+vn 0.301462 -0.480850 0.823328
+vn 0.606250 -0.440687 0.661977
+vn 0.986419 -0.161626 0.028596
+vn -0.329936 -0.635670 0.697867
+vn 0.160710 -0.827784 0.537492
+vn 0.452467 -0.820734 0.348704
+vn 0.872219 -0.443617 -0.205817
+vn -0.279611 -0.239448 0.929746
+vn -0.728965 -0.331675 0.598804
+vn -0.241798 -0.437696 0.865963
+vn 0.251595 -0.073305 0.965026
+vn 0.314890 -0.405164 0.858272
+vn 0.554064 0.045930 0.831172
+vn 0.623554 -0.318369 0.713981
+vn 0.945769 0.279214 0.165960
+vn 0.996704 0.012146 0.080050
+vn 0.728965 0.331675 -0.598804
+vn 0.728965 0.331675 -0.598773
+vn -0.260384 -0.611774 0.746940
+vn 0.283761 -0.696493 0.659017
+vn 0.589404 -0.638203 0.495224
+vn 0.971679 -0.222236 -0.080233
+vn -0.332560 -0.735099 0.590747
+vn 0.162969 -0.902921 0.397626
+vn 0.456801 -0.864834 0.208258
+vn 0.874447 -0.388348 -0.290597
+vn -0.447310 -0.788965 0.421186
+vn -0.029084 -0.993042 0.113865
+vn 0.245918 -0.963744 -0.103214
+vn 0.719901 -0.460891 -0.518937
+vn -0.587207 -0.765099 0.264107
+vn -0.263222 -0.953124 -0.149022
+vn -0.011078 -0.919919 -0.391858
+vn 0.531480 -0.428755 -0.730522
+vn 0.728965 0.331706 -0.598804
+vn -0.730918 -0.667196 0.143406
+vn -0.503769 -0.789239 -0.351085
+vn -0.275155 -0.740013 -0.613666
+vn 0.337901 -0.296884 -0.893094
+vn -0.856594 -0.510117 0.077425
+vn -0.714072 -0.526353 -0.461501
+vn -0.506058 -0.451430 -0.734886
+vn 0.168676 -0.085330 -0.981964
+vn -0.945067 -0.317820 0.076235
+vn -0.862178 -0.204505 -0.463485
+vn -0.668630 -0.098056 -0.737083
+vn 0.049501 0.173650 -0.983551
+vn -0.982879 -0.119541 0.140019
+vn -0.925474 0.127354 -0.356700
+vn -0.738121 0.266243 -0.619861
+vn -0.001404 0.440687 -0.897641
+vn -0.964293 0.054506 0.259072
+vn -0.894345 0.418653 -0.157476
+vn -0.703970 0.586077 -0.401135
+vn 0.023591 0.675130 -0.737297
+vn 0.728935 0.331706 -0.598804
+vn -0.892117 0.177862 0.415265
+vn -0.773553 0.625111 0.103916
+vn -0.571368 0.812708 -0.114170
+vn 0.120792 0.841243 -0.526933
+vn -0.777367 0.231697 0.584796
+vn -0.581469 0.715232 0.387677
+vn -0.360485 0.911618 0.197333
+vn 0.275369 0.913755 -0.298593
+vn -0.637471 0.207831 0.741874
+vn -0.347331 0.675314 0.650594
+vn -0.103458 0.867794 0.485977
+vn 0.463790 0.881649 -0.087039
+vn -0.493759 0.109928 0.862606
+vn -0.106815 0.511429 0.852626
+vn 0.160588 0.687887 0.707785
+vn 0.657338 0.749779 0.075533
+vn -0.368084 -0.047121 0.928587
+vn 0.103488 0.248543 0.963042
+vn 0.391491 0.399304 0.829005
+vn 0.826594 0.538224 0.164373
+vn 0.869930 0.207892 -0.447157
+vn 0.764183 0.197546 -0.613941
+vn 0.834101 0.302194 -0.461409
+vn 0.965789 0.207770 -0.155034
+vn 0.877438 0.440321 -0.190191
+vn 0.906308 0.209906 -0.366710
+vn 0.854885 0.345256 -0.387158
+vn 0.889004 0.209113 -0.407300
+vn 0.845332 0.324046 -0.424696
+vn 0.972869 0.189856 0.131993
+vn 0.842891 0.532029 0.080264
+vn 0.805780 0.125584 0.578692
+vn 0.631306 0.584796 0.509323
+vn 0.701254 0.095614 0.706442
+vn 0.520554 0.571215 0.634571
+vn 0.775536 0.367412 -0.513291
+vn 0.733024 0.601154 -0.318217
+vn 0.770806 0.438887 -0.461684
+vn 0.773949 0.403546 -0.487960
+vn 0.630360 0.768731 -0.108066
+vn 0.346110 0.902432 0.256508
+vn 0.225166 0.900174 0.372753
+vn 0.709952 0.386090 -0.588977
+vn 0.571215 0.647175 -0.504776
+vn 0.676626 0.465712 -0.570299
+vn 0.693960 0.426313 -0.580187
+vn 0.392254 0.836482 -0.382641
+vn 0.026582 0.993347 -0.111942
+vn -0.105747 0.994324 -0.008850
+vn 0.654866 0.353191 -0.668111
+vn 0.435377 0.566088 -0.699942
+vn 0.597552 0.418500 -0.683920
+vn 0.626820 0.386212 -0.676656
+vn 0.192389 0.717124 -0.669820
+vn -0.241646 0.833186 -0.497330
+vn -0.383557 0.828486 -0.408002
+vn 0.625080 0.277566 -0.729514
+vn 0.361919 0.379589 -0.851405
+vn 0.554796 0.309915 -0.772057
+vn 0.590503 0.294046 -0.751518
+vn 0.084262 0.442701 -0.892666
+vn -0.386700 0.464888 -0.796411
+vn -0.533799 0.447035 -0.717765
+vn 0.628559 0.179479 -0.756737
+vn 0.370525 0.137669 -0.918546
+vn 0.559801 0.169073 -0.811151
+vn 0.594775 0.174444 -0.784722
+vn 0.096927 0.086673 -0.991485
+vn -0.369732 -0.012848 -0.929014
+vn -0.516221 -0.047761 -0.855098
+vn 0.664388 0.085177 -0.742485
+vn 0.458876 -0.094852 -0.883389
+vn 0.611225 0.033723 -0.790704
+vn 0.638417 0.059511 -0.767357
+vn 0.226936 -0.255470 -0.939787
+vn -0.195257 -0.472060 -0.859645
+vn -0.335521 -0.523392 -0.783227
+vn 0.722953 0.019959 -0.690573
+vn 0.603290 -0.255684 -0.755394
+vn 0.695303 -0.059877 -0.716178
+vn 0.709830 -0.019990 -0.704062
+vn 0.439467 -0.492141 -0.751396
+vn 0.089908 -0.789697 -0.606830
+vn -0.040132 -0.852351 -0.521409
+vn 0.788568 0.001282 -0.614917
+vn 0.765099 -0.301706 -0.568804
+vn 0.789483 -0.086673 -0.607562
+vn 0.789788 -0.042726 -0.611835
+vn 0.677572 -0.559893 -0.476852
+vn 0.409467 -0.880612 -0.238350
+vn 0.290780 -0.946501 -0.139775
+vn 0.843623 0.034150 -0.535783
+vn 0.900937 -0.220618 -0.373638
+vn 0.868557 -0.039460 -0.493973
+vn 0.856929 -0.002655 -0.515366
+vn 0.877438 -0.440565 -0.189642
+vn 0.677694 -0.720481 0.147008
+vn 0.568590 -0.780633 0.259346
+vn 0.873409 0.109806 -0.474380
+vn 0.974395 -0.034120 -0.222205
+vn 0.911313 0.069063 -0.405805
+vn 0.893246 0.089511 -0.440504
+vn 0.985534 -0.166112 0.033174
+vn 0.822748 -0.352153 0.446089
+vn 0.718833 -0.399182 0.569109
+vn 0.862636 0.241218 -0.444533
+vn 0.756767 0.231544 -0.611286
+vn 0.824213 0.334788 -0.456679
+vn 0.959288 0.237495 -0.152715
+vn 0.864498 0.468215 -0.182653
+vn 0.899197 0.242531 -0.364147
+vn 0.844020 0.376812 -0.381573
+vn 0.881771 0.242103 -0.404706
+vn 0.834925 0.356151 -0.419507
+vn 0.967681 0.213660 0.133854
+vn 0.828181 0.553178 0.089785
+vn 0.803674 0.135289 0.579455
+vn 0.616474 0.590899 0.520310
+vn 0.700339 0.099704 0.706778
+vn 0.506485 0.571612 0.645497
+vn 0.763726 0.399457 -0.507035
+vn 0.715354 0.627735 -0.306864
+vn 0.757195 0.469680 -0.453902
+vn 0.761193 0.435011 -0.480911
+vn 0.608722 0.787896 -0.092959
+vn 0.321940 0.905911 0.275033
+vn 0.201453 0.897855 0.391461
+vn 0.697409 0.417951 -0.582141
+vn 0.551836 0.673269 -0.492080
+vn 0.662008 0.496200 -0.561693
+vn 0.680380 0.457503 -0.572466
+vn 0.368084 0.854915 -0.365490
+vn -0.000977 0.995849 -0.090670
+vn -0.133000 0.991028 0.012665
+vn 0.643055 0.385266 -0.661824
+vn 0.417737 0.592669 -0.688620
+vn 0.583941 0.449263 -0.676107
+vn 0.614093 0.417676 -0.669637
+vn 0.170751 0.736290 -0.654714
+vn -0.265786 0.836665 -0.478835
+vn -0.407270 0.826136 -0.389294
+vn 0.615162 0.310160 -0.724784
+vn 0.348979 0.407514 -0.843867
+vn 0.543901 0.341472 -0.766472
+vn 0.580096 0.326151 -0.746361
+vn 0.069582 0.463820 -0.883175
+vn -0.401532 0.470992 -0.785394
+vn -0.547868 0.447432 -0.706809
+vn 0.621265 0.212806 -0.754112
+vn 0.364025 0.167394 -0.916196
+vn 0.552660 0.201697 -0.808588
+vn 0.587542 0.207465 -0.782128
+vn 0.091739 0.110477 -0.989624
+vn -0.371838 -0.003143 -0.928251
+vn -0.517106 -0.043641 -0.854762
+vn 0.659688 0.119236 -0.741966
+vn 0.458815 -0.063295 -0.886258
+vn 0.607837 0.067385 -0.791162
+vn 0.634388 0.093417 -0.767327
+vn 0.231208 -0.229011 -0.945555
+vn -0.184667 -0.458785 -0.869106
+vn -0.323252 -0.515549 -0.793512
+vn 0.720176 0.054567 -0.691610
+vn 0.607959 -0.222816 -0.762047
+vn 0.694662 -0.025422 -0.718863
+vn 0.708121 0.014557 -0.705924
+vn 0.450667 -0.463729 -0.762749
+vn 0.109836 -0.773766 -0.623829
+vn -0.018220 -0.841792 -0.539476
+vn 0.786493 0.036073 -0.616504
+vn 0.771477 -0.268349 -0.576830
+vn 0.789850 -0.051943 -0.611042
+vn 0.788934 -0.007935 -0.614368
+vn 0.691305 -0.530747 -0.490249
+vn 0.432783 -0.863735 -0.258095
+vn 0.316233 -0.934965 -0.160680
+vn 0.840877 0.068789 -0.536790
+vn 0.905576 -0.187750 -0.380291
+vn 0.867916 -0.005036 -0.496628
+vn 0.855251 0.031892 -0.517228
+vn 0.888638 -0.412152 -0.200995
+vn 0.697592 -0.704550 0.130039
+vn 0.590503 -0.770074 0.241279
+vn 0.868740 0.143864 -0.473861
+vn 0.974334 -0.002594 -0.225043
+vn 0.907956 0.102756 -0.406262
+vn 0.889218 0.123417 -0.440474
+vn 0.989807 -0.139653 0.027406
+vn 0.833369 -0.338878 0.436598
+vn 0.731101 -0.391369 0.558794
+vn 0.862636 0.241218 -0.444502
+vn 0.899197 0.242500 -0.364147
+vn 0.506485 0.571612 0.645527
+vn 0.763726 0.399487 -0.507035
+vn 0.757195 0.469680 -0.453871
+vn 0.697439 0.417951 -0.582141
+vn -0.133000 0.991028 0.012696
+vn 0.583911 0.449263 -0.676107
+vn 0.348979 0.407483 -0.843867
+vn 0.543931 0.341472 -0.766472
+vn -0.401532 0.470992 -0.785424
+vn 0.091708 0.110477 -0.989624
+vn 0.659719 0.119236 -0.741966
+vn 0.694662 -0.025452 -0.718863
+vn 0.109836 -0.773797 -0.623829
+vn 0.786493 0.036103 -0.616504
+vn 0.771477 -0.268349 -0.576861
+vn 0.840877 0.068789 -0.536821
+vn 0.855220 0.031892 -0.517228
+vn 0.907956 0.102725 -0.406262
+vn 0.731101 -0.391369 0.558824
+vn 0.841060 0.204260 -0.500870
+vn 0.784539 0.059572 -0.617145
+vn 0.798791 0.241432 -0.550981
+vn 0.865413 0.414045 -0.282052
+vn 0.760613 0.506211 -0.406415
+vn 0.723441 0.675710 0.141453
+vn 0.536637 0.839961 -0.080142
+vn 0.548235 0.746971 0.376080
+vn 0.335978 0.933622 0.124271
+vn 0.752129 0.250740 -0.609424
+vn 0.644826 0.529283 -0.551347
+vn 0.330332 0.881069 -0.338450
+vn 0.101566 0.980316 -0.169195
+vn 0.708152 0.230750 -0.667257
+vn 0.535752 0.479720 -0.694845
+vn 0.135899 0.792749 -0.594165
+vn -0.119327 0.879971 -0.459731
+vn 0.673544 0.184545 -0.715720
+vn 0.449904 0.365093 -0.814997
+vn -0.017029 0.588488 -0.808313
+vn -0.293130 0.647877 -0.703055
+vn 0.653584 0.119144 -0.747368
+vn 0.400433 0.202857 -0.893582
+vn -0.105197 0.299326 -0.948302
+vn -0.393292 0.319315 -0.862148
+vn 0.651326 0.044496 -0.757439
+vn 0.394848 0.017670 -0.918546
+vn -0.115177 -0.030641 -0.992859
+vn -0.404645 -0.055605 -0.912748
+vn 0.667104 -0.028016 -0.744407
+vn 0.433973 -0.162206 -0.886196
+vn -0.045442 -0.351268 -0.935148
+vn -0.325419 -0.419904 -0.847194
+vn 0.698508 -0.087374 -0.710196
+vn 0.511856 -0.309458 -0.801355
+vn 0.093356 -0.613666 -0.783990
+vn -0.167669 -0.718070 -0.675436
+vn 0.740776 -0.124516 -0.660085
+vn 0.616688 -0.401624 -0.677023
+vn 0.280160 -0.777917 -0.562395
+vn 0.044557 -0.904721 -0.423658
+vn 0.787439 -0.133824 -0.601642
+vn 0.732444 -0.424696 -0.532060
+vn 0.486465 -0.819056 -0.304086
+vn 0.278970 -0.951415 -0.130131
+vn 0.831416 -0.113834 -0.543809
+vn 0.841578 -0.375134 -0.388592
+vn 0.680929 -0.730735 -0.048372
+vn 0.499893 -0.851070 0.160375
+vn 0.866024 -0.067629 -0.495376
+vn 0.927396 -0.260506 -0.268410
+vn 0.833857 -0.526444 0.165746
+vn 0.673696 -0.618976 0.403699
+vn 0.885983 -0.002228 -0.463698
+vn 0.976867 -0.098239 -0.189856
+vn 0.922025 -0.237312 0.305765
+vn 0.773888 -0.290414 0.562761
+vn 0.888241 0.072390 -0.453627
+vn 0.982452 0.086886 -0.164861
+vn 0.932005 0.092654 0.350291
+vn 0.785211 0.084506 0.613392
+vn 0.872463 0.144902 -0.466659
+vn 0.943327 0.266793 -0.197241
+vn 0.862270 0.413282 0.292611
+vn 0.705985 0.448805 0.547838
+vn 0.841060 0.204291 -0.500870
+vn 0.784570 0.059572 -0.617145
+vn 0.760613 0.506211 -0.406384
+vn 0.723441 0.675680 0.141423
+vn 0.336009 0.933622 0.124271
+vn 0.535722 0.479720 -0.694845
+vn 0.135899 0.792749 -0.594134
+vn -0.016999 0.588488 -0.808313
+vn -0.293100 0.647877 -0.703055
+vn 0.400433 0.202857 -0.893551
+vn 0.651326 0.044496 -0.757469
+vn 0.394818 0.017670 -0.918577
+vn -0.045442 -0.351238 -0.935148
+vn 0.093387 -0.613666 -0.783990
+vn 0.280160 -0.777947 -0.562395
+vn 0.486496 -0.819056 -0.304056
+vn 0.279000 -0.951415 -0.130131
+vn 0.841578 -0.375134 -0.388562
+vn 0.499924 -0.851070 0.160375
+vn 0.866024 -0.067629 -0.495346
+vn 0.976867 -0.098270 -0.189856
+vn 0.922056 -0.237281 0.305765
+vn 0.982452 0.086886 -0.164830
+vn 0.932035 0.092685 0.350291
+vn 0.785241 0.084506 0.613392
+vn 0.872463 0.144932 -0.466659
+vn 0.943327 0.266793 -0.197211
+vn 0.862300 0.413282 0.292611
+vn 0.705985 0.448805 0.547807
+vn -0.602557 -0.161321 -0.781579
+vn 0.115879 -0.991913 0.051546
+vn 0.569872 -0.461409 0.679922
+vn 0.613330 -0.220466 0.758415
+vn 0.618824 -0.013581 0.785363
+vn 0.597156 0.195227 0.777978
+vn 0.547441 0.400739 0.734611
+vn 0.291025 0.843501 0.451399
+vn -0.326334 0.885983 -0.329356
+vn 0.618976 -0.017457 0.785180
+vn 0.066836 -0.997681 -0.011322
+vn -0.473830 -0.584338 -0.658773
+vn -0.560137 -0.358684 -0.746696
+vn -0.603107 -0.157506 -0.781915
+vn -0.619861 0.051881 -0.782983
+vn -0.608539 0.264595 -0.748070
+vn -0.438063 0.757622 -0.483779
+vn 0.158361 0.943083 0.292367
+vn -0.298898 -0.455184 0.838710
+vn -0.785272 -0.055574 0.616627
+vn -0.454390 -0.633290 0.626423
+vn 0.329417 -0.651906 0.682974
+vn 0.086978 -0.932493 0.350475
+vn 0.897397 -0.441145 0.003815
+vn 0.716025 -0.653005 -0.246620
+vn -0.653432 -0.658773 0.372845
+vn -0.224281 -0.973388 -0.046602
+vn 0.481399 -0.685232 -0.546495
+vn -0.843684 -0.517258 0.143559
+vn -0.521531 -0.751701 -0.403577
+vn 0.255623 -0.517869 -0.816340
+vn -0.969604 -0.244484 0.005127
+vn -0.717399 -0.325297 -0.616016
+vn 0.106540 -0.194739 -0.975036
+vn -0.996765 0.080172 -0.004120
+vn -0.758629 0.180090 -0.626087
+vn 0.074801 0.186163 -0.979644
+vn -0.922208 0.369335 0.114292
+vn -0.642232 0.628254 -0.439070
+vn 0.161504 0.522233 -0.837336
+vn -0.766472 0.551256 0.329508
+vn -0.400708 0.910184 -0.104678
+vn 0.342265 0.734306 -0.586200
+vn -0.566881 0.576373 0.588549
+vn -0.091281 0.950774 0.296030
+vn 0.575640 0.766411 -0.284951
+vn 0.784570 0.059542 -0.617145
+vn -0.376293 0.430647 0.820307
+vn 0.205054 0.727439 0.654775
+vn 0.800806 0.598712 -0.014435
+vn -0.250587 0.154088 0.955718
+vn 0.401807 0.299661 0.865291
+vn 0.950530 0.275399 0.143498
+vn -0.224036 -0.170202 0.959593
+vn 0.444899 -0.205390 0.871700
+vn 0.983520 -0.105411 0.146764
+vn -0.298898 -0.455153 0.838710
+vn -0.454360 -0.633290 0.626453
+vn 0.897427 -0.441115 0.003815
+vn 0.716056 -0.653005 -0.246651
+vn 0.478042 0.346324 -0.807154
+vn 0.590289 0.472304 -0.654561
+vn 0.786279 0.049104 -0.615894
+vn -0.653401 -0.658773 0.372845
+vn 0.732505 0.487350 -0.475265
+vn 0.866543 0.386975 -0.315104
+vn 0.106510 -0.194739 -0.975036
+vn 0.956420 0.196387 -0.216041
+vn -0.996765 0.080203 -0.004120
+vn -0.758660 0.180090 -0.626057
+vn 0.074770 0.186193 -0.979644
+vn 0.977935 -0.034547 -0.205969
+vn -0.922208 0.369366 0.114322
+vn 0.161473 0.522233 -0.837367
+vn 0.925565 -0.243690 -0.289712
+vn -0.766472 0.551256 0.329539
+vn 0.342235 0.734306 -0.586200
+vn 0.813379 -0.373730 -0.445723
+vn -0.566851 0.576373 0.588549
+vn 0.671163 -0.388348 -0.631397
+vn -0.376263 0.430647 0.820307
+vn 0.205023 0.727439 0.654775
+vn 0.800806 0.598743 -0.014435
+vn 0.537034 -0.283303 -0.794519
+vn 0.950530 0.275369 0.143498
+vn 0.447127 -0.088626 -0.890042
+vn 0.444899 -0.205390 0.871670
+vn 0.983520 -0.105411 0.146733
+vn 0.425611 0.141789 -0.893704
+s 1
+f 1204/1/1 1236/2/2 1176/3/3
+f 1132/4/4 1176/3/3 1177/5/5
+f 1131/6/6 1177/5/5 980/7/7
+f 980/7/7 448/8/8 466/9/9
+f 940/10/10 980/7/7 466/9/9
+f 466/9/9 448/8/8 175/11/11
+f 223/12/12 175/11/11 174/13/13
+f 224/14/14 174/13/13 117/15/15
+f 1204/1/1 1176/3/3 1132/4/4
+f 1132/4/4 1177/5/5 1131/6/6
+f 1131/6/6 980/7/7 940/10/10
+f 466/9/9 175/11/11 223/12/12
+f 223/12/12 174/13/13 224/14/14
+f 224/14/14 117/15/15 148/16/16
+f 1260/17/17 1208/18/18 1238/19/19
+f 1253/20/20 1109/21/21 1208/18/18
+f 1183/22/22 979/23/23 1109/21/21
+f 1013/24/24 868/25/25 979/23/23
+f 889/26/26 760/27/27 868/25/25
+f 760/27/27 580/28/28 593/29/29
+f 773/30/30 580/28/28 760/27/27
+f 580/28/28 487/31/31 593/29/29
+f 464/32/32 378/33/33 487/31/31
+f 341/34/34 247/35/35 378/33/33
+f 170/36/36 144/37/37 247/35/35
+f 102/38/38 119/39/39 144/37/37
+f 119/39/39 1260/17/17 1238/19/19
+f 95/40/40 1260/17/17 119/39/39
+f 1260/17/17 1253/20/20 1208/18/18
+f 1253/20/20 1183/22/22 1109/21/21
+f 1183/22/22 1013/24/24 979/23/23
+f 1013/24/24 889/26/26 868/25/25
+f 889/26/26 773/30/30 760/27/27
+f 580/28/28 464/32/32 487/31/31
+f 464/32/32 341/34/34 378/33/33
+f 341/34/34 170/36/36 247/35/35
+f 170/36/36 102/38/38 144/37/37
+f 102/38/38 95/40/40 119/39/39
+f 1237/41/41 1207/42/42 661/43/43
+f 1237/41/41 1253/20/20 1260/17/17
+f 697/44/44 696/45/45 1253/20/20
+f 1260/17/17 697/44/44 1253/20/20
+f 1207/42/42 1108/46/46 661/43/43
+f 1207/42/42 1183/22/22 1253/20/20
+f 696/45/45 695/47/47 1183/22/22
+f 1253/20/20 696/45/45 1183/22/22
+f 1108/46/46 978/48/48 661/43/43
+f 1108/46/46 1013/24/24 1183/22/22
+f 695/47/47 694/49/49 1013/24/24
+f 1183/22/22 695/47/47 1013/24/24
+f 978/48/48 867/50/50 661/43/43
+f 978/48/48 889/26/26 1013/24/24
+f 694/49/49 693/51/51 889/26/26
+f 1013/24/24 694/49/49 889/26/26
+f 867/50/50 759/52/52 661/43/43
+f 867/50/50 773/30/30 889/26/26
+f 693/51/51 690/53/53 773/30/30
+f 889/26/26 693/51/51 773/30/30
+f 759/52/52 592/54/54 661/43/43
+f 773/30/30 592/54/54 580/28/28
+f 759/52/52 592/54/54 773/30/30
+f 690/53/53 668/55/55 580/28/28
+f 773/30/30 580/28/28 690/53/53
+f 592/54/54 486/56/56 661/43/43
+f 592/54/54 464/32/32 580/28/28
+f 580/28/28 464/32/32 668/55/55
+f 486/56/56 377/57/57 661/43/43
+f 486/56/56 341/34/34 464/32/32
+f 464/32/32 668/55/55 341/34/34
+f 377/57/57 246/58/58 661/43/43
+f 377/57/57 170/36/36 341/34/34
+f 341/34/34 668/55/55 170/36/36
+f 246/58/58 143/59/59 661/43/43
+f 246/58/58 102/38/38 170/36/36
+f 170/36/36 668/55/55 102/38/38
+f 143/59/59 118/60/60 661/43/43
+f 143/59/59 95/40/40 102/38/38
+f 102/38/38 668/55/55 95/40/40
+f 118/60/60 117/15/15 661/43/43
+f 118/60/60 95/40/40 94/61/61
+f 95/40/40 668/55/55 94/61/61
+f 117/15/15 142/62/62 661/43/43
+f 117/15/15 94/61/61 101/63/63
+f 94/61/61 668/55/55 101/63/63
+f 142/62/62 245/64/64 661/43/43
+f 142/62/62 101/63/63 169/65/65
+f 101/63/63 668/55/55 169/65/65
+f 245/64/64 376/66/66 661/43/43
+f 245/64/64 169/65/65 340/67/67
+f 169/65/65 668/55/55 340/67/67
+f 376/66/66 485/68/68 661/43/43
+f 376/66/66 340/67/67 463/69/69
+f 340/67/67 668/55/55 463/69/69
+f 485/68/68 591/70/70 661/43/43
+f 485/68/68 463/69/69 579/71/71
+f 463/69/69 668/55/55 579/71/71
+f 591/70/70 647/72/72 661/43/43
+f 591/70/70 579/71/71 646/73/73
+f 579/71/71 668/55/55 646/73/73
+f 647/72/72 758/74/74 661/43/43
+f 647/72/72 646/73/73 772/75/75
+f 668/55/55 690/53/53 772/75/75
+f 646/73/73 668/55/55 772/75/75
+f 758/74/74 866/76/76 661/43/43
+f 758/74/74 772/75/75 888/77/77
+f 690/53/53 693/51/51 888/77/77
+f 772/75/75 690/53/53 888/77/77
+f 866/76/76 977/78/78 661/43/43
+f 866/76/76 888/77/77 1012/79/79
+f 693/51/51 694/49/49 1012/79/79
+f 888/77/77 693/51/51 1012/79/79
+f 977/78/78 1107/80/80 661/43/43
+f 977/78/78 1012/79/79 1182/81/81
+f 694/49/49 695/47/47 1182/81/81
+f 1012/79/79 694/49/49 1182/81/81
+f 1107/80/80 1206/82/82 661/43/43
+f 1107/80/80 1182/81/81 1252/83/83
+f 695/47/47 696/45/45 1252/83/83
+f 1182/81/81 695/47/47 1252/83/83
+f 1206/82/82 1236/2/2 661/43/43
+f 1206/82/82 1252/83/83 1259/84/84
+f 696/45/45 697/44/44 1259/84/84
+f 1252/83/83 696/45/45 1259/84/84
+f 1236/2/2 1237/41/41 661/43/43
+f 1236/2/2 1259/84/84 1260/17/17
+f 1259/84/84 697/44/44 1260/17/17
+f 1237/41/41 1253/20/20 1207/42/42
+f 1207/42/42 1183/22/22 1108/46/46
+f 1108/46/46 1013/24/24 978/48/48
+f 978/48/48 889/26/26 867/50/50
+f 867/50/50 773/30/30 759/52/52
+f 592/54/54 486/56/56 464/32/32
+f 486/56/56 377/57/57 341/34/34
+f 377/57/57 246/58/58 170/36/36
+f 246/58/58 143/59/59 102/38/38
+f 143/59/59 118/60/60 95/40/40
+f 118/60/60 117/15/15 94/61/61
+f 117/15/15 101/63/63 142/62/62
+f 142/62/62 169/65/65 245/64/64
+f 245/64/64 340/67/67 376/66/66
+f 376/66/66 463/69/69 485/68/68
+f 485/68/68 579/71/71 591/70/70
+f 591/70/70 646/73/73 647/72/72
+f 647/72/72 772/75/75 758/74/74
+f 758/74/74 888/77/77 866/76/76
+f 866/76/76 1012/79/79 977/78/78
+f 977/78/78 1182/81/81 1107/80/80
+f 1107/80/80 1252/83/83 1206/82/82
+f 1206/82/82 1259/84/84 1236/2/2
+f 1236/2/2 1260/17/17 1237/41/41
+f 777/85/85 659/86/86 766/87/87
+f 777/85/85 824/88/88 835/89/89
+f 835/89/89 924/90/90 945/91/91
+f 945/91/91 1030/92/92 1068/93/93
+f 1068/93/93 1067/94/94 1129/95/95
+f 1129/95/95 1117/96/96 1163/97/97
+f 1163/97/97 1155/98/98 1200/99/99
+f 1200/99/99 1160/100/100 1203/101/101
+f 1203/101/101 1161/102/102 1205/103/103
+f 1205/103/103 660/104/104 1161/102/102
+f 766/87/87 659/86/86 734/105/105
+f 766/87/87 789/106/106 824/88/88
+f 824/88/88 846/107/107 924/90/90
+f 924/90/90 895/108/108 1030/92/92
+f 1030/92/92 906/109/109 1067/94/94
+f 1067/94/94 917/110/110 1117/96/96
+f 1117/96/96 931/111/111 1155/98/98
+f 1155/98/98 937/112/112 1160/100/100
+f 1160/100/100 1161/102/102 938/113/113
+f 1161/102/102 660/104/104 938/113/113
+f 734/105/105 659/86/86 701/114/114
+f 734/105/105 708/115/115 789/106/106
+f 789/106/106 731/116/116 846/107/107
+f 846/107/107 738/117/117 895/108/108
+f 895/108/108 743/118/118 906/109/109
+f 906/109/109 746/119/119 917/110/110
+f 917/110/110 752/120/120 931/111/111
+f 931/111/111 754/121/121 937/112/112
+f 937/112/112 938/113/113 756/122/122
+f 938/113/113 660/104/104 756/122/122
+f 701/114/114 659/86/86 645/123/123
+f 708/115/115 645/123/123 641/124/124
+f 701/114/114 645/123/123 708/115/115
+f 731/116/116 641/124/124 632/125/125
+f 708/115/115 641/124/124 731/116/116
+f 738/117/117 632/125/125 611/126/126
+f 731/116/116 632/125/125 738/117/117
+f 743/118/118 611/126/126 606/127/127
+f 738/117/117 611/126/126 743/118/118
+f 746/119/119 606/127/127 604/128/128
+f 743/118/118 606/127/127 746/119/119
+f 752/120/120 604/128/128 599/129/129
+f 746/119/119 604/128/128 752/120/120
+f 754/121/121 599/129/129 596/130/130
+f 752/120/120 599/129/129 754/121/121
+f 756/122/122 597/131/131 596/130/130
+f 754/121/121 756/122/122 596/130/130
+f 756/122/122 660/104/104 597/131/131
+f 645/123/123 659/86/86 630/132/132
+f 645/123/123 566/133/133 641/124/124
+f 641/124/124 507/134/134 632/125/125
+f 632/125/125 459/135/135 611/126/126
+f 611/126/126 445/136/136 606/127/127
+f 606/127/127 435/137/137 604/128/128
+f 604/128/128 420/138/138 599/129/129
+f 599/129/129 596/130/130 414/139/139
+f 596/130/130 597/131/131 415/140/140
+f 597/131/131 660/104/104 415/140/140
+f 630/132/132 659/86/86 587/141/141
+f 630/132/132 529/142/142 566/133/133
+f 566/133/133 427/143/143 507/134/134
+f 507/134/134 320/144/144 459/135/135
+f 459/135/135 288/145/145 445/136/136
+f 445/136/136 235/146/146 435/137/137
+f 435/137/137 197/147/147 420/138/138
+f 420/138/138 414/139/139 190/148/148
+f 414/139/139 415/140/140 191/149/149
+f 415/140/140 660/104/104 191/149/149
+f 587/141/141 659/86/86 578/150/150
+f 587/141/141 525/151/151 529/142/142
+f 529/142/142 408/152/152 427/143/143
+f 427/143/143 286/153/153 320/144/144
+f 320/144/144 221/154/154 288/145/145
+f 288/145/145 187/155/155 235/146/146
+f 235/146/146 154/156/156 197/147/147
+f 197/147/147 146/157/157 190/148/148
+f 190/148/148 147/158/158 191/149/149
+f 191/149/149 660/104/104 147/158/158
+f 578/150/150 659/86/86 577/159/159
+f 578/150/150 524/160/160 525/151/151
+f 525/151/151 409/161/161 408/152/152
+f 408/152/152 287/162/162 286/153/153
+f 286/153/153 222/163/163 221/154/154
+f 221/154/154 188/164/164 187/155/155
+f 187/155/155 153/165/165 154/156/156
+f 154/156/156 145/166/166 146/157/157
+f 147/158/158 145/166/166 148/16/16
+f 146/157/157 145/166/166 147/158/158
+f 147/158/158 148/16/16 660/104/104
+f 577/159/159 659/86/86 586/167/167
+f 577/159/159 530/168/168 524/160/160
+f 524/160/160 428/169/169 409/161/161
+f 409/161/161 321/170/170 287/162/162
+f 287/162/162 289/171/171 222/163/163
+f 222/163/163 236/172/172 188/164/164
+f 188/164/164 196/173/173 153/165/165
+f 153/165/165 189/174/174 145/166/166
+f 145/166/166 192/175/175 148/16/16
+f 148/16/16 192/175/175 660/104/104
+f 586/167/167 659/86/86 629/176/176
+f 586/167/167 567/177/177 530/168/168
+f 530/168/168 508/178/178 428/169/169
+f 428/169/169 460/179/179 321/170/170
+f 321/170/170 446/180/180 289/171/171
+f 289/171/171 436/181/181 236/172/172
+f 236/172/172 419/182/182 196/173/173
+f 196/173/173 413/183/183 189/174/174
+f 189/174/174 416/184/184 192/175/175
+f 192/175/175 416/184/184 660/104/104
+f 629/176/176 659/86/86 638/185/185
+f 629/176/176 601/186/186 567/177/177
+f 567/177/177 554/187/187 508/178/178
+f 508/178/178 533/188/188 460/179/179
+f 460/179/179 526/189/189 446/180/180
+f 446/180/180 517/190/190 436/181/181
+f 436/181/181 504/191/191 419/182/182
+f 419/182/182 500/192/192 413/183/183
+f 413/183/183 501/193/193 416/184/184
+f 416/184/184 501/193/193 660/104/104
+f 638/185/185 659/86/86 644/194/194
+f 638/185/185 642/195/195 601/186/186
+f 601/186/186 633/196/196 554/187/187
+f 554/187/187 612/197/197 533/188/188
+f 533/188/188 607/198/198 526/189/189
+f 526/189/189 605/199/199 517/190/190
+f 517/190/190 598/200/200 504/191/191
+f 504/191/191 594/201/201 500/192/192
+f 500/192/192 595/202/202 501/193/193
+f 501/193/193 595/202/202 660/104/104
+f 644/194/194 659/86/86 658/203/203
+f 642/195/195 658/203/203 657/204/204
+f 644/194/194 658/203/203 642/195/195
+f 633/196/196 657/204/204 656/205/205
+f 642/195/195 657/204/204 633/196/196
+f 612/197/197 656/205/205 655/206/206
+f 633/196/196 656/205/205 612/197/197
+f 607/198/198 655/206/206 654/207/207
+f 612/197/197 655/206/206 607/198/198
+f 607/198/198 653/208/208 605/199/199
+f 605/199/199 652/209/209 598/200/200
+f 594/201/201 652/209/209 649/210/210
+f 598/200/200 652/209/209 594/201/201
+f 594/201/201 651/211/211 595/202/202
+f 595/202/202 651/211/211 660/104/104
+f 658/203/203 659/86/86 700/212/212
+f 657/204/204 700/212/212 709/213/213
+f 658/203/203 700/212/212 657/204/204
+f 656/205/205 709/213/213 730/214/214
+f 657/204/204 709/213/213 656/205/205
+f 655/206/206 730/214/214 739/215/215
+f 656/205/205 730/214/214 655/206/206
+f 654/207/207 739/215/215 744/216/216
+f 655/206/206 739/215/215 654/207/207
+f 654/207/207 745/217/217 653/208/208
+f 653/208/208 751/218/218 652/209/209
+f 649/210/210 751/218/218 753/219/219
+f 652/209/209 751/218/218 649/210/210
+f 649/210/210 755/220/220 651/211/211
+f 651/211/211 755/220/220 660/104/104
+f 700/212/212 659/86/86 720/221/221
+f 700/212/212 749/222/222 709/213/213
+f 709/213/213 801/223/223 730/214/214
+f 730/214/214 823/224/224 739/215/215
+f 739/215/215 828/225/225 744/216/216
+f 744/216/216 840/226/226 745/217/217
+f 745/217/217 850/227/227 751/218/218
+f 751/218/218 852/228/228 753/219/219
+f 753/219/219 853/229/229 755/220/220
+f 755/220/220 660/104/104 853/229/229
+f 720/221/221 659/86/86 733/230/230
+f 720/221/221 790/231/231 749/222/222
+f 749/222/222 847/232/232 801/223/223
+f 801/223/223 894/233/233 823/224/224
+f 823/224/224 907/234/234 828/225/225
+f 828/225/225 916/235/235 840/226/226
+f 840/226/226 930/236/236 850/227/227
+f 850/227/227 936/237/237 852/228/228
+f 852/228/228 853/229/229 939/238/238
+f 853/229/229 660/104/104 939/238/238
+f 733/230/230 659/86/86 765/239/239
+f 733/230/230 825/240/240 790/231/231
+f 790/231/231 923/241/241 847/232/232
+f 847/232/232 1031/242/242 894/233/233
+f 894/233/233 1066/243/243 907/234/234
+f 907/234/234 1116/244/244 916/235/235
+f 916/235/235 1154/245/245 930/236/236
+f 930/236/236 1159/246/246 936/237/237
+f 936/237/237 939/238/238 1162/247/247
+f 939/238/238 660/104/104 1162/247/247
+f 765/239/239 659/86/86 776/248/248
+f 765/239/239 834/249/249 825/240/240
+f 825/240/240 946/250/250 923/241/241
+f 923/241/241 1069/251/251 1031/242/242
+f 1031/242/242 1130/252/252 1066/243/243
+f 1066/243/243 1164/253/253 1116/244/244
+f 1116/244/244 1199/254/254 1154/245/245
+f 1154/245/245 1202/255/255 1159/246/246
+f 1159/246/246 1204/1/1 1162/247/247
+f 1162/247/247 660/104/104 1204/1/1
+f 776/248/248 659/86/86 777/85/85
+f 776/248/248 835/89/89 834/249/249
+f 834/249/249 945/91/91 946/250/250
+f 946/250/250 1068/93/93 1069/251/251
+f 1069/251/251 1129/95/95 1130/252/252
+f 1130/252/252 1163/97/97 1164/253/253
+f 1164/253/253 1200/99/99 1199/254/254
+f 1199/254/254 1203/101/101 1202/255/255
+f 1204/1/1 1205/103/103 1203/101/101
+f 1202/255/255 1203/101/101 1204/1/1
+f 1204/1/1 660/104/104 1205/103/103
+f 777/85/85 766/87/87 824/88/88
+f 835/89/89 824/88/88 924/90/90
+f 945/91/91 924/90/90 1030/92/92
+f 1068/93/93 1030/92/92 1067/94/94
+f 1129/95/95 1067/94/94 1117/96/96
+f 1163/97/97 1117/96/96 1155/98/98
+f 1200/99/99 1155/98/98 1160/100/100
+f 1203/101/101 1160/100/100 1161/102/102
+f 766/87/87 734/105/105 789/106/106
+f 824/88/88 789/106/106 846/107/107
+f 924/90/90 846/107/107 895/108/108
+f 1030/92/92 895/108/108 906/109/109
+f 1067/94/94 906/109/109 917/110/110
+f 1117/96/96 917/110/110 931/111/111
+f 1155/98/98 931/111/111 937/112/112
+f 1160/100/100 937/112/112 938/113/113
+f 734/105/105 701/114/114 708/115/115
+f 789/106/106 708/115/115 731/116/116
+f 846/107/107 731/116/116 738/117/117
+f 895/108/108 738/117/117 743/118/118
+f 906/109/109 743/118/118 746/119/119
+f 917/110/110 746/119/119 752/120/120
+f 931/111/111 752/120/120 754/121/121
+f 937/112/112 754/121/121 756/122/122
+f 645/123/123 630/132/132 566/133/133
+f 641/124/124 566/133/133 507/134/134
+f 632/125/125 507/134/134 459/135/135
+f 611/126/126 459/135/135 445/136/136
+f 606/127/127 445/136/136 435/137/137
+f 604/128/128 435/137/137 420/138/138
+f 599/129/129 420/138/138 414/139/139
+f 596/130/130 415/140/140 414/139/139
+f 630/132/132 587/141/141 529/142/142
+f 566/133/133 529/142/142 427/143/143
+f 507/134/134 427/143/143 320/144/144
+f 459/135/135 320/144/144 288/145/145
+f 445/136/136 288/145/145 235/146/146
+f 435/137/137 235/146/146 197/147/147
+f 420/138/138 197/147/147 190/148/148
+f 414/139/139 191/149/149 190/148/148
+f 587/141/141 578/150/150 525/151/151
+f 529/142/142 525/151/151 408/152/152
+f 427/143/143 408/152/152 286/153/153
+f 320/144/144 286/153/153 221/154/154
+f 288/145/145 221/154/154 187/155/155
+f 235/146/146 187/155/155 154/156/156
+f 197/147/147 154/156/156 146/157/157
+f 190/148/148 146/157/157 147/158/158
+f 578/150/150 577/159/159 524/160/160
+f 525/151/151 524/160/160 409/161/161
+f 408/152/152 409/161/161 287/162/162
+f 286/153/153 287/162/162 222/163/163
+f 221/154/154 222/163/163 188/164/164
+f 187/155/155 188/164/164 153/165/165
+f 154/156/156 153/165/165 145/166/166
+f 577/159/159 586/167/167 530/168/168
+f 524/160/160 530/168/168 428/169/169
+f 409/161/161 428/169/169 321/170/170
+f 287/162/162 321/170/170 289/171/171
+f 222/163/163 289/171/171 236/172/172
+f 188/164/164 236/172/172 196/173/173
+f 153/165/165 196/173/173 189/174/174
+f 145/166/166 189/174/174 192/175/175
+f 586/167/167 629/176/176 567/177/177
+f 530/168/168 567/177/177 508/178/178
+f 428/169/169 508/178/178 460/179/179
+f 321/170/170 460/179/179 446/180/180
+f 289/171/171 446/180/180 436/181/181
+f 236/172/172 436/181/181 419/182/182
+f 196/173/173 419/182/182 413/183/183
+f 189/174/174 413/183/183 416/184/184
+f 629/176/176 638/185/185 601/186/186
+f 567/177/177 601/186/186 554/187/187
+f 508/178/178 554/187/187 533/188/188
+f 460/179/179 533/188/188 526/189/189
+f 446/180/180 526/189/189 517/190/190
+f 436/181/181 517/190/190 504/191/191
+f 419/182/182 504/191/191 500/192/192
+f 413/183/183 500/192/192 501/193/193
+f 638/185/185 644/194/194 642/195/195
+f 601/186/186 642/195/195 633/196/196
+f 554/187/187 633/196/196 612/197/197
+f 533/188/188 612/197/197 607/198/198
+f 526/189/189 607/198/198 605/199/199
+f 517/190/190 605/199/199 598/200/200
+f 504/191/191 598/200/200 594/201/201
+f 500/192/192 594/201/201 595/202/202
+f 607/198/198 654/207/207 653/208/208
+f 605/199/199 653/208/208 652/209/209
+f 594/201/201 649/210/210 651/211/211
+f 654/207/207 744/216/216 745/217/217
+f 653/208/208 745/217/217 751/218/218
+f 649/210/210 753/219/219 755/220/220
+f 700/212/212 720/221/221 749/222/222
+f 709/213/213 749/222/222 801/223/223
+f 730/214/214 801/223/223 823/224/224
+f 739/215/215 823/224/224 828/225/225
+f 744/216/216 828/225/225 840/226/226
+f 745/217/217 840/226/226 850/227/227
+f 751/218/218 850/227/227 852/228/228
+f 753/219/219 852/228/228 853/229/229
+f 720/221/221 733/230/230 790/231/231
+f 749/222/222 790/231/231 847/232/232
+f 801/223/223 847/232/232 894/233/233
+f 823/224/224 894/233/233 907/234/234
+f 828/225/225 907/234/234 916/235/235
+f 840/226/226 916/235/235 930/236/236
+f 850/227/227 930/236/236 936/237/237
+f 852/228/228 936/237/237 939/238/238
+f 733/230/230 765/239/239 825/240/240
+f 790/231/231 825/240/240 923/241/241
+f 847/232/232 923/241/241 1031/242/242
+f 894/233/233 1031/242/242 1066/243/243
+f 907/234/234 1066/243/243 1116/244/244
+f 916/235/235 1116/244/244 1154/245/245
+f 930/236/236 1154/245/245 1159/246/246
+f 936/237/237 1159/246/246 1162/247/247
+f 765/239/239 776/248/248 834/249/249
+f 825/240/240 834/249/249 946/250/250
+f 923/241/241 946/250/250 1069/251/251
+f 1031/242/242 1069/251/251 1130/252/252
+f 1066/243/243 1130/252/252 1164/253/253
+f 1116/244/244 1164/253/253 1199/254/254
+f 1154/245/245 1199/254/254 1202/255/255
+f 1159/246/246 1202/255/255 1204/1/1
+f 776/248/248 777/85/85 835/89/89
+f 834/249/249 835/89/89 945/91/91
+f 946/250/250 945/91/91 1068/93/93
+f 1069/251/251 1068/93/93 1129/95/95
+f 1130/252/252 1129/95/95 1163/97/97
+f 1164/253/253 1163/97/97 1200/99/99
+f 1199/254/254 1200/99/99 1203/101/101
+f 698/256/256 870/257/257 699/258/258
+f 699/258/258 1033/259/259 702/260/260
+f 702/260/260 1062/261/261 703/262/262
+f 703/262/262 1125/263/263 704/264/264
+f 704/264/264 1178/265/265 705/266/266
+f 705/266/266 1234/267/267 707/268/268
+f 707/268/268 1271/269/269 712/270/270
+f 712/270/270 1297/271/271 719/272/272
+f 719/272/272 1301/273/273 725/274/274
+f 725/274/274 1308/275/275 727/276/276
+f 727/276/276 1306/277/277 726/278/278
+f 726/278/278 1306/277/277 662/279/279
+f 829/280/280 1011/281/281 870/257/257
+f 870/257/257 1263/282/282 1033/259/259
+f 1033/259/259 1270/283/283 1062/261/261
+f 1062/261/261 1291/284/284 1125/263/263
+f 1125/263/263 1295/285/285 1178/265/265
+f 1178/265/265 1303/286/286 1234/267/267
+f 1234/267/267 1313/287/287 1271/269/269
+f 1271/269/269 1320/288/288 1297/271/271
+f 1297/271/271 1329/289/289 1301/273/273
+f 1301/273/273 1333/290/290 1308/275/275
+f 1308/275/275 1332/291/291 1306/277/277
+f 1306/277/277 1332/291/291 662/279/279
+f 922/292/292 1158/293/293 1011/281/281
+f 1011/281/281 1294/294/294 1263/282/282
+f 1263/282/282 1298/295/295 1270/283/283
+f 1270/283/283 1302/296/296 1291/284/284
+f 1291/284/284 1309/297/297 1295/285/285
+f 1295/285/285 1312/298/298 1303/286/286
+f 1303/286/286 1321/299/299 1313/287/287
+f 1313/287/287 1335/300/300 1320/288/288
+f 1320/288/288 1340/301/301 1329/289/289
+f 1329/289/289 1343/302/302 1333/290/290
+f 1333/290/290 1341/303/303 1332/291/291
+f 1332/291/291 1341/303/303 662/279/279
+f 1005/304/304 1158/293/293 1180/305/305
+f 1158/293/293 1294/294/294 1296/306/306
+f 1294/294/294 1298/295/295 1300/307/307
+f 1298/295/295 1302/296/296 1307/308/308
+f 1302/296/296 1309/297/297 1310/309/309
+f 1309/297/297 1312/298/298 1315/310/310
+f 1312/298/298 1321/299/299 1322/311/311
+f 1321/299/299 1335/300/300 1337/312/312
+f 1335/300/300 1340/301/301 1342/313/313
+f 1340/301/301 1343/302/302 1353/314/314
+f 1343/302/302 1341/303/303 1352/315/315
+f 1341/303/303 1352/315/315 662/279/279
+f 1180/305/305 184/316/316 342/317/317
+f 1038/318/318 1180/305/305 342/317/317
+f 1296/306/306 184/316/316 57/319/319
+f 1180/305/305 1296/306/306 184/316/316
+f 1300/307/307 57/319/319 54/320/320
+f 1296/306/306 1300/307/307 57/319/319
+f 1307/308/308 46/321/321 54/320/320
+f 1300/307/307 1307/308/308 54/320/320
+f 1310/309/309 44/322/322 46/321/321
+f 1307/308/308 1310/309/309 46/321/321
+f 1315/310/310 44/322/322 39/323/323
+f 1310/309/309 1315/310/310 44/322/322
+f 1322/311/311 32/324/324 39/323/323
+f 1315/310/310 1322/311/311 39/323/323
+f 1337/312/312 17/325/325 32/324/324
+f 1322/311/311 1337/312/312 32/324/324
+f 1337/312/312 1342/313/313 12/326/326
+f 1353/314/314 1/327/327 12/326/326
+f 1342/313/313 1353/314/314 12/326/326
+f 1/327/327 1352/315/315 2/328/328
+f 1/327/327 1353/314/314 1352/315/315
+f 1352/315/315 662/279/279 2/328/328
+f 342/317/317 184/316/316 204/329/329
+f 184/316/316 60/330/330 57/319/319
+f 57/319/319 55/331/331 54/320/320
+f 54/320/320 52/332/332 46/321/321
+f 46/321/321 45/333/333 44/322/322
+f 44/322/322 40/334/334 39/323/323
+f 39/323/323 33/335/335 32/324/324
+f 32/324/324 19/336/336 17/325/325
+f 17/325/325 14/337/337 12/326/326
+f 12/326/326 11/338/338 1/327/327
+f 1/327/327 2/328/328 13/339/339
+f 2/328/328 662/279/279 13/339/339
+f 353/340/340 349/341/341 204/329/329
+f 204/329/329 93/342/342 60/330/330
+f 60/330/330 85/343/343 55/331/331
+f 55/331/331 71/344/344 52/332/332
+f 52/332/332 59/345/345 45/333/333
+f 45/333/333 51/346/346 40/334/334
+f 40/334/334 41/347/347 33/335/335
+f 33/335/335 34/348/348 19/336/336
+f 19/336/336 27/349/349 14/337/337
+f 14/337/337 21/350/350 11/338/338
+f 11/338/338 22/351/351 13/339/339
+f 13/339/339 22/351/351 662/279/279
+f 431/352/352 492/353/353 349/341/341
+f 349/341/341 352/354/354 93/342/342
+f 93/342/342 313/355/355 85/343/343
+f 85/343/343 268/356/356 71/344/344
+f 71/344/344 202/357/357 59/345/345
+f 59/345/345 133/358/358 51/346/346
+f 51/346/346 87/359/359 41/347/347
+f 41/347/347 58/360/360 34/348/348
+f 34/348/348 53/361/361 27/349/349
+f 27/349/349 47/362/362 21/350/350
+f 21/350/350 48/363/363 22/351/351
+f 22/351/351 48/363/363 662/279/279
+f 531/364/364 699/258/258 492/353/353
+f 492/353/353 702/260/260 352/354/354
+f 352/354/354 703/262/262 313/355/355
+f 313/355/355 704/264/264 268/356/356
+f 268/356/356 705/266/266 202/357/357
+f 202/357/357 707/268/268 133/358/358
+f 133/358/358 712/270/270 87/359/359
+f 87/359/359 719/272/272 58/360/360
+f 58/360/360 725/274/274 53/361/361
+f 53/361/361 727/276/276 47/362/362
+f 47/362/362 726/278/278 48/363/363
+f 48/363/363 726/278/278 662/279/279
+f 698/256/256 829/280/280 870/257/257
+f 699/258/258 870/257/257 1033/259/259
+f 702/260/260 1033/259/259 1062/261/261
+f 703/262/262 1062/261/261 1125/263/263
+f 704/264/264 1125/263/263 1178/265/265
+f 705/266/266 1178/265/265 1234/267/267
+f 707/268/268 1234/267/267 1271/269/269
+f 712/270/270 1271/269/269 1297/271/271
+f 719/272/272 1297/271/271 1301/273/273
+f 725/274/274 1301/273/273 1308/275/275
+f 727/276/276 1308/275/275 1306/277/277
+f 829/280/280 922/292/292 1011/281/281
+f 870/257/257 1011/281/281 1263/282/282
+f 1033/259/259 1263/282/282 1270/283/283
+f 1062/261/261 1270/283/283 1291/284/284
+f 1125/263/263 1291/284/284 1295/285/285
+f 1178/265/265 1295/285/285 1303/286/286
+f 1234/267/267 1303/286/286 1313/287/287
+f 1271/269/269 1313/287/287 1320/288/288
+f 1297/271/271 1320/288/288 1329/289/289
+f 1301/273/273 1329/289/289 1333/290/290
+f 1308/275/275 1333/290/290 1332/291/291
+f 922/292/292 1158/293/293 1005/304/304
+f 1011/281/281 1294/294/294 1158/293/293
+f 1263/282/282 1298/295/295 1294/294/294
+f 1270/283/283 1302/296/296 1298/295/295
+f 1291/284/284 1309/297/297 1302/296/296
+f 1295/285/285 1312/298/298 1309/297/297
+f 1303/286/286 1321/299/299 1312/298/298
+f 1313/287/287 1335/300/300 1321/299/299
+f 1320/288/288 1340/301/301 1335/300/300
+f 1329/289/289 1343/302/302 1340/301/301
+f 1333/290/290 1343/302/302 1341/303/303
+f 1005/304/304 1180/305/305 1038/318/318
+f 1158/293/293 1296/306/306 1180/305/305
+f 1294/294/294 1300/307/307 1296/306/306
+f 1298/295/295 1307/308/308 1300/307/307
+f 1302/296/296 1310/309/309 1307/308/308
+f 1309/297/297 1315/310/310 1310/309/309
+f 1312/298/298 1322/311/311 1315/310/310
+f 1321/299/299 1337/312/312 1322/311/311
+f 1335/300/300 1342/313/313 1337/312/312
+f 1340/301/301 1353/314/314 1342/313/313
+f 1343/302/302 1352/315/315 1353/314/314
+f 1337/312/312 17/325/325 12/326/326
+f 342/317/317 353/340/340 204/329/329
+f 184/316/316 204/329/329 60/330/330
+f 57/319/319 60/330/330 55/331/331
+f 54/320/320 55/331/331 52/332/332
+f 46/321/321 52/332/332 45/333/333
+f 44/322/322 45/333/333 40/334/334
+f 39/323/323 40/334/334 33/335/335
+f 32/324/324 33/335/335 19/336/336
+f 17/325/325 19/336/336 14/337/337
+f 12/326/326 14/337/337 11/338/338
+f 1/327/327 11/338/338 13/339/339
+f 353/340/340 431/352/352 349/341/341
+f 204/329/329 349/341/341 93/342/342
+f 60/330/330 93/342/342 85/343/343
+f 55/331/331 85/343/343 71/344/344
+f 52/332/332 71/344/344 59/345/345
+f 45/333/333 59/345/345 51/346/346
+f 40/334/334 51/346/346 41/347/347
+f 33/335/335 41/347/347 34/348/348
+f 19/336/336 34/348/348 27/349/349
+f 14/337/337 27/349/349 21/350/350
+f 11/338/338 21/350/350 22/351/351
+f 431/352/352 531/364/364 492/353/353
+f 349/341/341 492/353/353 352/354/354
+f 93/342/342 352/354/354 313/355/355
+f 85/343/343 313/355/355 268/356/356
+f 71/344/344 268/356/356 202/357/357
+f 59/345/345 202/357/357 133/358/358
+f 51/346/346 133/358/358 87/359/359
+f 41/347/347 87/359/359 58/360/360
+f 34/348/348 58/360/360 53/361/361
+f 27/349/349 53/361/361 47/362/362
+f 21/350/350 47/362/362 48/363/363
+f 531/364/364 698/256/256 699/258/258
+f 492/353/353 699/258/258 702/260/260
+f 352/354/354 702/260/260 703/262/262
+f 313/355/355 703/262/262 704/264/264
+f 268/356/356 704/264/264 705/266/266
+f 202/357/357 705/266/266 707/268/268
+f 133/358/358 707/268/268 712/270/270
+f 87/359/359 712/270/270 719/272/272
+f 58/360/360 719/272/272 725/274/274
+f 53/361/361 725/274/274 727/276/276
+f 47/362/362 727/276/276 726/278/278
+f 1038/318/318 1180/305/305 1101/365/365
+f 1180/305/305 1296/306/306 1284/366/366
+f 1296/306/306 1300/307/307 1293/367/367
+f 1300/307/307 1307/308/308 1299/368/368
+f 1307/308/308 1310/309/309 1304/369/369
+f 1310/309/309 1315/310/310 1311/370/370
+f 1315/310/310 1322/311/311 1318/371/371
+f 1322/311/311 1337/312/312 1334/372/372
+f 1337/312/312 1342/313/313 1336/373/373
+f 1342/313/313 1353/314/314 1339/374/374
+f 1353/314/314 1352/315/315 1338/375/375
+f 1352/315/315 1338/375/375 662/279/279
+f 984/376/376 935/377/377 1101/365/365
+f 1101/365/365 1219/378/378 1284/366/366
+f 1284/366/366 1240/379/379 1293/367/367
+f 1293/367/367 1255/380/380 1299/368/368
+f 1299/368/368 1267/381/381 1304/369/369
+f 1304/369/369 1292/382/382 1311/370/370
+f 1311/370/370 1305/383/383 1318/371/371
+f 1318/371/371 1314/384/384 1334/372/372
+f 1334/372/372 1316/385/385 1336/373/373
+f 1336/373/373 1319/386/386 1339/374/374
+f 1339/374/374 1317/387/387 1338/375/375
+f 1338/375/375 1317/387/387 662/279/279
+f 887/388/388 799/389/389 935/377/377
+f 935/377/377 865/390/390 1219/378/378
+f 1219/378/378 874/391/391 1240/379/379
+f 1240/379/379 896/392/392 1255/380/380
+f 1255/380/380 908/393/393 1267/381/381
+f 1267/381/381 942/394/394 1292/382/382
+f 1292/382/382 1045/395/395 1305/383/383
+f 1305/383/383 1174/396/396 1314/384/384
+f 1314/384/384 1218/397/397 1316/385/385
+f 1316/385/385 1231/398/398 1319/386/386
+f 1319/386/386 1228/399/399 1317/387/387
+f 1317/387/387 1228/399/399 662/279/279
+f 778/400/400 564/401/401 799/389/389
+f 799/389/389 510/402/402 865/390/390
+f 874/391/391 510/402/402 493/403/403
+f 865/390/390 510/402/402 874/391/391
+f 896/392/392 493/403/403 483/404/404
+f 874/391/391 493/403/403 896/392/392
+f 908/393/393 483/404/404 465/405/405
+f 896/392/392 483/404/404 908/393/393
+f 942/394/394 465/405/405 441/406/406
+f 908/393/393 465/405/405 942/394/394
+f 1045/395/395 441/406/406 362/407/407
+f 942/394/394 441/406/406 1045/395/395
+f 1045/395/395 251/408/408 1174/396/396
+f 1174/396/396 193/409/409 1218/397/397
+f 1218/397/397 164/410/410 1231/398/398
+f 1228/399/399 164/410/410 171/411/411
+f 1231/398/398 164/410/410 1228/399/399
+f 1228/399/399 171/411/411 662/279/279
+f 585/412/412 429/413/413 564/401/401
+f 564/401/401 150/414/414 510/402/402
+f 510/402/402 125/415/415 493/403/403
+f 493/403/403 100/416/416 483/404/404
+f 483/404/404 92/417/417 465/405/405
+f 465/405/405 70/418/418 441/406/406
+f 441/406/406 49/419/419 362/407/407
+f 362/407/407 42/420/420 251/408/408
+f 251/408/408 38/421/421 193/409/409
+f 193/409/409 36/422/422 164/410/410
+f 164/410/410 37/423/423 171/411/411
+f 171/411/411 37/423/423 662/279/279
+f 477/424/424 264/425/425 429/413/413
+f 429/413/413 74/426/426 150/414/414
+f 150/414/414 61/427/427 125/415/415
+f 125/415/415 56/428/428 100/416/416
+f 100/416/416 50/429/429 92/417/417
+f 92/417/417 43/430/430 70/418/418
+f 70/418/418 35/431/431 49/419/419
+f 49/419/419 20/432/432 42/420/420
+f 42/420/420 18/433/433 38/421/421
+f 38/421/421 15/434/434 36/422/422
+f 36/422/422 16/435/435 37/423/423
+f 37/423/423 16/435/435 662/279/279
+f 381/436/436 184/316/316 264/425/425
+f 264/425/425 57/319/319 74/426/426
+f 74/426/426 54/320/320 61/427/427
+f 61/427/427 46/321/321 56/428/428
+f 56/428/428 44/322/322 50/429/429
+f 50/429/429 39/323/323 43/430/430
+f 43/430/430 32/324/324 35/431/431
+f 35/431/431 17/325/325 20/432/432
+f 20/432/432 12/326/326 18/433/433
+f 1/327/327 15/434/434 18/433/433
+f 15/434/434 2/328/328 16/435/435
+f 16/435/435 2/328/328 662/279/279
+f 1038/318/318 984/376/376 1101/365/365
+f 1180/305/305 1101/365/365 1284/366/366
+f 1296/306/306 1284/366/366 1293/367/367
+f 1300/307/307 1293/367/367 1299/368/368
+f 1307/308/308 1299/368/368 1304/369/369
+f 1310/309/309 1304/369/369 1311/370/370
+f 1315/310/310 1311/370/370 1318/371/371
+f 1322/311/311 1318/371/371 1334/372/372
+f 1337/312/312 1334/372/372 1336/373/373
+f 1342/313/313 1336/373/373 1339/374/374
+f 1353/314/314 1339/374/374 1338/375/375
+f 984/376/376 887/388/388 935/377/377
+f 1101/365/365 935/377/377 1219/378/378
+f 1284/366/366 1219/378/378 1240/379/379
+f 1293/367/367 1240/379/379 1255/380/380
+f 1299/368/368 1255/380/380 1267/381/381
+f 1304/369/369 1267/381/381 1292/382/382
+f 1311/370/370 1292/382/382 1305/383/383
+f 1318/371/371 1305/383/383 1314/384/384
+f 1334/372/372 1314/384/384 1316/385/385
+f 1336/373/373 1316/385/385 1319/386/386
+f 1339/374/374 1319/386/386 1317/387/387
+f 887/388/388 778/400/400 799/389/389
+f 935/377/377 799/389/389 865/390/390
+f 1219/378/378 865/390/390 874/391/391
+f 1240/379/379 874/391/391 896/392/392
+f 1255/380/380 896/392/392 908/393/393
+f 1267/381/381 908/393/393 942/394/394
+f 1292/382/382 942/394/394 1045/395/395
+f 1305/383/383 1045/395/395 1174/396/396
+f 1314/384/384 1174/396/396 1218/397/397
+f 1316/385/385 1218/397/397 1231/398/398
+f 1319/386/386 1231/398/398 1228/399/399
+f 778/400/400 585/412/412 564/401/401
+f 799/389/389 564/401/401 510/402/402
+f 1045/395/395 362/407/407 251/408/408
+f 1174/396/396 251/408/408 193/409/409
+f 1218/397/397 193/409/409 164/410/410
+f 585/412/412 477/424/424 429/413/413
+f 564/401/401 429/413/413 150/414/414
+f 510/402/402 150/414/414 125/415/415
+f 493/403/403 125/415/415 100/416/416
+f 483/404/404 100/416/416 92/417/417
+f 465/405/405 92/417/417 70/418/418
+f 441/406/406 70/418/418 49/419/419
+f 362/407/407 49/419/419 42/420/420
+f 251/408/408 42/420/420 38/421/421
+f 193/409/409 38/421/421 36/422/422
+f 164/410/410 36/422/422 37/423/423
+f 477/424/424 381/436/436 264/425/425
+f 429/413/413 264/425/425 74/426/426
+f 150/414/414 74/426/426 61/427/427
+f 125/415/415 61/427/427 56/428/428
+f 100/416/416 56/428/428 50/429/429
+f 92/417/417 50/429/429 43/430/430
+f 70/418/418 43/430/430 35/431/431
+f 49/419/419 35/431/431 20/432/432
+f 42/420/420 20/432/432 18/433/433
+f 38/421/421 18/433/433 15/434/434
+f 36/422/422 15/434/434 16/435/435
+f 381/436/436 342/317/317 184/316/316
+f 264/425/425 184/316/316 57/319/319
+f 74/426/426 57/319/319 54/320/320
+f 61/427/427 54/320/320 46/321/321
+f 56/428/428 46/321/321 44/322/322
+f 50/429/429 44/322/322 39/323/323
+f 43/430/430 39/323/323 32/324/324
+f 35/431/431 32/324/324 17/325/325
+f 20/432/432 17/325/325 12/326/326
+f 18/433/433 12/326/326 1/327/327
+f 1/327/327 2/328/328 15/434/434
+f 648/437/437 759/52/52 756/122/122
+f 650/438/438 648/437/437 756/122/122
+f 756/122/122 759/52/52 867/50/50
+f 854/439/439 867/50/50 978/48/48
+f 938/113/113 978/48/48 1108/46/46
+f 1057/440/440 1108/46/46 1207/42/42
+f 1161/102/102 1207/42/42 1237/41/41
+f 1205/103/103 1237/41/41 1236/2/2
+f 756/122/122 867/50/50 854/439/439
+f 854/439/439 978/48/48 938/113/113
+f 938/113/113 1108/46/46 1057/440/440
+f 1057/440/440 1207/42/42 1161/102/102
+f 1161/102/102 1237/41/41 1205/103/103
+f 1205/103/103 1236/2/2 1204/1/1
+f 692/441/441 597/131/131 592/54/54
+f 691/442/442 597/131/131 692/441/441
+f 597/131/131 486/56/56 592/54/54
+f 502/443/443 377/57/57 486/56/56
+f 415/140/140 246/58/58 377/57/57
+f 297/444/444 143/59/59 246/58/58
+f 191/149/149 118/60/60 143/59/59
+f 147/158/158 117/15/15 118/60/60
+f 597/131/131 502/443/443 486/56/56
+f 502/443/443 415/140/140 377/57/57
+f 415/140/140 297/444/444 246/58/58
+f 297/444/444 191/149/149 143/59/59
+f 191/149/149 147/158/158 118/60/60
+f 147/158/158 148/16/16 117/15/15
+f 148/16/16 142/62/62 117/15/15
+f 192/175/175 245/64/64 142/62/62
+f 298/445/445 376/66/66 245/64/64
+f 416/184/184 485/68/68 376/66/66
+f 501/193/193 591/70/70 485/68/68
+f 595/202/202 647/72/72 591/70/70
+f 148/16/16 192/175/175 142/62/62
+f 192/175/175 298/445/445 245/64/64
+f 298/445/445 416/184/184 376/66/66
+f 416/184/184 501/193/193 485/68/68
+f 501/193/193 595/202/202 591/70/70
+f 595/202/202 651/211/211 647/72/72
+f 651/211/211 758/74/74 647/72/72
+f 755/220/220 866/76/76 758/74/74
+f 853/229/229 977/78/78 866/76/76
+f 939/238/238 1107/80/80 977/78/78
+f 1056/446/446 1206/82/82 1107/80/80
+f 1162/247/247 1236/2/2 1206/82/82
+f 651/211/211 755/220/220 758/74/74
+f 755/220/220 853/229/229 866/76/76
+f 853/229/229 939/238/238 977/78/78
+f 939/238/238 1056/446/446 1107/80/80
+f 1056/446/446 1162/247/247 1206/82/82
+f 1162/247/247 1204/1/1 1236/2/2
+f 97/447/447 78/448/448 77/449/448
+f 98/450/449 78/448/448 97/447/447
+f 77/449/448 80/451/450 79/452/450
+f 78/448/448 80/451/450 77/449/448
+f 79/452/450 31/453/451 30/454/451
+f 80/451/450 31/453/451 79/452/450
+f 30/454/451 29/455/452 28/456/452
+f 31/453/451 29/455/452 30/454/451
+f 28/456/452 98/450/449 97/447/447
+f 29/455/452 98/450/449 28/456/452
+f 25/457/453 24/458/454 23/459/454
+f 26/460/453 24/458/454 25/457/453
+f 23/459/454 10/461/455 9/462/455
+f 24/458/454 10/461/455 23/459/454
+f 9/462/455 4/463/456 3/464/457
+f 10/461/455 4/463/456 9/462/455
+f 3/464/457 8/465/458 7/466/459
+f 4/463/456 8/465/458 3/464/457
+f 7/466/459 6/467/460 5/468/460
+f 8/465/458 6/467/460 7/466/459
+f 5/468/460 26/460/453 25/457/453
+f 6/467/460 26/460/453 5/468/460
+f 1328/469/461 1330/470/462 1331/471/462
+f 1327/472/461 1330/470/462 1328/469/461
+f 1331/471/462 1344/473/463 1345/474/463
+f 1330/470/462 1344/473/463 1331/471/462
+f 1345/474/463 1350/475/464 1351/476/464
+f 1344/473/463 1350/475/464 1345/474/463
+f 1351/476/464 1346/477/465 1347/478/465
+f 1350/475/464 1346/477/465 1351/476/464
+f 1347/478/465 1348/479/466 1349/480/466
+f 1346/477/465 1348/479/466 1347/478/465
+f 1349/480/466 1327/472/461 1328/469/461
+f 1348/479/466 1327/472/461 1349/480/466
+f 1257/481/467 1274/482/468 1275/483/468
+f 1256/484/467 1274/482/468 1257/481/467
+f 1275/483/468 1276/485/469 1277/486/469
+f 1274/482/468 1276/485/469 1275/483/468
+f 1277/486/469 1323/487/470 1324/488/470
+f 1276/485/469 1323/487/470 1277/486/469
+f 1324/488/470 1325/489/471 1326/490/471
+f 1323/487/470 1325/489/471 1324/488/470
+f 1326/490/471 1256/484/467 1257/481/467
+f 1325/489/471 1256/484/467 1326/490/471
+f 91/491/472 99/492/473 141/493/474
+f 99/492/473 108/494/475 157/495/476
+f 108/494/475 149/496/477 203/497/478
+f 149/496/477 258/498/479 292/499/480
+f 258/498/479 329/500/481 335/501/482
+f 124/502/483 141/493/474 198/503/484
+f 141/493/474 157/495/476 209/504/485
+f 157/495/476 203/497/478 261/505/486
+f 203/497/478 292/499/480 299/506/487
+f 335/501/482 338/507/488 299/506/487
+f 292/499/480 335/501/482 299/506/487
+f 182/508/489 198/503/484 412/509/490
+f 198/503/484 209/504/485 407/510/491
+f 209/504/485 261/505/486 388/511/492
+f 261/505/486 299/506/487 350/512/493
+f 299/506/487 338/507/488 337/513/494
+f 437/514/495 412/509/490 565/515/496
+f 412/509/490 407/510/491 540/516/497
+f 407/510/491 388/511/492 489/517/498
+f 350/512/493 405/518/499 489/517/498
+f 388/511/492 350/512/493 489/517/498
+f 350/512/493 337/513/494 328/519/500
+f 565/515/496 109/520/501 104/521/502
+f 643/522/503 565/515/496 104/521/502
+f 540/516/497 116/523/504 109/520/501
+f 565/515/496 540/516/497 109/520/501
+f 489/517/498 155/524/505 116/523/504
+f 540/516/497 489/517/498 116/523/504
+f 405/518/499 265/525/506 155/524/505
+f 489/517/498 405/518/499 155/524/505
+f 328/519/500 325/526/507 265/525/506
+f 405/518/499 328/519/500 265/525/506
+f 104/521/502 109/520/501 84/527/508
+f 109/520/501 116/523/504 89/528/509
+f 116/523/504 155/524/505 110/529/510
+f 155/524/505 265/525/506 227/530/511
+f 325/526/507 333/531/512 227/530/511
+f 265/525/506 325/526/507 227/530/511
+f 75/532/513 84/527/508 82/533/514
+f 84/527/508 89/528/509 86/534/515
+f 89/528/509 110/529/510 106/535/516
+f 110/529/510 227/530/511 216/536/517
+f 227/530/511 333/531/512 336/537/518
+f 66/538/519 82/533/514 83/539/520
+f 82/533/514 86/534/515 90/540/521
+f 86/534/515 106/535/516 111/541/522
+f 106/535/516 216/536/517 225/542/523
+f 216/536/517 336/537/518 334/543/524
+f 72/544/525 83/539/520 88/545/526
+f 83/539/520 90/540/521 96/546/527
+f 90/540/521 111/541/522 123/547/528
+f 111/541/522 225/542/523 240/548/529
+f 225/542/523 334/543/524 332/549/530
+f 81/550/531 88/545/526 99/492/473
+f 88/545/526 96/546/527 108/494/475
+f 96/546/527 123/547/528 149/496/477
+f 123/547/528 240/548/529 258/498/479
+f 240/548/529 332/549/530 329/500/481
+f 91/491/472 141/493/474 124/502/483
+f 99/492/473 157/495/476 141/493/474
+f 108/494/475 203/497/478 157/495/476
+f 149/496/477 292/499/480 203/497/478
+f 258/498/479 335/501/482 292/499/480
+f 124/502/483 198/503/484 182/508/489
+f 141/493/474 209/504/485 198/503/484
+f 157/495/476 261/505/486 209/504/485
+f 203/497/478 299/506/487 261/505/486
+f 182/508/489 412/509/490 437/514/495
+f 198/503/484 407/510/491 412/509/490
+f 209/504/485 388/511/492 407/510/491
+f 261/505/486 350/512/493 388/511/492
+f 299/506/487 337/513/494 350/512/493
+f 437/514/495 565/515/496 643/522/503
+f 412/509/490 540/516/497 565/515/496
+f 407/510/491 489/517/498 540/516/497
+f 350/512/493 328/519/500 405/518/499
+f 104/521/502 84/527/508 75/532/513
+f 109/520/501 89/528/509 84/527/508
+f 116/523/504 110/529/510 89/528/509
+f 155/524/505 227/530/511 110/529/510
+f 75/532/513 82/533/514 66/538/519
+f 84/527/508 86/534/515 82/533/514
+f 89/528/509 106/535/516 86/534/515
+f 110/529/510 216/536/517 106/535/516
+f 227/530/511 336/537/518 216/536/517
+f 66/538/519 83/539/520 72/544/525
+f 82/533/514 90/540/521 83/539/520
+f 86/534/515 111/541/522 90/540/521
+f 106/535/516 225/542/523 111/541/522
+f 216/536/517 334/543/524 225/542/523
+f 72/544/525 88/545/526 81/550/531
+f 83/539/520 96/546/527 88/545/526
+f 90/540/521 123/547/528 96/546/527
+f 111/541/522 240/548/529 123/547/528
+f 225/542/523 332/549/530 240/548/529
+f 81/550/531 99/492/473 91/491/472
+f 88/545/526 108/494/475 99/492/473
+f 96/546/527 149/496/477 108/494/475
+f 123/547/528 258/498/479 149/496/477
+f 240/548/529 329/500/481 258/498/479
+f 1261/551/532 1209/552/533 1254/553/534
+f 1254/553/534 1196/554/535 1246/555/536
+f 1246/555/536 1149/556/537 1201/557/538
+f 1201/557/538 1063/558/539 1094/559/540
+f 1094/559/540 1017/560/541 1023/561/542
+f 1226/562/543 1153/563/544 1209/552/533
+f 1209/552/533 1146/564/545 1196/554/535
+f 1196/554/535 1091/565/546 1149/556/537
+f 1149/556/537 1055/566/547 1063/558/539
+f 1017/560/541 1055/566/547 1014/567/548
+f 1063/558/539 1055/566/547 1017/560/541
+f 1169/568/549 941/569/550 1153/563/544
+f 1153/563/544 947/570/551 1146/564/545
+f 1146/564/545 968/571/552 1091/565/546
+f 1091/565/546 1002/572/553 1055/566/547
+f 1055/566/547 1015/573/554 1014/567/548
+f 915/574/555 791/575/556 941/569/550
+f 941/569/550 816/576/557 947/570/551
+f 947/570/551 863/577/558 968/571/552
+f 1002/572/553 863/577/558 949/578/559
+f 968/571/552 863/577/558 1002/572/553
+f 1002/572/553 1024/579/560 1015/573/554
+f 791/575/556 1249/580/561 1245/581/562
+f 706/582/563 1249/580/561 791/575/556
+f 816/576/557 1245/581/562 1239/583/564
+f 791/575/556 1245/581/562 816/576/557
+f 863/577/558 1239/583/564 1197/584/565
+f 816/576/557 1239/583/564 863/577/558
+f 949/578/559 1197/584/565 1088/585/566
+f 863/577/558 1197/584/565 949/578/559
+f 1024/579/560 1088/585/566 1027/586/567
+f 949/578/559 1088/585/566 1024/579/560
+f 1249/580/561 1268/587/568 1245/581/562
+f 1245/581/562 1264/588/569 1239/583/564
+f 1239/583/564 1244/589/570 1197/584/565
+f 1197/584/565 1124/590/571 1088/585/566
+f 1027/586/567 1124/590/571 1019/591/572
+f 1088/585/566 1124/590/571 1027/586/567
+f 1278/592/573 1272/593/574 1268/587/568
+f 1268/587/568 1266/594/575 1264/588/569
+f 1264/588/569 1248/595/576 1244/589/570
+f 1244/589/570 1137/596/577 1124/590/571
+f 1124/590/571 1016/597/578 1019/591/572
+f 1285/598/579 1269/599/580 1272/593/574
+f 1272/593/574 1262/600/581 1266/594/575
+f 1266/594/575 1243/601/582 1248/595/576
+f 1248/595/576 1126/602/583 1137/596/577
+f 1137/596/577 1018/603/584 1016/597/578
+f 1280/604/585 1265/605/586 1269/599/580
+f 1269/599/580 1258/606/587 1262/600/581
+f 1262/600/581 1227/607/588 1243/601/582
+f 1243/601/582 1114/608/589 1126/602/583
+f 1126/602/583 1020/609/590 1018/603/584
+f 1273/610/591 1254/553/534 1265/605/586
+f 1265/605/586 1246/555/536 1258/606/587
+f 1258/606/587 1201/557/538 1227/607/588
+f 1227/607/588 1094/559/540 1114/608/589
+f 1114/608/589 1023/561/542 1020/609/590
+f 1261/551/532 1226/562/543 1209/552/533
+f 1254/553/534 1209/552/533 1196/554/535
+f 1246/555/536 1196/554/535 1149/556/537
+f 1201/557/538 1149/556/537 1063/558/539
+f 1094/559/540 1063/558/539 1017/560/541
+f 1226/562/543 1169/568/549 1153/563/544
+f 1209/552/533 1153/563/544 1146/564/545
+f 1196/554/535 1146/564/545 1091/565/546
+f 1149/556/537 1091/565/546 1055/566/547
+f 1169/568/549 915/574/555 941/569/550
+f 1153/563/544 941/569/550 947/570/551
+f 1146/564/545 947/570/551 968/571/552
+f 1091/565/546 968/571/552 1002/572/553
+f 1055/566/547 1002/572/553 1015/573/554
+f 915/574/555 706/582/563 791/575/556
+f 941/569/550 791/575/556 816/576/557
+f 947/570/551 816/576/557 863/577/558
+f 1002/572/553 949/578/559 1024/579/560
+f 1249/580/561 1278/592/573 1268/587/568
+f 1245/581/562 1268/587/568 1264/588/569
+f 1239/583/564 1264/588/569 1244/589/570
+f 1197/584/565 1244/589/570 1124/590/571
+f 1278/592/573 1285/598/579 1272/593/574
+f 1268/587/568 1272/593/574 1266/594/575
+f 1264/588/569 1266/594/575 1248/595/576
+f 1244/589/570 1248/595/576 1137/596/577
+f 1124/590/571 1137/596/577 1016/597/578
+f 1285/598/579 1280/604/585 1269/599/580
+f 1272/593/574 1269/599/580 1262/600/581
+f 1266/594/575 1262/600/581 1243/601/582
+f 1248/595/576 1243/601/582 1126/602/583
+f 1137/596/577 1126/602/583 1018/603/584
+f 1280/604/585 1273/610/591 1265/605/586
+f 1269/599/580 1265/605/586 1258/606/587
+f 1262/600/581 1258/606/587 1227/607/588
+f 1243/601/582 1227/607/588 1114/608/589
+f 1126/602/583 1114/608/589 1020/609/590
+f 1273/610/591 1261/551/532 1254/553/534
+f 1265/605/586 1254/553/534 1246/555/536
+f 1258/606/587 1246/555/536 1201/557/538
+f 1227/607/588 1201/557/538 1094/559/540
+f 1114/608/589 1094/559/540 1023/561/542
+f 615/611/592 576/612/593 618/613/594
+f 774/614/595 618/613/594 775/615/594
+f 615/611/592 618/613/594 774/614/595
+f 774/614/595 775/615/594 800/616/596
+f 618/613/594 576/612/593 623/617/597
+f 775/615/594 623/617/597 757/618/598
+f 618/613/594 623/617/597 775/615/594
+f 775/615/594 757/618/598 800/616/596
+f 623/617/597 576/612/593 625/619/599
+f 757/618/598 625/619/599 722/620/600
+f 623/617/597 625/619/599 757/618/598
+f 757/618/598 722/620/600 800/616/596
+f 625/619/599 576/612/593 627/621/601
+f 722/620/600 627/621/601 717/622/602
+f 625/619/599 627/621/601 722/620/600
+f 722/620/600 717/622/602 800/616/596
+f 627/621/601 576/612/593 626/623/603
+f 717/622/602 626/623/603 715/624/604
+f 627/621/601 626/623/603 717/622/602
+f 717/622/602 715/624/604 800/616/596
+f 626/623/603 576/612/593 624/625/605
+f 715/624/604 624/625/605 713/626/606
+f 626/623/603 624/625/605 715/624/604
+f 715/624/604 713/626/606 800/616/596
+f 624/625/605 576/612/593 622/627/607
+f 713/626/606 622/627/607 714/628/608
+f 624/625/605 622/627/607 713/626/606
+f 713/626/606 714/628/608 800/616/596
+f 622/627/607 576/612/593 621/629/609
+f 714/628/608 621/629/609 716/630/610
+f 622/627/607 621/629/609 714/628/608
+f 714/628/608 716/630/610 800/616/596
+f 621/629/609 576/612/593 620/631/611
+f 716/630/610 620/631/611 718/632/612
+f 621/629/609 620/631/611 716/630/610
+f 716/630/610 718/632/612 800/616/596
+f 620/631/611 576/612/593 619/633/613
+f 718/632/612 619/633/613 721/634/614
+f 620/631/611 619/633/613 718/632/612
+f 718/632/612 721/634/614 800/616/596
+f 619/633/613 576/612/593 617/635/615
+f 721/634/614 617/635/615 764/636/616
+f 619/633/613 617/635/615 721/634/614
+f 721/634/614 764/636/616 800/616/596
+f 617/635/615 576/612/593 616/637/617
+f 764/636/616 616/637/617 767/638/618
+f 617/635/615 616/637/617 764/636/616
+f 764/636/616 767/638/618 800/616/596
+f 616/637/617 576/612/593 615/611/592
+f 767/638/618 615/611/592 774/614/595
+f 616/637/617 615/611/592 767/638/618
+f 767/638/618 774/614/595 800/616/596
+f 951/639/619 963/640/620 934/641/621
+f 973/642/622 934/641/621 893/643/623
+f 951/639/619 934/641/621 973/642/622
+f 983/644/624 893/643/623 872/645/625
+f 973/642/622 893/643/623 983/644/624
+f 986/646/626 872/645/625 876/647/627
+f 983/644/624 872/645/625 986/646/626
+f 988/648/628 876/647/627 898/649/628
+f 986/646/626 876/647/627 988/648/628
+f 934/641/621 963/640/620 920/650/629
+f 893/643/623 920/650/629 833/651/630
+f 934/641/621 920/650/629 893/643/623
+f 872/645/625 833/651/630 804/652/631
+f 893/643/623 833/651/630 872/645/625
+f 876/647/627 804/652/631 808/653/632
+f 872/645/625 804/652/631 876/647/627
+f 898/649/628 808/653/632 831/654/628
+f 876/647/627 808/653/632 898/649/628
+f 920/650/629 963/640/620 912/655/633
+f 833/651/630 912/655/633 819/656/634
+f 920/650/629 912/655/633 833/651/630
+f 804/652/631 819/656/634 783/657/635
+f 833/651/630 819/656/634 804/652/631
+f 808/653/632 783/657/635 788/658/636
+f 804/652/631 783/657/635 808/653/632
+f 831/654/628 788/658/636 811/659/628
+f 808/653/632 788/658/636 831/654/628
+f 912/655/633 963/640/620 919/660/637
+f 819/656/634 919/660/637 832/661/638
+f 912/655/633 919/660/637 819/656/634
+f 783/657/635 832/661/638 803/662/639
+f 819/656/634 832/661/638 783/657/635
+f 788/658/636 803/662/639 807/663/640
+f 783/657/635 803/662/639 788/658/636
+f 811/659/628 807/663/640 830/664/628
+f 788/658/636 807/663/640 811/659/628
+f 919/660/637 963/640/620 933/665/641
+f 832/661/638 933/665/641 892/666/642
+f 919/660/637 933/665/641 832/661/638
+f 803/662/639 892/666/642 871/667/643
+f 832/661/638 892/666/642 803/662/639
+f 807/663/640 871/667/643 875/668/644
+f 803/662/639 871/667/643 807/663/640
+f 830/664/628 875/668/644 897/669/628
+f 807/663/640 875/668/644 830/664/628
+f 933/665/641 963/640/620 950/670/645
+f 892/666/642 950/670/645 972/671/646
+f 933/665/641 950/670/645 892/666/642
+f 871/667/643 972/671/646 982/672/647
+f 892/666/642 972/671/646 871/667/643
+f 875/668/644 982/672/647 985/673/648
+f 871/667/643 982/672/647 875/668/644
+f 897/669/628 985/673/648 987/674/628
+f 875/668/644 985/673/648 897/669/628
+f 950/670/645 963/640/620 995/675/649
+f 972/671/646 995/675/649 1082/676/650
+f 950/670/645 995/675/649 972/671/646
+f 982/672/647 1082/676/650 1138/677/651
+f 972/671/646 1082/676/650 982/672/647
+f 985/673/648 1138/677/651 1140/678/652
+f 982/672/647 1138/677/651 985/673/648
+f 987/674/628 1140/678/652 1102/679/628
+f 985/673/648 1140/678/652 987/674/628
+f 995/675/649 963/640/620 1006/680/653
+f 1082/676/650 1006/680/653 1165/681/654
+f 995/675/649 1006/680/653 1082/676/650
+f 1138/677/651 1165/681/654 1222/682/655
+f 1082/676/650 1165/681/654 1138/677/651
+f 1140/678/652 1222/682/655 1220/683/656
+f 1138/677/651 1222/682/655 1140/678/652
+f 1102/679/628 1220/683/656 1192/684/657
+f 1140/678/652 1220/683/656 1102/679/628
+f 1006/680/653 963/640/620 1010/685/658
+f 1165/681/654 1010/685/658 1191/686/659
+f 1006/680/653 1010/685/658 1165/681/654
+f 1222/682/655 1191/686/659 1235/687/660
+f 1165/681/654 1191/686/659 1222/682/655
+f 1220/683/656 1235/687/660 1233/688/661
+f 1222/682/655 1235/687/660 1220/683/656
+f 1192/684/657 1233/688/661 1213/689/628
+f 1220/683/656 1233/688/661 1192/684/657
+f 1010/685/658 963/640/620 1007/690/662
+f 1191/686/659 1007/690/662 1166/691/663
+f 1010/685/658 1007/690/662 1191/686/659
+f 1235/687/660 1166/691/663 1223/692/664
+f 1191/686/659 1166/691/663 1235/687/660
+f 1233/688/661 1223/692/664 1221/693/665
+f 1235/687/660 1223/692/664 1233/688/661
+f 1213/689/628 1221/693/665 1193/694/628
+f 1233/688/661 1221/693/665 1213/689/628
+f 1007/690/662 963/640/620 996/695/666
+f 1166/691/663 996/695/666 1083/696/667
+f 1007/690/662 996/695/666 1166/691/663
+f 1223/692/664 1083/696/667 1139/697/668
+f 1166/691/663 1083/696/667 1223/692/664
+f 1221/693/665 1139/697/668 1141/698/669
+f 1223/692/664 1139/697/668 1221/693/665
+f 1193/694/628 1141/698/669 1103/699/628
+f 1221/693/665 1141/698/669 1193/694/628
+f 996/695/666 963/640/620 951/639/619
+f 1083/696/667 951/639/619 973/642/622
+f 996/695/666 951/639/619 1083/696/667
+f 1139/697/668 973/642/622 983/644/624
+f 1083/696/667 973/642/622 1139/697/668
+f 1141/698/669 983/644/624 986/646/626
+f 1139/697/668 983/644/624 1141/698/669
+f 1103/699/628 986/646/626 988/648/628
+f 1141/698/669 986/646/626 1103/699/628
+f 387/700/670 400/701/671 359/702/672
+f 375/703/673 359/702/672 271/704/674
+f 387/700/670 359/702/672 375/703/673
+f 368/705/675 271/704/674 213/706/676
+f 375/703/673 271/704/674 368/705/675
+f 364/707/677 213/706/676 206/708/678
+f 368/705/675 213/706/676 364/707/677
+f 366/709/679 206/708/678 238/710/679
+f 364/707/677 206/708/678 366/709/679
+f 359/702/672 400/701/671 346/711/680
+f 271/704/674 346/711/680 181/712/681
+f 359/702/672 346/711/680 271/704/674
+f 213/706/676 181/712/681 129/713/682
+f 271/704/674 181/712/681 213/706/676
+f 206/708/678 129/713/682 131/714/683
+f 213/706/676 129/713/682 206/708/678
+f 238/710/679 131/714/683 152/715/679
+f 206/708/678 131/714/683 238/710/679
+f 346/711/680 400/701/671 339/716/684
+f 181/712/681 339/716/684 159/717/685
+f 346/711/680 339/716/684 181/712/681
+f 129/713/682 159/717/685 112/718/686
+f 181/712/681 159/717/685 129/713/682
+f 131/714/683 112/718/686 115/719/687
+f 129/713/682 112/718/686 131/714/683
+f 152/715/679 115/719/687 132/720/679
+f 131/714/683 115/719/687 152/715/679
+f 339/716/684 400/701/671 345/721/688
+f 159/717/685 345/721/688 180/722/689
+f 339/716/684 345/721/688 159/717/685
+f 112/718/686 180/722/689 128/723/690
+f 159/717/685 180/722/689 112/718/686
+f 115/719/687 128/723/690 130/724/691
+f 112/718/686 128/723/690 115/719/687
+f 132/720/679 130/724/691 151/725/692
+f 115/719/687 130/724/691 132/720/679
+f 345/721/688 400/701/671 358/726/693
+f 180/722/689 358/726/693 270/727/694
+f 345/721/688 358/726/693 180/722/689
+f 128/723/690 270/727/694 212/728/695
+f 180/722/689 270/727/694 128/723/690
+f 130/724/691 212/728/695 205/729/696
+f 128/723/690 212/728/695 130/724/691
+f 151/725/692 205/729/696 237/730/679
+f 130/724/691 205/729/696 151/725/692
+f 358/726/693 400/701/671 386/731/697
+f 270/727/694 386/731/697 374/732/698
+f 358/726/693 386/731/697 270/727/694
+f 212/728/695 374/732/698 367/733/699
+f 270/727/694 374/732/698 212/728/695
+f 205/729/696 367/733/699 363/734/700
+f 212/728/695 367/733/699 205/729/696
+f 237/730/679 363/734/700 365/735/679
+f 205/729/696 363/734/700 237/730/679
+f 386/731/697 400/701/671 417/736/701
+f 374/732/698 417/736/701 455/737/702
+f 386/731/697 417/736/701 374/732/698
+f 367/733/699 455/737/702 475/738/703
+f 374/732/698 455/737/702 367/733/699
+f 363/734/700 475/738/703 469/739/704
+f 367/733/699 475/738/703 363/734/700
+f 365/735/679 469/739/704 452/740/705
+f 363/734/700 469/739/704 365/735/679
+f 417/736/701 400/701/671 432/741/706
+f 455/737/702 432/741/706 511/742/707
+f 417/736/701 432/741/706 455/737/702
+f 475/738/703 511/742/707 547/743/708
+f 455/737/702 511/742/707 475/738/703
+f 469/739/704 547/743/708 545/744/709
+f 475/738/703 547/743/708 469/739/704
+f 452/740/705 545/744/709 518/745/679
+f 469/739/704 545/744/709 452/740/705
+f 432/741/706 400/701/671 440/746/710
+f 511/742/707 440/746/710 532/747/711
+f 432/741/706 440/746/710 511/742/707
+f 547/743/708 532/747/711 563/748/712
+f 511/742/707 532/747/711 547/743/708
+f 545/744/709 563/748/712 560/749/713
+f 547/743/708 563/748/712 545/744/709
+f 518/745/679 560/749/713 535/750/679
+f 545/744/709 560/749/713 518/745/679
+f 440/746/710 400/701/671 433/751/714
+f 532/747/711 433/751/714 512/752/715
+f 440/746/710 433/751/714 532/747/711
+f 563/748/712 512/752/715 548/753/716
+f 532/747/711 512/752/715 563/748/712
+f 560/749/713 548/753/716 546/754/717
+f 563/748/712 548/753/716 560/749/713
+f 535/750/679 546/754/717 519/755/679
+f 560/749/713 546/754/717 535/750/679
+f 433/751/714 400/701/671 418/756/718
+f 512/752/715 418/756/718 456/757/719
+f 433/751/714 418/756/718 512/752/715
+f 548/753/716 456/757/719 476/758/720
+f 512/752/715 456/757/719 548/753/716
+f 546/754/717 476/758/720 470/759/721
+f 548/753/716 476/758/720 546/754/717
+f 519/755/679 470/759/721 453/760/679
+f 546/754/717 470/759/721 519/755/679
+f 418/756/718 400/701/671 387/700/670
+f 456/757/719 387/700/670 375/703/673
+f 418/756/718 387/700/670 456/757/719
+f 476/758/720 375/703/673 368/705/675
+f 456/757/719 375/703/673 476/758/720
+f 470/759/721 368/705/675 364/707/677
+f 476/758/720 368/705/675 470/759/721
+f 453/760/679 364/707/677 366/709/679
+f 470/759/721 364/707/677 453/760/679
+f 742/761/722 676/762/723 737/763/724
+f 851/764/725 737/763/724 839/765/726
+f 742/761/722 737/763/724 851/764/725
+f 902/766/727 839/765/726 886/767/728
+f 851/764/725 839/765/726 902/766/727
+f 901/768/729 886/767/728 884/769/730
+f 902/766/727 886/767/728 901/768/729
+f 864/770/731 884/769/730 858/771/732
+f 901/768/729 884/769/730 864/770/731
+f 737/763/724 676/762/723 729/772/733
+f 839/765/726 729/772/733 810/773/734
+f 737/763/724 729/772/733 839/765/726
+f 886/767/728 810/773/734 844/774/735
+f 839/765/726 810/773/734 886/767/728
+f 884/769/730 844/774/735 842/775/736
+f 886/767/728 844/774/735 884/769/730
+f 858/771/732 842/775/736 818/776/731
+f 884/769/730 842/775/736 858/771/732
+f 729/772/733 676/762/723 711/777/737
+f 810/773/734 711/777/737 762/778/738
+f 729/772/733 711/777/737 810/773/734
+f 844/774/735 762/778/738 787/779/739
+f 810/773/734 762/778/738 844/774/735
+f 842/775/736 787/779/739 785/780/740
+f 844/774/735 787/779/739 842/775/736
+f 818/776/731 785/780/740 771/781/731
+f 842/775/736 785/780/740 818/776/731
+f 711/777/737 676/762/723 679/782/741
+f 762/778/738 679/782/741 683/783/742
+f 711/777/737 679/782/741 762/778/738
+f 787/779/739 683/783/742 687/784/743
+f 762/778/738 683/783/742 787/779/739
+f 785/780/740 687/784/743 689/785/744
+f 787/779/739 687/784/743 785/780/740
+f 771/781/731 689/785/744 688/786/731
+f 785/780/740 689/785/744 771/781/731
+f 679/782/741 676/762/723 640/787/745
+f 683/783/742 640/787/745 590/788/746
+f 679/782/741 640/787/745 683/783/742
+f 687/784/743 590/788/746 569/789/747
+f 683/783/742 590/788/746 687/784/743
+f 689/785/744 569/789/747 571/790/748
+f 687/784/743 569/789/747 689/785/744
+f 688/786/731 571/790/748 582/791/749
+f 689/785/744 571/790/748 688/786/731
+f 640/787/745 676/762/723 635/792/750
+f 590/788/746 635/792/750 550/793/751
+f 640/787/745 635/792/750 590/788/746
+f 569/789/747 550/793/751 514/794/752
+f 590/788/746 550/793/751 569/789/747
+f 571/790/748 514/794/752 516/795/753
+f 569/789/747 514/794/752 571/790/748
+f 582/791/749 516/795/753 539/796/731
+f 571/790/748 516/795/753 582/791/749
+f 635/792/750 676/762/723 614/797/754
+f 550/793/751 614/797/754 521/798/755
+f 635/792/750 614/797/754 550/793/751
+f 514/794/752 521/798/755 468/799/756
+f 550/793/751 521/798/755 514/794/752
+f 516/795/753 468/799/756 472/800/757
+f 514/794/752 468/799/756 516/795/753
+f 539/796/731 472/800/757 497/801/731
+f 516/795/753 472/800/757 539/796/731
+f 614/797/754 676/762/723 608/802/758
+f 521/798/755 608/802/758 503/803/759
+f 614/797/754 608/802/758 521/798/755
+f 468/799/756 503/803/759 451/804/760
+f 521/798/755 503/803/759 468/799/756
+f 472/800/757 451/804/760 454/805/761
+f 468/799/756 451/804/760 472/800/757
+f 497/801/731 454/805/761 488/806/731
+f 472/800/757 454/805/761 497/801/731
+f 608/802/758 676/762/723 613/807/762
+f 503/803/759 613/807/762 520/808/763
+f 608/802/758 613/807/762 503/803/759
+f 451/804/760 520/808/763 467/809/764
+f 503/803/759 520/808/763 451/804/760
+f 454/805/761 467/809/764 471/810/765
+f 451/804/760 467/809/764 454/805/761
+f 488/806/731 471/810/765 496/811/731
+f 454/805/761 471/810/765 488/806/731
+f 613/807/762 676/762/723 634/812/766
+f 520/808/763 634/812/766 549/813/767
+f 613/807/762 634/812/766 520/808/763
+f 467/809/764 549/813/767 513/814/768
+f 520/808/763 549/813/767 467/809/764
+f 471/810/765 513/814/768 515/815/769
+f 467/809/764 513/814/768 471/810/765
+f 496/811/731 515/815/769 538/816/770
+f 471/810/765 515/815/769 496/811/731
+f 634/812/766 676/762/723 639/817/771
+f 549/813/767 639/817/771 589/818/772
+f 634/812/766 639/817/771 549/813/767
+f 513/814/768 589/818/772 568/819/773
+f 549/813/767 589/818/772 513/814/768
+f 515/815/769 568/819/773 570/820/774
+f 513/814/768 568/819/773 515/815/769
+f 538/816/770 570/820/774 581/821/749
+f 515/815/769 570/820/774 538/816/770
+f 639/817/771 676/762/723 675/822/775
+f 589/818/772 675/822/775 682/823/776
+f 639/817/771 675/822/775 589/818/772
+f 568/819/773 682/823/776 684/824/777
+f 589/818/772 682/823/776 568/819/773
+f 570/820/774 684/824/777 685/825/778
+f 568/819/773 684/824/777 570/820/774
+f 581/821/749 685/825/778 686/826/749
+f 570/820/774 685/825/778 581/821/749
+f 675/822/775 676/762/723 710/827/779
+f 682/823/776 710/827/779 761/828/780
+f 675/822/775 710/827/779 682/823/776
+f 684/824/777 761/828/780 786/829/781
+f 682/823/776 761/828/780 684/824/777
+f 685/825/778 786/829/781 784/830/782
+f 684/824/777 786/829/781 685/825/778
+f 686/826/749 784/830/782 770/831/749
+f 685/825/778 784/830/782 686/826/749
+f 710/827/779 676/762/723 728/832/783
+f 761/828/780 728/832/783 809/833/784
+f 710/827/779 728/832/783 761/828/780
+f 786/829/781 809/833/784 843/834/785
+f 761/828/780 809/833/784 786/829/781
+f 784/830/782 843/834/785 841/835/786
+f 786/829/781 843/834/785 784/830/782
+f 770/831/749 841/835/786 817/836/749
+f 784/830/782 841/835/786 770/831/749
+f 728/832/783 676/762/723 736/837/787
+f 809/833/784 736/837/787 838/838/788
+f 728/832/783 736/837/787 809/833/784
+f 843/834/785 838/838/788 885/839/789
+f 809/833/784 838/838/788 843/834/785
+f 841/835/786 885/839/789 883/840/790
+f 843/834/785 885/839/789 841/835/786
+f 817/836/749 883/840/790 857/841/731
+f 841/835/786 883/840/790 817/836/749
+f 736/837/787 676/762/723 742/761/722
+f 838/838/788 742/761/722 851/764/725
+f 736/837/787 742/761/722 838/838/788
+f 885/839/789 851/764/725 902/766/727
+f 838/838/788 851/764/725 885/839/789
+f 883/840/790 902/766/727 901/768/729
+f 885/839/789 902/766/727 883/840/790
+f 857/841/731 901/768/729 864/770/731
+f 883/840/790 901/768/729 857/841/731
+f 750/842/791 680/843/792 740/844/793
+f 802/845/794 740/844/793 792/846/795
+f 750/842/791 740/844/793 802/845/794
+f 845/847/796 792/846/795 826/848/797
+f 802/845/794 792/846/795 845/847/796
+f 873/849/798 826/848/797 855/850/799
+f 845/847/796 826/848/797 873/849/798
+f 905/851/800 855/850/799 879/852/801
+f 873/849/798 855/850/799 905/851/800
+f 918/853/802 879/852/801 899/854/803
+f 905/851/800 879/852/801 918/853/802
+f 921/855/804 899/854/803 903/856/805
+f 918/853/802 899/854/803 921/855/804
+f 740/844/793 680/843/792 723/857/806
+f 792/846/795 723/857/806 747/858/807
+f 740/844/793 723/857/806 792/846/795
+f 826/848/797 747/858/807 781/859/808
+f 792/846/795 747/858/807 826/848/797
+f 855/850/799 781/859/808 796/860/809
+f 826/848/797 781/859/808 855/850/799
+f 879/852/801 796/860/809 805/861/810
+f 855/850/799 796/860/809 879/852/801
+f 899/854/803 805/861/810 812/862/811
+f 879/852/801 805/861/810 899/854/803
+f 903/856/805 812/862/811 820/863/812
+f 899/854/803 812/862/811 903/856/805
+f 723/857/806 680/843/792 677/864/813
+f 747/858/807 677/864/813 674/865/814
+f 723/857/806 677/864/813 747/858/807
+f 781/859/808 674/865/814 670/866/815
+f 747/858/807 674/865/814 781/859/808
+f 796/860/809 670/866/815 667/867/816
+f 781/859/808 670/866/815 796/860/809
+f 805/861/810 667/867/816 666/868/817
+f 796/860/809 667/867/816 805/861/810
+f 812/862/811 666/868/817 664/869/818
+f 805/861/810 666/868/817 812/862/811
+f 820/863/812 664/869/818 663/870/819
+f 812/862/811 664/869/818 820/863/812
+f 677/864/813 680/843/792 636/871/820
+f 674/865/814 636/871/820 602/872/821
+f 677/864/813 636/871/820 674/865/814
+f 670/866/815 602/872/821 572/873/822
+f 674/865/814 602/872/821 670/866/815
+f 667/867/816 572/873/822 556/874/823
+f 670/866/815 572/873/822 667/867/816
+f 666/868/817 556/874/823 551/875/824
+f 667/867/816 556/874/823 666/868/817
+f 664/869/818 551/875/824 543/876/825
+f 666/868/817 551/875/824 664/869/818
+f 663/870/819 543/876/825 536/877/826
+f 664/869/818 543/876/825 663/870/819
+f 636/871/820 680/843/792 609/878/827
+f 602/872/821 609/878/827 561/879/828
+f 636/871/820 609/878/827 602/872/821
+f 572/873/822 561/879/828 527/880/829
+f 602/872/821 561/879/828 572/873/822
+f 556/874/823 527/880/829 498/881/830
+f 572/873/822 527/880/829 556/874/823
+f 551/875/824 498/881/830 478/882/831
+f 556/874/823 498/881/830 551/875/824
+f 543/876/825 478/882/831 457/883/832
+f 551/875/824 478/882/831 543/876/825
+f 536/877/826 457/883/832 449/884/833
+f 543/876/825 457/883/832 536/877/826
+f 609/878/827 680/843/792 600/885/834
+f 561/879/828 600/885/834 553/886/835
+f 609/878/827 600/885/834 561/879/828
+f 527/880/829 553/886/835 509/887/836
+f 561/879/828 553/886/835 527/880/829
+f 498/881/830 509/887/836 482/888/837
+f 527/880/829 509/887/836 498/881/830
+f 478/882/831 482/888/837 447/889/838
+f 498/881/830 482/888/837 478/882/831
+f 457/883/832 447/889/838 434/890/839
+f 478/882/831 447/889/838 457/883/832
+f 449/884/833 434/890/839 430/891/840
+f 457/883/832 434/890/839 449/884/833
+f 600/885/834 680/843/792 610/892/841
+f 553/886/835 610/892/841 562/893/842
+f 600/885/834 610/892/841 553/886/835
+f 509/887/836 562/893/842 528/894/843
+f 553/886/835 562/893/842 509/887/836
+f 482/888/837 528/894/843 499/895/844
+f 509/887/836 528/894/843 482/888/837
+f 447/889/838 499/895/844 479/896/845
+f 482/888/837 499/895/844 447/889/838
+f 434/890/839 479/896/845 458/897/846
+f 447/889/838 479/896/845 434/890/839
+f 430/891/840 458/897/846 450/898/847
+f 434/890/839 458/897/846 430/891/840
+f 610/892/841 680/843/792 637/899/848
+f 562/893/842 637/899/848 603/900/849
+f 610/892/841 637/899/848 562/893/842
+f 528/894/843 603/900/849 573/901/850
+f 562/893/842 603/900/849 528/894/843
+f 499/895/844 573/901/850 557/902/851
+f 528/894/843 573/901/850 499/895/844
+f 479/896/845 557/902/851 552/903/852
+f 499/895/844 557/902/851 479/896/845
+f 458/897/846 552/903/852 544/904/853
+f 479/896/845 552/903/852 458/897/846
+f 450/898/847 544/904/853 537/905/854
+f 458/897/846 544/904/853 450/898/847
+f 637/899/848 680/843/792 681/906/855
+f 603/900/849 681/906/855 678/907/856
+f 637/899/848 681/906/855 603/900/849
+f 573/901/850 678/907/856 672/908/857
+f 603/900/849 678/907/856 573/901/850
+f 557/902/851 672/908/857 673/909/858
+f 573/901/850 672/908/857 557/902/851
+f 552/903/852 673/909/858 671/910/859
+f 557/902/851 673/909/858 552/903/852
+f 544/904/853 671/910/859 669/911/860
+f 552/903/852 671/910/859 544/904/853
+f 537/905/854 669/911/860 665/912/861
+f 544/904/853 669/911/860 537/905/854
+f 681/906/855 680/843/792 724/913/862
+f 678/907/856 724/913/862 748/914/863
+f 681/906/855 724/913/862 678/907/856
+f 672/908/857 748/914/863 782/915/864
+f 678/907/856 748/914/863 672/908/857
+f 673/909/858 782/915/864 797/916/865
+f 672/908/857 782/915/864 673/909/858
+f 671/910/859 797/916/865 806/917/866
+f 673/909/858 797/916/865 671/910/859
+f 669/911/860 806/917/866 813/918/867
+f 671/910/859 806/917/866 669/911/860
+f 665/912/861 813/918/867 821/919/868
+f 669/911/860 813/918/867 665/912/861
+f 724/913/862 680/843/792 741/920/869
+f 748/914/863 741/920/869 793/921/870
+f 724/913/862 741/920/869 748/914/863
+f 782/915/864 793/921/870 827/922/871
+f 748/914/863 793/921/870 782/915/864
+f 797/916/865 827/922/871 856/923/872
+f 782/915/864 827/922/871 797/916/865
+f 806/917/866 856/923/872 880/924/873
+f 797/916/865 856/923/872 806/917/866
+f 813/918/867 880/924/873 900/925/874
+f 806/917/866 880/924/873 813/918/867
+f 821/919/868 900/925/874 904/926/875
+f 813/918/867 900/925/874 821/919/868
+f 741/920/869 680/843/792 750/842/791
+f 793/921/870 750/842/791 802/845/794
+f 741/920/869 750/842/791 793/921/870
+f 827/922/871 802/845/794 845/847/796
+f 793/921/870 802/845/794 827/922/871
+f 856/923/872 845/847/796 873/849/798
+f 827/922/871 845/847/796 856/923/872
+f 880/924/873 873/849/798 905/851/800
+f 856/923/872 873/849/798 880/924/873
+f 900/925/874 905/851/800 918/853/802
+f 880/924/873 905/851/800 900/925/874
+f 904/926/875 918/853/802 921/855/804
+f 900/925/874 918/853/802 904/926/875
+f 444/927/876 403/928/877 438/929/878
+f 484/930/879 438/929/878 473/931/880
+f 444/927/876 438/929/878 484/930/879
+f 534/932/881 473/931/880 522/933/882
+f 484/930/879 473/931/880 534/932/881
+f 555/934/883 522/933/882 541/935/884
+f 534/932/881 522/933/882 555/934/883
+f 588/936/885 541/935/884 558/937/886
+f 555/934/883 541/935/884 588/936/885
+f 628/938/887 558/937/886 574/939/888
+f 588/936/885 558/937/886 628/938/887
+f 631/940/889 574/939/888 583/941/890
+f 628/938/887 574/939/888 631/940/889
+f 438/929/878 403/928/877 423/942/891
+f 473/931/880 423/942/891 443/943/892
+f 438/929/878 423/942/891 473/931/880
+f 522/933/882 443/943/892 461/944/893
+f 473/931/880 443/943/892 522/933/882
+f 541/935/884 461/944/893 480/945/894
+f 522/933/882 461/944/893 541/935/884
+f 558/937/886 480/945/894 490/946/895
+f 541/935/884 480/945/894 558/937/886
+f 574/939/888 490/946/895 494/947/896
+f 558/937/886 490/946/895 574/939/888
+f 583/941/890 494/947/896 505/948/897
+f 574/939/888 494/947/896 583/941/890
+f 423/942/891 403/928/877 401/949/898
+f 443/943/892 401/949/898 397/950/899
+f 423/942/891 401/949/898 443/943/892
+f 461/944/893 397/950/899 394/951/900
+f 443/943/892 397/950/899 461/944/893
+f 480/945/894 394/951/900 393/952/901
+f 461/944/893 394/951/900 480/945/894
+f 490/946/895 393/952/901 392/953/902
+f 480/945/894 393/952/901 490/946/895
+f 494/947/896 392/953/902 390/954/903
+f 490/946/895 392/953/902 494/947/896
+f 505/948/897 390/954/903 389/955/904
+f 494/947/896 390/954/903 505/948/897
+f 401/949/898 403/928/877 356/956/905
+f 397/950/899 356/956/905 322/957/906
+f 401/949/898 356/956/905 397/950/899
+f 394/951/900 322/957/906 290/958/907
+f 397/950/899 322/957/906 394/951/900
+f 393/952/901 290/958/907 259/959/908
+f 394/951/900 290/958/907 393/952/901
+f 392/953/902 259/959/908 229/960/909
+f 393/952/901 259/959/908 392/953/902
+f 390/954/903 229/960/909 214/961/910
+f 392/953/902 229/960/909 390/954/903
+f 389/955/904 214/961/910 210/962/911
+f 390/954/903 214/961/910 389/955/904
+f 356/956/905 403/928/877 343/963/912
+f 322/957/906 343/963/912 266/964/913
+f 356/956/905 343/963/912 322/957/906
+f 290/958/907 266/964/913 194/965/914
+f 322/957/906 266/964/913 290/958/907
+f 259/959/908 194/965/914 161/966/915
+f 290/958/907 194/965/914 259/959/908
+f 229/960/909 161/966/915 134/967/916
+f 259/959/908 161/966/915 229/960/909
+f 214/961/910 134/967/916 126/968/917
+f 229/960/909 134/967/916 214/961/910
+f 210/962/911 126/968/917 121/969/918
+f 214/961/910 126/968/917 210/962/911
+f 343/963/912 403/928/877 318/970/919
+f 266/964/913 318/970/919 250/971/920
+f 343/963/912 318/970/919 266/964/913
+f 194/965/914 250/971/920 173/972/921
+f 266/964/913 250/971/920 194/965/914
+f 161/966/915 173/972/921 140/973/922
+f 194/965/914 173/972/921 161/966/915
+f 134/967/916 140/973/922 120/974/923
+f 161/966/915 140/973/922 134/967/916
+f 126/968/917 120/974/923 107/975/924
+f 134/967/916 120/974/923 126/968/917
+f 121/969/918 107/975/924 103/976/925
+f 126/968/917 107/975/924 121/969/918
+f 318/970/919 403/928/877 344/977/926
+f 250/971/920 344/977/926 267/978/927
+f 318/970/919 344/977/926 250/971/920
+f 173/972/921 267/978/927 195/979/928
+f 250/971/920 267/978/927 173/972/921
+f 140/973/922 195/979/928 162/980/929
+f 173/972/921 195/979/928 140/973/922
+f 120/974/923 162/980/929 135/981/930
+f 140/973/922 162/980/929 120/974/923
+f 107/975/924 135/981/930 127/982/931
+f 120/974/923 135/981/930 107/975/924
+f 103/976/925 127/982/931 122/983/932
+f 107/975/924 127/982/931 103/976/925
+f 344/977/926 403/928/877 357/984/933
+f 267/978/927 357/984/933 323/985/934
+f 344/977/926 357/984/933 267/978/927
+f 195/979/928 323/985/934 291/986/935
+f 267/978/927 323/985/934 195/979/928
+f 162/980/929 291/986/935 260/987/936
+f 195/979/928 291/986/935 162/980/929
+f 135/981/930 260/987/936 230/988/937
+f 162/980/929 260/987/936 135/981/930
+f 127/982/931 230/988/937 215/989/938
+f 135/981/930 230/988/937 127/982/931
+f 122/983/932 215/989/938 211/990/939
+f 127/982/931 215/989/938 122/983/932
+f 357/984/933 403/928/877 404/991/940
+f 323/985/934 404/991/940 402/992/941
+f 357/984/933 404/991/940 323/985/934
+f 291/986/935 402/992/941 398/993/942
+f 323/985/934 402/992/941 291/986/935
+f 260/987/936 398/993/942 399/994/943
+f 291/986/935 398/993/942 260/987/936
+f 230/988/937 399/994/943 396/995/944
+f 260/987/936 399/994/943 230/988/937
+f 215/989/938 396/995/944 395/996/945
+f 230/988/937 396/995/944 215/989/938
+f 211/990/939 395/996/945 391/997/946
+f 215/989/938 395/996/945 211/990/939
+f 404/991/940 403/928/877 424/998/947
+f 402/992/941 424/998/947 442/999/948
+f 404/991/940 424/998/947 402/992/941
+f 398/993/942 442/999/948 462/1000/949
+f 402/992/941 442/999/948 398/993/942
+f 399/994/943 462/1000/949 481/1001/950
+f 398/993/942 462/1000/949 399/994/943
+f 396/995/944 481/1001/950 491/1002/951
+f 399/994/943 481/1001/950 396/995/944
+f 395/996/945 491/1002/951 495/1003/952
+f 396/995/944 491/1002/951 395/996/945
+f 391/997/946 495/1003/952 506/1004/953
+f 395/996/945 495/1003/952 391/997/946
+f 424/998/947 403/928/877 439/1005/954
+f 442/999/948 439/1005/954 474/1006/955
+f 424/998/947 439/1005/954 442/999/948
+f 462/1000/949 474/1006/955 523/1007/956
+f 442/999/948 474/1006/955 462/1000/949
+f 481/1001/950 523/1007/956 542/1008/957
+f 462/1000/949 523/1007/956 481/1001/950
+f 491/1002/951 542/1008/957 559/1009/958
+f 481/1001/950 542/1008/957 491/1002/951
+f 495/1003/952 559/1009/958 575/1010/959
+f 491/1002/951 559/1009/958 495/1003/952
+f 506/1004/953 575/1010/959 584/1011/960
+f 495/1003/952 575/1010/959 506/1004/953
+f 439/1005/954 403/928/877 444/927/876
+f 474/1006/955 444/927/876 484/930/879
+f 439/1005/954 444/927/876 474/1006/955
+f 523/1007/956 484/930/879 534/932/881
+f 474/1006/955 484/930/879 523/1007/956
+f 542/1008/957 534/932/881 555/934/883
+f 523/1007/956 534/932/881 542/1008/957
+f 559/1009/958 555/934/883 588/936/885
+f 542/1008/957 555/934/883 559/1009/958
+f 575/1010/959 588/936/885 628/938/887
+f 559/1009/958 588/936/885 575/1010/959
+f 584/1011/960 628/938/887 631/940/889
+f 575/1010/959 628/938/887 584/1011/960
+f 1035/1012/961 966/1013/877 1008/1014/878
+f 1104/1015/879 1008/1014/878 1086/1016/880
+f 1035/1012/961 1008/1014/878 1104/1015/879
+f 1179/1017/962 1086/1016/880 1156/1018/882
+f 1104/1015/879 1086/1016/880 1179/1017/962
+f 1210/1019/883 1156/1018/882 1188/1020/884
+f 1179/1017/962 1156/1018/882 1210/1019/883
+f 1232/1021/885 1188/1020/884 1215/1022/886
+f 1210/1019/883 1188/1020/884 1232/1021/885
+f 1247/1023/887 1215/1022/886 1225/1024/888
+f 1232/1021/885 1215/1022/886 1247/1023/887
+f 1251/1025/889 1225/1024/888 1229/1026/963
+f 1247/1023/887 1225/1024/888 1251/1025/889
+f 1008/1014/878 966/1013/877 997/1027/964
+f 1086/1016/880 997/1027/964 1029/1028/892
+f 1008/1014/878 997/1027/964 1086/1016/880
+f 1156/1018/882 1029/1028/892 1064/1029/965
+f 1086/1016/880 1029/1028/892 1156/1018/882
+f 1188/1020/884 1064/1029/965 1092/1030/894
+f 1156/1018/882 1064/1029/965 1188/1020/884
+f 1215/1022/886 1092/1030/894 1122/1031/895
+f 1188/1020/884 1092/1030/894 1215/1022/886
+f 1225/1024/888 1122/1031/895 1142/1032/896
+f 1215/1022/886 1122/1031/895 1225/1024/888
+f 1229/1026/963 1142/1032/896 1144/1033/897
+f 1225/1024/888 1142/1032/896 1229/1026/963
+f 997/1027/964 966/1013/877 964/1034/966
+f 1029/1028/892 964/1034/966 960/1035/899
+f 997/1027/964 964/1034/966 1029/1028/892
+f 1064/1029/965 960/1035/899 957/1036/900
+f 1029/1028/892 960/1035/899 1064/1029/965
+f 1092/1030/894 957/1036/900 956/1037/901
+f 1064/1029/965 957/1036/900 1092/1030/894
+f 1122/1031/895 956/1037/901 955/1038/902
+f 1092/1030/894 956/1037/901 1122/1031/895
+f 1142/1032/896 955/1038/902 953/1039/903
+f 1122/1031/895 955/1038/902 1142/1032/896
+f 1144/1033/897 953/1039/903 952/1040/967
+f 1142/1032/896 953/1039/903 1144/1033/897
+f 964/1034/966 966/1013/877 926/1041/905
+f 960/1035/899 926/1041/905 910/1042/906
+f 964/1034/966 926/1041/905 960/1035/899
+f 957/1036/900 910/1042/906 890/1043/968
+f 960/1035/899 910/1042/906 957/1036/900
+f 956/1037/901 890/1043/968 877/1044/908
+f 957/1036/900 890/1043/968 956/1037/901
+f 955/1038/902 877/1044/908 861/1045/909
+f 956/1037/901 877/1044/908 955/1038/902
+f 953/1039/903 861/1045/909 859/1046/910
+f 955/1038/902 861/1045/909 953/1039/903
+f 952/1040/967 859/1046/910 848/1047/911
+f 953/1039/903 859/1046/910 952/1040/967
+f 926/1041/905 966/1013/877 913/1048/912
+f 910/1042/906 913/1048/912 881/1049/969
+f 926/1041/905 913/1048/912 910/1042/906
+f 890/1043/968 881/1049/969 836/1050/970
+f 910/1042/906 881/1049/969 890/1043/968
+f 877/1044/908 836/1050/970 814/1051/915
+f 890/1043/968 836/1050/970 877/1044/908
+f 861/1045/909 814/1051/915 794/1052/916
+f 877/1044/908 814/1051/915 861/1045/909
+f 859/1046/910 794/1052/916 779/1053/971
+f 861/1045/909 794/1052/916 859/1046/910
+f 848/1047/911 779/1053/971 768/1054/918
+f 859/1046/910 779/1053/971 848/1047/911
+f 913/1048/912 966/1013/877 909/1055/919
+f 881/1049/969 909/1055/919 869/1056/920
+f 913/1048/912 909/1055/919 881/1049/969
+f 836/1050/970 869/1056/920 822/1057/921
+f 881/1049/969 869/1056/920 836/1050/970
+f 814/1051/915 822/1057/921 798/1058/922
+f 836/1050/970 822/1057/921 814/1051/915
+f 794/1052/916 798/1058/922 763/1059/972
+f 814/1051/915 798/1058/922 794/1052/916
+f 779/1053/971 763/1059/972 735/1060/924
+f 794/1052/916 763/1059/972 779/1053/971
+f 768/1054/918 735/1060/924 732/1061/925
+f 779/1053/971 735/1060/924 768/1054/918
+f 909/1055/919 966/1013/877 914/1062/973
+f 869/1056/920 914/1062/973 882/1063/927
+f 909/1055/919 914/1062/973 869/1056/920
+f 822/1057/921 882/1063/927 837/1064/928
+f 869/1056/920 882/1063/927 822/1057/921
+f 798/1058/922 837/1064/928 815/1065/929
+f 822/1057/921 837/1064/928 798/1058/922
+f 763/1059/972 815/1065/929 795/1066/930
+f 798/1058/922 815/1065/929 763/1059/972
+f 735/1060/924 795/1066/930 780/1067/931
+f 763/1059/972 795/1066/930 735/1060/924
+f 732/1061/925 780/1067/931 769/1068/932
+f 735/1060/924 780/1067/931 732/1061/925
+f 914/1062/973 966/1013/877 927/1069/933
+f 882/1063/927 927/1069/933 911/1070/934
+f 914/1062/973 927/1069/933 882/1063/927
+f 837/1064/928 911/1070/934 891/1071/974
+f 882/1063/927 911/1070/934 837/1064/928
+f 815/1065/929 891/1071/974 878/1072/936
+f 837/1064/928 891/1071/974 815/1065/929
+f 795/1066/930 878/1072/936 862/1073/937
+f 815/1065/929 878/1072/936 795/1066/930
+f 780/1067/931 862/1073/937 860/1074/975
+f 795/1066/930 862/1073/937 780/1067/931
+f 769/1068/932 860/1074/975 849/1075/939
+f 780/1067/931 860/1074/975 769/1068/932
+f 927/1069/933 966/1013/877 967/1076/976
+f 911/1070/934 967/1076/976 965/1077/977
+f 927/1069/933 967/1076/976 911/1070/934
+f 891/1071/974 965/1077/977 961/1078/942
+f 911/1070/934 965/1077/977 891/1071/974
+f 878/1072/936 961/1078/942 962/1079/943
+f 891/1071/974 961/1078/942 878/1072/936
+f 862/1073/937 962/1079/943 959/1080/944
+f 878/1072/936 962/1079/943 862/1073/937
+f 860/1074/975 959/1080/944 958/1081/945
+f 862/1073/937 959/1080/944 860/1074/975
+f 849/1075/939 958/1081/945 954/1082/946
+f 860/1074/975 958/1081/945 849/1075/939
+f 967/1076/976 966/1013/877 998/1083/978
+f 965/1077/977 998/1083/978 1028/1084/948
+f 967/1076/976 998/1083/978 965/1077/977
+f 961/1078/942 1028/1084/948 1065/1085/949
+f 965/1077/977 1028/1084/948 961/1078/942
+f 962/1079/943 1065/1085/949 1093/1086/979
+f 961/1078/942 1065/1085/949 962/1079/943
+f 959/1080/944 1093/1086/979 1123/1087/951
+f 962/1079/943 1093/1086/979 959/1080/944
+f 958/1081/945 1123/1087/951 1143/1088/952
+f 959/1080/944 1123/1087/951 958/1081/945
+f 954/1082/946 1143/1088/952 1145/1089/953
+f 958/1081/945 1143/1088/952 954/1082/946
+f 998/1083/978 966/1013/877 1009/1090/954
+f 1028/1084/948 1009/1090/954 1087/1091/955
+f 998/1083/978 1009/1090/954 1028/1084/948
+f 1065/1085/949 1087/1091/955 1157/1092/980
+f 1028/1084/948 1087/1091/955 1065/1085/949
+f 1093/1086/979 1157/1092/980 1189/1093/957
+f 1065/1085/949 1157/1092/980 1093/1086/979
+f 1123/1087/951 1189/1093/957 1216/1094/958
+f 1093/1086/979 1189/1093/957 1123/1087/951
+f 1143/1088/952 1216/1094/958 1224/1095/959
+f 1123/1087/951 1216/1094/958 1143/1088/952
+f 1145/1089/953 1224/1095/959 1230/1096/981
+f 1143/1088/952 1224/1095/959 1145/1089/953
+f 1009/1090/954 966/1013/877 1035/1012/961
+f 1087/1091/955 1035/1012/961 1104/1015/879
+f 1009/1090/954 1035/1012/961 1087/1091/955
+f 1157/1092/980 1104/1015/879 1179/1017/962
+f 1087/1091/955 1104/1015/879 1157/1092/980
+f 1189/1093/957 1179/1017/962 1210/1019/883
+f 1157/1092/980 1179/1017/962 1189/1093/957
+f 1216/1094/958 1210/1019/883 1232/1021/885
+f 1189/1093/957 1210/1019/883 1216/1094/958
+f 1224/1095/959 1232/1021/885 1247/1023/887
+f 1216/1094/958 1232/1021/885 1224/1095/959
+f 1230/1096/981 1247/1023/887 1251/1025/889
+f 1224/1095/959 1247/1023/887 1230/1096/981
+f 1096/1097/982 1079/1098/983 1090/1099/984
+f 1136/1100/985 1090/1099/984 1100/1101/986
+f 1096/1097/982 1090/1099/984 1136/1100/985
+f 1152/1102/987 1100/1101/986 1119/1103/988
+f 1136/1100/985 1100/1101/986 1152/1102/987
+f 1168/1104/989 1119/1103/988 1134/1105/990
+f 1152/1102/987 1119/1103/988 1168/1104/989
+f 1090/1099/984 1079/1098/983 1078/1106/991
+f 1100/1101/986 1078/1106/991 1076/1107/992
+f 1090/1099/984 1078/1106/991 1100/1101/986
+f 1119/1103/988 1076/1107/992 1073/1108/993
+f 1100/1101/986 1076/1107/992 1119/1103/988
+f 1134/1105/990 1073/1108/993 1071/1109/994
+f 1119/1103/988 1073/1108/993 1134/1105/990
+f 1078/1106/991 1079/1098/983 1059/1110/995
+f 1076/1107/992 1059/1110/995 1050/1111/996
+f 1078/1106/991 1059/1110/995 1076/1107/992
+f 1073/1108/993 1050/1111/996 1037/1112/997
+f 1076/1107/992 1050/1111/996 1073/1108/993
+f 1071/1109/994 1037/1112/997 1026/1113/998
+f 1073/1108/993 1037/1112/997 1071/1109/994
+f 1059/1110/995 1079/1098/983 1054/1114/999
+f 1050/1111/996 1054/1114/999 1022/1115/1000
+f 1059/1110/995 1054/1114/999 1050/1111/996
+f 1037/1112/997 1022/1115/1000 1000/1116/1001
+f 1050/1111/996 1022/1115/1000 1037/1112/997
+f 1026/1113/998 1000/1116/1001 994/1117/1002
+f 1037/1112/997 1000/1116/1001 1026/1113/998
+f 1054/1114/999 1079/1098/983 1048/1118/1003
+f 1022/1115/1000 1048/1118/1003 1004/1119/1004
+f 1054/1114/999 1048/1118/1003 1022/1115/1000
+f 1000/1116/1001 1004/1119/1004 990/1120/1005
+f 1022/1115/1000 1004/1119/1004 1000/1116/1001
+f 994/1117/1002 990/1120/1005 971/1121/1006
+f 1000/1116/1001 990/1120/1005 994/1117/1002
+f 1048/1118/1003 1079/1098/983 1042/1122/1007
+f 1004/1119/1004 1042/1122/1007 1001/1123/1008
+f 1048/1118/1003 1042/1122/1007 1004/1119/1004
+f 990/1120/1005 1001/1123/1008 981/1124/1009
+f 1004/1119/1004 1001/1123/1008 990/1120/1005
+f 971/1121/1006 981/1124/1009 948/1125/1010
+f 990/1120/1005 981/1124/1009 971/1121/1006
+f 1042/1122/1007 1079/1098/983 1047/1126/1011
+f 1001/1123/1008 1047/1126/1011 1003/1127/1012
+f 1042/1122/1007 1047/1126/1011 1001/1123/1008
+f 981/1124/1009 1003/1127/1012 989/1128/1013
+f 1001/1123/1008 1003/1127/1012 981/1124/1009
+f 948/1125/1010 989/1128/1013 970/1129/1014
+f 981/1124/1009 989/1128/1013 948/1125/1010
+f 1047/1126/1011 1079/1098/983 1053/1130/1015
+f 1003/1127/1012 1053/1130/1015 1021/1131/1016
+f 1047/1126/1011 1053/1130/1015 1003/1127/1012
+f 989/1128/1013 1021/1131/1016 999/1132/1017
+f 1003/1127/1012 1021/1131/1016 989/1128/1013
+f 970/1129/1014 999/1132/1017 993/1133/1018
+f 989/1128/1013 999/1132/1017 970/1129/1014
+f 1053/1130/1015 1079/1098/983 1058/1134/1019
+f 1021/1131/1016 1058/1134/1019 1049/1135/1020
+f 1053/1130/1015 1058/1134/1019 1021/1131/1016
+f 999/1132/1017 1049/1135/1020 1036/1136/1021
+f 1021/1131/1016 1049/1135/1020 999/1132/1017
+f 993/1133/1018 1036/1136/1021 1025/1137/1022
+f 999/1132/1017 1036/1136/1021 993/1133/1018
+f 1058/1134/1019 1079/1098/983 1077/1138/1023
+f 1049/1135/1020 1077/1138/1023 1075/1139/1024
+f 1058/1134/1019 1077/1138/1023 1049/1135/1020
+f 1036/1136/1021 1075/1139/1024 1072/1140/1025
+f 1049/1135/1020 1075/1139/1024 1036/1136/1021
+f 1025/1137/1022 1072/1140/1025 1070/1141/1026
+f 1036/1136/1021 1072/1140/1025 1025/1137/1022
+f 1077/1138/1023 1079/1098/983 1089/1142/1027
+f 1075/1139/1024 1089/1142/1027 1099/1143/1028
+f 1077/1138/1023 1089/1142/1027 1075/1139/1024
+f 1072/1140/1025 1099/1143/1028 1118/1144/1029
+f 1075/1139/1024 1099/1143/1028 1072/1140/1025
+f 1070/1141/1026 1118/1144/1029 1133/1145/1030
+f 1072/1140/1025 1118/1144/1029 1070/1141/1026
+f 1089/1142/1027 1079/1098/983 1095/1146/1031
+f 1099/1143/1028 1095/1146/1031 1135/1147/1032
+f 1089/1142/1027 1095/1146/1031 1099/1143/1028
+f 1118/1144/1029 1135/1147/1032 1151/1148/1033
+f 1099/1143/1028 1135/1147/1032 1118/1144/1029
+f 1133/1145/1030 1151/1148/1033 1167/1149/1034
+f 1118/1144/1029 1151/1148/1033 1133/1145/1030
+f 1095/1146/1031 1079/1098/983 1105/1150/1035
+f 1135/1147/1032 1105/1150/1035 1147/1151/1036
+f 1095/1146/1031 1105/1150/1035 1135/1147/1032
+f 1151/1148/1033 1147/1151/1036 1171/1152/1037
+f 1135/1147/1032 1147/1151/1036 1151/1148/1033
+f 1167/1149/1034 1171/1152/1037 1185/1153/1038
+f 1151/1148/1033 1171/1152/1037 1167/1149/1034
+f 1105/1150/1035 1079/1098/983 1113/1154/1039
+f 1147/1151/1036 1113/1154/1039 1150/1155/1040
+f 1105/1150/1035 1113/1154/1039 1147/1151/1036
+f 1171/1152/1037 1150/1155/1040 1175/1156/1041
+f 1147/1151/1036 1150/1155/1040 1171/1152/1037
+f 1185/1153/1038 1175/1156/1041 1194/1157/1042
+f 1171/1152/1037 1175/1156/1041 1185/1153/1038
+f 1113/1154/1039 1079/1098/983 1106/1158/1043
+f 1150/1155/1040 1106/1158/1043 1148/1159/1044
+f 1113/1154/1039 1106/1158/1043 1150/1155/1040
+f 1175/1156/1041 1148/1159/1044 1172/1160/1045
+f 1150/1155/1040 1148/1159/1044 1175/1156/1041
+f 1194/1157/1042 1172/1160/1045 1186/1161/1046
+f 1175/1156/1041 1172/1160/1045 1194/1157/1042
+f 1106/1158/1043 1079/1098/983 1096/1097/982
+f 1148/1159/1044 1096/1097/982 1136/1100/985
+f 1106/1158/1043 1096/1097/982 1148/1159/1044
+f 1172/1160/1045 1136/1100/985 1152/1102/987
+f 1148/1159/1044 1136/1100/985 1172/1160/1045
+f 1186/1161/1046 1152/1102/987 1168/1104/989
+f 1172/1160/1045 1152/1102/987 1186/1161/1046
+f 301/1162/1047 284/1163/1048 296/1164/984
+f 331/1165/985 296/1164/984 305/1166/1049
+f 301/1162/1047 296/1164/984 331/1165/985
+f 355/1167/1050 305/1166/1049 315/1168/988
+f 331/1165/985 305/1166/1049 355/1167/1050
+f 361/1169/989 315/1168/988 327/1170/1051
+f 355/1167/1050 315/1168/988 361/1169/989
+f 296/1164/984 284/1163/1048 283/1171/991
+f 305/1166/1049 283/1171/991 281/1172/992
+f 296/1164/984 283/1171/991 305/1166/1049
+f 315/1168/988 281/1172/992 278/1173/993
+f 305/1166/1049 281/1172/992 315/1168/988
+f 327/1170/1051 278/1173/993 276/1174/994
+f 315/1168/988 278/1173/993 327/1170/1051
+f 283/1171/991 284/1163/1048 263/1175/995
+f 281/1172/992 263/1175/995 253/1176/1052
+f 283/1171/991 263/1175/995 281/1172/992
+f 278/1173/993 253/1176/1052 231/1177/1053
+f 281/1172/992 253/1176/1052 278/1173/993
+f 276/1174/994 231/1177/1053 220/1178/998
+f 278/1173/993 231/1177/1053 276/1174/994
+f 263/1175/995 284/1163/1048 257/1179/999
+f 253/1176/1052 257/1179/999 218/1180/1000
+f 263/1175/995 257/1179/999 253/1176/1052
+f 231/1177/1053 218/1180/1000 199/1181/1054
+f 253/1176/1052 218/1180/1000 231/1177/1053
+f 220/1178/998 199/1181/1054 186/1182/1055
+f 231/1177/1053 199/1181/1054 220/1178/998
+f 257/1179/999 284/1163/1048 249/1183/1003
+f 218/1180/1000 249/1183/1003 208/1184/1056
+f 257/1179/999 249/1183/1003 218/1180/1000
+f 199/1181/1054 208/1184/1056 178/1185/1005
+f 218/1180/1000 208/1184/1056 199/1181/1054
+f 186/1182/1055 178/1185/1005 166/1186/1006
+f 199/1181/1054 178/1185/1005 186/1182/1055
+f 249/1183/1003 284/1163/1048 241/1187/1057
+f 208/1184/1056 241/1187/1057 201/1188/1058
+f 249/1183/1003 241/1187/1057 208/1184/1056
+f 178/1185/1005 201/1188/1058 176/1189/1009
+f 208/1184/1056 201/1188/1058 178/1185/1005
+f 166/1186/1006 176/1189/1009 160/1190/1010
+f 178/1185/1005 176/1189/1009 166/1186/1006
+f 241/1187/1057 284/1163/1048 248/1191/1011
+f 201/1188/1058 248/1191/1011 207/1192/1012
+f 241/1187/1057 248/1191/1011 201/1188/1058
+f 176/1189/1009 207/1192/1012 177/1193/1059
+f 201/1188/1058 207/1192/1012 176/1189/1009
+f 160/1190/1010 177/1193/1059 165/1194/1014
+f 176/1189/1009 177/1193/1059 160/1190/1010
+f 248/1191/1011 284/1163/1048 256/1195/1015
+f 207/1192/1012 256/1195/1015 217/1196/1016
+f 248/1191/1011 256/1195/1015 207/1192/1012
+f 177/1193/1059 217/1196/1016 200/1197/1060
+f 207/1192/1012 217/1196/1016 177/1193/1059
+f 165/1194/1014 200/1197/1060 185/1198/1018
+f 177/1193/1059 200/1197/1060 165/1194/1014
+f 256/1195/1015 284/1163/1048 262/1199/1019
+f 217/1196/1016 262/1199/1019 252/1200/1020
+f 256/1195/1015 262/1199/1019 217/1196/1016
+f 200/1197/1060 252/1200/1020 232/1201/1061
+f 217/1196/1016 252/1200/1020 200/1197/1060
+f 185/1198/1018 232/1201/1061 219/1202/1022
+f 200/1197/1060 232/1201/1061 185/1198/1018
+f 262/1199/1019 284/1163/1048 282/1203/1023
+f 252/1200/1020 282/1203/1023 280/1204/1024
+f 262/1199/1019 282/1203/1023 252/1200/1020
+f 232/1201/1061 280/1204/1024 277/1205/1062
+f 252/1200/1020 280/1204/1024 232/1201/1061
+f 219/1202/1022 277/1205/1062 275/1206/1063
+f 232/1201/1061 277/1205/1062 219/1202/1022
+f 282/1203/1023 284/1163/1048 295/1207/1027
+f 280/1204/1024 295/1207/1027 304/1208/1064
+f 282/1203/1023 295/1207/1027 280/1204/1024
+f 277/1205/1062 304/1208/1064 314/1209/1029
+f 280/1204/1024 304/1208/1064 277/1205/1062
+f 275/1206/1063 314/1209/1029 326/1210/1065
+f 277/1205/1062 314/1209/1029 275/1206/1063
+f 295/1207/1027 284/1163/1048 300/1211/1066
+f 304/1208/1064 300/1211/1066 330/1212/1032
+f 295/1207/1027 300/1211/1066 304/1208/1064
+f 314/1209/1029 330/1212/1032 354/1213/1033
+f 304/1208/1064 330/1212/1032 314/1209/1029
+f 326/1210/1065 354/1213/1033 360/1214/1034
+f 314/1209/1029 354/1213/1033 326/1210/1065
+f 300/1211/1066 284/1163/1048 306/1215/1035
+f 330/1212/1032 306/1215/1035 347/1216/1067
+f 300/1211/1066 306/1215/1035 330/1212/1032
+f 354/1213/1033 347/1216/1067 370/1217/1068
+f 330/1212/1032 347/1216/1067 354/1213/1033
+f 360/1214/1034 370/1217/1068 382/1218/1038
+f 354/1213/1033 370/1217/1068 360/1214/1034
+f 306/1215/1035 284/1163/1048 311/1219/1039
+f 347/1216/1067 311/1219/1039 351/1220/1069
+f 306/1215/1035 311/1219/1039 347/1216/1067
+f 370/1217/1068 351/1220/1069 373/1221/1070
+f 347/1216/1067 351/1220/1069 370/1217/1068
+f 382/1218/1038 373/1221/1070 406/1222/1071
+f 370/1217/1068 373/1221/1070 382/1218/1038
+f 311/1219/1039 284/1163/1048 307/1223/1072
+f 351/1220/1069 307/1223/1072 348/1224/1073
+f 311/1219/1039 307/1223/1072 351/1220/1069
+f 373/1221/1070 348/1224/1073 371/1225/1074
+f 351/1220/1069 348/1224/1073 373/1221/1070
+f 406/1222/1071 371/1225/1074 383/1226/1075
+f 373/1221/1070 371/1225/1074 406/1222/1071
+f 307/1223/1072 284/1163/1048 301/1162/1047
+f 348/1224/1073 301/1162/1047 331/1165/985
+f 307/1223/1072 301/1162/1047 348/1224/1073
+f 371/1225/1074 331/1165/985 355/1167/1050
+f 348/1224/1073 331/1165/985 371/1225/1074
+f 383/1226/1075 355/1167/1050 361/1169/989
+f 371/1225/1074 355/1167/1050 383/1226/1075
+f 1080/1227/1076 1250/1228/1077 1249/580/561
+f 1081/1229/1076 1250/1228/1077 1080/1227/1076
+f 1249/580/561 1279/1230/1078 1278/592/573
+f 1250/1228/1077 1279/1230/1078 1249/580/561
+f 1278/592/573 1286/1231/1079 1285/598/579
+f 1279/1230/1078 1286/1231/1079 1278/592/573
+f 1285/598/579 1290/1232/1080 1289/1233/1080
+f 1286/1231/1079 1290/1232/1080 1285/598/579
+f 1289/1233/1080 1288/1234/1081 1287/1235/1081
+f 1290/1232/1080 1288/1234/1081 1289/1233/1080
+f 1287/1235/1081 1283/1236/1082 1282/1237/1082
+f 1288/1234/1081 1283/1236/1082 1287/1235/1081
+f 1282/1237/1082 1281/1238/1083 1280/604/585
+f 1283/1236/1082 1281/1238/1083 1282/1237/1082
+f 1280/604/585 1242/1239/1084 1241/1240/1084
+f 1281/1238/1083 1242/1239/1084 1280/604/585
+f 1241/1240/1084 1081/1229/1076 1080/1227/1076
+f 1242/1239/1084 1081/1229/1076 1241/1240/1084
+f 273/1241/1085 104/521/502 105/1242/1086
+f 274/1243/1085 273/1241/1085 105/1242/1086
+f 104/521/502 75/532/513 76/1244/1087
+f 105/1242/1086 104/521/502 76/1244/1087
+f 75/532/513 66/538/519 67/1245/1088
+f 76/1244/1087 75/532/513 67/1245/1088
+f 66/538/519 62/1246/1089 63/1247/1089
+f 67/1245/1088 66/538/519 63/1247/1089
+f 62/1246/1089 64/1248/1090 65/1249/1090
+f 63/1247/1089 62/1246/1089 65/1249/1090
+f 64/1248/1090 68/1250/1091 69/1251/1091
+f 65/1249/1090 64/1248/1090 69/1251/1091
+f 68/1250/1091 72/544/525 73/1252/1092
+f 69/1251/1091 68/1250/1091 73/1252/1092
+f 72/544/525 113/1253/1093 114/1254/1093
+f 73/1252/1092 72/544/525 114/1254/1093
+f 113/1253/1093 273/1241/1085 274/1243/1085
+f 114/1254/1093 113/1253/1093 274/1243/1085
+f 1097/1255/1094 1074/1256/1095 1084/1257/1096
+f 1184/1258/1097 1084/1257/1096 1121/1259/1098
+f 1097/1255/1094 1084/1257/1096 1184/1258/1097
+f 1181/1260/1099 1121/1259/1098 1120/1261/1100
+f 1184/1258/1097 1121/1259/1098 1181/1260/1099
+f 1170/1262/1048 1120/1261/1100 1110/1263/1048
+f 1181/1260/1099 1120/1261/1100 1170/1262/1048
+f 1084/1257/1096 1074/1256/1095 1060/1264/1101
+f 1121/1259/1098 1060/1264/1101 1032/1265/1102
+f 1084/1257/1096 1060/1264/1101 1121/1259/1098
+f 1120/1261/1100 1032/1265/1102 1034/1266/1103
+f 1121/1259/1098 1032/1265/1102 1120/1261/1100
+f 1110/1263/1048 1034/1266/1103 1041/1267/1048
+f 1120/1261/1100 1034/1266/1103 1110/1263/1048
+f 1060/1264/1101 1074/1256/1095 1051/1268/1104
+f 1032/1265/1102 1051/1268/1104 969/1269/1105
+f 1060/1264/1101 1051/1268/1104 1032/1265/1102
+f 1034/1266/1103 969/1269/1105 974/1270/1106
+f 1032/1265/1102 969/1269/1105 1034/1266/1103
+f 1041/1267/1048 974/1270/1106 991/1271/1048
+f 1034/1266/1103 974/1270/1106 1041/1267/1048
+f 1051/1268/1104 1074/1256/1095 1043/1272/1107
+f 969/1269/1105 1043/1272/1107 925/1273/1108
+f 1051/1268/1104 1043/1272/1107 969/1269/1105
+f 974/1270/1106 925/1273/1108 929/1274/1109
+f 969/1269/1105 925/1273/1108 974/1270/1106
+f 991/1271/1048 929/1274/1109 943/1275/1048
+f 974/1270/1106 929/1274/1109 991/1271/1048
+f 1043/1272/1107 1074/1256/1095 1044/1276/1110
+f 925/1273/1108 1044/1276/1110 928/1277/1111
+f 1043/1272/1107 1044/1276/1110 925/1273/1108
+f 929/1274/1109 928/1277/1111 932/1278/1112
+f 925/1273/1108 928/1277/1111 929/1274/1109
+f 943/1275/1048 932/1278/1112 944/1279/983
+f 929/1274/1109 932/1278/1112 943/1275/1048
+f 1044/1276/1110 1074/1256/1095 1052/1280/1113
+f 928/1277/1111 1052/1280/1113 975/1281/1114
+f 1044/1276/1110 1052/1280/1113 928/1277/1111
+f 932/1278/1112 975/1281/1114 976/1282/1115
+f 928/1277/1111 975/1281/1114 932/1278/1112
+f 944/1279/983 976/1282/1115 992/1283/983
+f 932/1278/1112 976/1282/1115 944/1279/983
+f 1052/1280/1113 1074/1256/1095 1061/1284/1116
+f 975/1281/1114 1061/1284/1116 1039/1285/1117
+f 1052/1280/1113 1061/1284/1116 975/1281/1114
+f 976/1282/1115 1039/1285/1117 1040/1286/1118
+f 975/1281/1114 1039/1285/1117 976/1282/1115
+f 992/1283/983 1040/1286/1118 1046/1287/1048
+f 976/1282/1115 1040/1286/1118 992/1283/983
+f 1061/1284/1116 1074/1256/1095 1085/1288/1119
+f 1039/1285/1117 1085/1288/1119 1128/1289/1120
+f 1061/1284/1116 1085/1288/1119 1039/1285/1117
+f 1040/1286/1118 1128/1289/1120 1127/1290/1121
+f 1039/1285/1117 1128/1289/1120 1040/1286/1118
+f 1046/1287/1048 1127/1290/1121 1115/1291/1122
+f 1040/1286/1118 1127/1290/1121 1046/1287/1048
+f 1085/1288/1119 1074/1256/1095 1098/1292/1123
+f 1128/1289/1120 1098/1292/1123 1190/1293/1124
+f 1085/1288/1119 1098/1292/1123 1128/1289/1120
+f 1127/1290/1121 1190/1293/1124 1187/1294/1125
+f 1128/1289/1120 1190/1293/1124 1127/1290/1121
+f 1115/1291/1122 1187/1294/1125 1173/1295/1048
+f 1127/1290/1121 1187/1294/1125 1115/1291/1122
+f 1098/1292/1123 1074/1256/1095 1112/1296/1126
+f 1190/1293/1124 1112/1296/1126 1217/1297/1127
+f 1098/1292/1123 1112/1296/1126 1190/1293/1124
+f 1187/1294/1125 1217/1297/1127 1212/1298/1128
+f 1190/1293/1124 1217/1297/1127 1187/1294/1125
+f 1173/1295/1048 1212/1298/1128 1198/1299/1048
+f 1187/1294/1125 1212/1298/1128 1173/1295/1048
+f 1112/1296/1126 1074/1256/1095 1111/1300/1129
+f 1217/1297/1127 1111/1300/1129 1214/1301/1130
+f 1112/1296/1126 1111/1300/1129 1217/1297/1127
+f 1212/1298/1128 1214/1301/1130 1211/1302/1131
+f 1217/1297/1127 1214/1301/1130 1212/1298/1128
+f 1198/1299/1048 1211/1302/1131 1195/1303/1048
+f 1212/1298/1128 1211/1302/1131 1198/1299/1048
+f 1111/1300/1129 1074/1256/1095 1097/1255/1094
+f 1214/1301/1130 1097/1255/1094 1184/1258/1097
+f 1111/1300/1129 1097/1255/1094 1214/1301/1130
+f 1211/1302/1131 1184/1258/1097 1181/1260/1099
+f 1214/1301/1130 1184/1258/1097 1211/1302/1131
+f 1195/1303/1048 1181/1260/1099 1170/1262/1048
+f 1211/1302/1131 1181/1260/1099 1195/1303/1048
+f 302/1304/1132 279/1305/1095 293/1306/1133
+f 380/1307/1097 293/1306/1133 317/1308/1098
+f 302/1304/1132 293/1306/1133 380/1307/1097
+f 379/1309/1134 317/1308/1098 316/1310/1135
+f 380/1307/1097 317/1308/1098 379/1309/1134
+f 369/1311/1136 316/1310/1135 308/1312/1137
+f 379/1309/1134 316/1310/1135 369/1311/1136
+f 369/1311/1136 308/1312/1137 285/1313/1138
+f 293/1306/1133 279/1305/1095 269/1314/1139
+f 317/1308/1098 269/1314/1139 226/1315/1102
+f 293/1306/1133 269/1314/1139 317/1308/1098
+f 316/1310/1135 226/1315/1102 228/1316/1103
+f 317/1308/1098 226/1315/1102 316/1310/1135
+f 308/1312/1137 228/1316/1103 239/1317/1140
+f 316/1310/1135 228/1316/1103 308/1312/1137
+f 308/1312/1137 239/1317/1140 285/1313/1138
+f 269/1314/1139 279/1305/1095 254/1318/1104
+f 226/1315/1102 254/1318/1104 163/1319/1105
+f 269/1314/1139 254/1318/1104 226/1315/1102
+f 228/1316/1103 163/1319/1105 167/1320/1106
+f 226/1315/1102 163/1319/1105 228/1316/1103
+f 239/1317/1140 167/1320/1106 179/1321/1141
+f 228/1316/1103 167/1320/1106 239/1317/1140
+f 239/1317/1140 179/1321/1141 285/1313/1138
+f 254/1318/1104 279/1305/1095 242/1322/1107
+f 163/1319/1105 242/1322/1107 136/1323/1108
+f 254/1318/1104 242/1322/1107 163/1319/1105
+f 167/1320/1106 136/1323/1108 138/1324/1142
+f 163/1319/1105 136/1323/1108 167/1320/1106
+f 179/1321/1141 138/1324/1142 156/1325/1143
+f 167/1320/1106 138/1324/1142 179/1321/1141
+f 179/1321/1141 156/1325/1143 285/1313/1138
+f 242/1322/1107 279/1305/1095 243/1326/1144
+f 136/1323/1108 243/1326/1144 137/1327/1145
+f 242/1322/1107 243/1326/1144 136/1323/1108
+f 138/1324/1142 137/1327/1145 139/1328/1146
+f 136/1323/1108 137/1327/1145 138/1324/1142
+f 156/1325/1143 139/1328/1146 158/1329/1147
+f 138/1324/1142 139/1328/1146 156/1325/1143
+f 156/1325/1143 158/1329/1147 285/1313/1138
+f 243/1326/1144 279/1305/1095 255/1330/1148
+f 137/1327/1145 255/1330/1148 168/1331/1114
+f 243/1326/1144 255/1330/1148 137/1327/1145
+f 139/1328/1146 168/1331/1114 172/1332/1149
+f 137/1327/1145 168/1331/1114 139/1328/1146
+f 158/1329/1147 172/1332/1149 183/1333/1150
+f 139/1328/1146 172/1332/1149 158/1329/1147
+f 158/1329/1147 183/1333/1150 285/1313/1138
+f 255/1330/1148 279/1305/1095 272/1334/1151
+f 168/1331/1114 272/1334/1151 233/1335/1117
+f 255/1330/1148 272/1334/1151 168/1331/1114
+f 172/1332/1149 233/1335/1117 234/1336/1152
+f 168/1331/1114 233/1335/1117 172/1332/1149
+f 183/1333/1150 234/1336/1152 244/1337/1153
+f 172/1332/1149 234/1336/1152 183/1333/1150
+f 183/1333/1150 244/1337/1153 285/1313/1138
+f 272/1334/1151 279/1305/1095 294/1338/1154
+f 233/1335/1117 294/1338/1154 324/1339/1120
+f 272/1334/1151 294/1338/1154 233/1335/1117
+f 234/1336/1152 324/1339/1120 319/1340/1121
+f 233/1335/1117 324/1339/1120 234/1336/1152
+f 244/1337/1153 319/1340/1121 312/1341/1155
+f 234/1336/1152 319/1340/1121 244/1337/1153
+f 244/1337/1153 312/1341/1155 285/1313/1138
+f 294/1338/1154 279/1305/1095 303/1342/1156
+f 324/1339/1120 303/1342/1156 385/1343/1157
+f 294/1338/1154 303/1342/1156 324/1339/1120
+f 319/1340/1121 385/1343/1157 384/1344/1158
+f 324/1339/1120 385/1343/1157 319/1340/1121
+f 312/1341/1155 384/1344/1158 372/1345/1159
+f 319/1340/1121 384/1344/1158 312/1341/1155
+f 312/1341/1155 372/1345/1159 285/1313/1138
+f 303/1342/1156 279/1305/1095 310/1346/1126
+f 385/1343/1157 310/1346/1126 426/1347/1127
+f 303/1342/1156 310/1346/1126 385/1343/1157
+f 384/1344/1158 426/1347/1127 422/1348/1160
+f 385/1343/1157 426/1347/1127 384/1344/1158
+f 372/1345/1159 422/1348/1160 411/1349/1161
+f 384/1344/1158 422/1348/1160 372/1345/1159
+f 372/1345/1159 411/1349/1161 285/1313/1138
+f 310/1346/1126 279/1305/1095 309/1350/1129
+f 426/1347/1127 309/1350/1129 425/1351/1162
+f 310/1346/1126 309/1350/1129 426/1347/1127
+f 422/1348/1160 425/1351/1162 421/1352/1163
+f 426/1347/1127 425/1351/1162 422/1348/1160
+f 411/1349/1161 421/1352/1163 410/1353/1164
+f 422/1348/1160 421/1352/1163 411/1349/1161
+f 411/1349/1161 410/1353/1164 285/1313/1138
+f 309/1350/1129 279/1305/1095 302/1304/1132
+f 425/1351/1162 302/1304/1132 380/1307/1097
+f 309/1350/1129 302/1304/1132 425/1351/1162
+f 421/1352/1163 380/1307/1097 379/1309/1134
+f 425/1351/1162 380/1307/1097 421/1352/1163
+f 410/1353/1164 379/1309/1134 369/1311/1136
+f 421/1352/1163 379/1309/1134 410/1353/1164
+f 410/1353/1164 369/1311/1136 285/1313/1138
diff --git a/tests/manual/barstest/shuttle.png b/tests/manual/barstest/shuttle.png
new file mode 100644
index 00000000..52d6244c
--- /dev/null
+++ b/tests/manual/barstest/shuttle.png
Binary files differ
diff --git a/tests/manual/directional/directional.pro b/tests/manual/directional/directional.pro
new file mode 100644
index 00000000..25b2a1f6
--- /dev/null
+++ b/tests/manual/directional/directional.pro
@@ -0,0 +1,8 @@
+!include( ../tests.pri ) {
+ error( "Couldn't find the tests.pri file!" )
+}
+
+SOURCES += main.cpp scatterdatamodifier.cpp
+HEADERS += scatterdatamodifier.h
+
+QT += widgets
diff --git a/tests/manual/directional/main.cpp b/tests/manual/directional/main.cpp
new file mode 100644
index 00000000..0eed202d
--- /dev/null
+++ b/tests/manual/directional/main.cpp
@@ -0,0 +1,166 @@
+/******************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module.
+**
+** $QT_BEGIN_LICENSE:COMM$
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** $QT_END_LICENSE$
+**
+******************************************************************************/
+
+#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)
+{
+ QApplication app(argc, argv);
+ Q3DScatter *graph = new Q3DScatter();
+ QWidget *container = QWidget::createWindowContainer(graph);
+
+ 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);
+
+ QWidget *widget = new QWidget;
+ QHBoxLayout *hLayout = new QHBoxLayout(widget);
+ QVBoxLayout *vLayout = new QVBoxLayout();
+ hLayout->addWidget(container, 1);
+ hLayout->addLayout(vLayout);
+
+ widget->setWindowTitle(QStringLiteral("Directional scatter"));
+
+ 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"));
+
+ QComboBox *itemStyleList = new QComboBox(widget);
+ itemStyleList->addItem(QStringLiteral("Arrow"), int(QAbstract3DSeries::MeshArrow));
+ itemStyleList->addItem(QStringLiteral("Cube"), int(QAbstract3DSeries::MeshCube));
+ itemStyleList->addItem(QStringLiteral("Minimal"), int(QAbstract3DSeries::MeshMinimal));
+ itemStyleList->setCurrentIndex(-1);
+
+ QPushButton *cameraButton = new QPushButton(widget);
+ cameraButton->setText(QStringLiteral("Change camera preset"));
+
+ QPushButton *toggleRotationButton = new QPushButton(widget);
+ toggleRotationButton->setText(QStringLiteral("Toggle animation"));
+
+ QCheckBox *backgroundCheckBox = new QCheckBox(widget);
+ backgroundCheckBox->setText(QStringLiteral("Show background"));
+ backgroundCheckBox->setChecked(true);
+
+ QCheckBox *optimizationCheckBox = new QCheckBox(widget);
+ optimizationCheckBox->setText(QStringLiteral("Optimization static"));
+
+ 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(4);
+
+ QFontComboBox *fontList = new QFontComboBox(widget);
+ fontList->setCurrentFont(QFont("Arial"));
+
+ vLayout->addWidget(labelButton, 0, Qt::AlignTop);
+ vLayout->addWidget(cameraButton, 0, Qt::AlignTop);
+ vLayout->addWidget(toggleRotationButton, 0, Qt::AlignTop);
+ vLayout->addWidget(optimizationCheckBox);
+ vLayout->addWidget(backgroundCheckBox);
+ vLayout->addWidget(gridCheckBox);
+ vLayout->addWidget(new QLabel(QStringLiteral("Change dot style")));
+ vLayout->addWidget(itemStyleList);
+ 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);
+
+ ScatterDataModifier *modifier = new ScatterDataModifier(graph);
+
+ QObject::connect(cameraButton, &QPushButton::clicked, modifier,
+ &ScatterDataModifier::changePresetCamera);
+ QObject::connect(toggleRotationButton, &QPushButton::clicked, modifier,
+ &ScatterDataModifier::toggleRotation);
+ 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(modifier, &ScatterDataModifier::backgroundEnabledChanged,
+ backgroundCheckBox, &QCheckBox::setChecked);
+ QObject::connect(optimizationCheckBox, &QCheckBox::stateChanged,
+ modifier, &ScatterDataModifier::enableOptimization);
+ QObject::connect(modifier, &ScatterDataModifier::gridEnabledChanged,
+ gridCheckBox, &QCheckBox::setChecked);
+ QObject::connect(itemStyleList, 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);
+
+ QObject::connect(modifier, &ScatterDataModifier::fontChanged, fontList,
+ &QFontComboBox::setCurrentFont);
+
+ itemStyleList->setCurrentIndex(0);
+ optimizationCheckBox->setChecked(true);
+
+ widget->show();
+ return app.exec();
+}
diff --git a/tests/manual/directional/scatterdatamodifier.cpp b/tests/manual/directional/scatterdatamodifier.cpp
new file mode 100644
index 00000000..2746bdf1
--- /dev/null
+++ b/tests/manual/directional/scatterdatamodifier.cpp
@@ -0,0 +1,220 @@
+/******************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module.
+**
+** $QT_BEGIN_LICENSE:COMM$
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** $QT_END_LICENSE$
+**
+******************************************************************************/
+
+#include "scatterdatamodifier.h"
+#include <QtDataVisualization/qscatterdataproxy.h>
+#include <QtDataVisualization/qvalue3daxis.h>
+#include <QtDataVisualization/q3dscene.h>
+#include <QtDataVisualization/q3dcamera.h>
+#include <QtDataVisualization/qscatter3dseries.h>
+#include <QtDataVisualization/q3dtheme.h>
+#include <qmath.h>
+#include <QComboBox>
+
+using namespace QtDataVisualization;
+
+const int numberOfCols = 8;
+const int numberOfRows = 8;
+const float limit = 8.0f;
+const float PI = 3.14159f;
+#define HEDGEHOG
+
+ScatterDataModifier::ScatterDataModifier(Q3DScatter *scatter)
+ : m_graph(scatter),
+ m_fontSize(40.0f),
+ m_style(QAbstract3DSeries::MeshUserDefined),
+ m_smooth(true)
+{
+ m_graph->activeTheme()->setType(Q3DTheme::ThemeEbony);
+ QFont font = m_graph->activeTheme()->font();
+ font.setPointSize(m_fontSize);
+ m_graph->activeTheme()->setFont(font);
+ m_graph->setShadowQuality(QAbstract3DGraph::ShadowQualitySoftLow);
+ m_graph->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPresetFront);
+
+ m_graph->setAxisX(new QValue3DAxis);
+ m_graph->setAxisY(new QValue3DAxis);
+ m_graph->setAxisZ(new QValue3DAxis);
+
+ QScatterDataProxy *proxy = new QScatterDataProxy;
+ QScatter3DSeries *series = new QScatter3DSeries(proxy);
+ series->setItemLabelFormat("@xTitle: @xLabel @yTitle: @yLabel @zTitle: @zLabel");
+ m_graph->addSeries(series);
+
+ QObject::connect(&m_rotationTimer, &QTimer::timeout, this,
+ &ScatterDataModifier::triggerRotation);
+
+ addData();
+}
+
+ScatterDataModifier::~ScatterDataModifier()
+{
+ delete m_graph;
+}
+
+void ScatterDataModifier::addData()
+{
+ // Configure the axes according to the data
+ m_graph->axisX()->setTitle("X");
+ m_graph->axisY()->setTitle("Y");
+ m_graph->axisZ()->setTitle("Z");
+ m_graph->axisX()->setRange(-limit, limit);
+ m_graph->axisY()->setRange(-1.0f, 1.0f);
+ m_graph->axisZ()->setRange(-limit, limit);
+
+ QScatterDataArray *dataArray = new QScatterDataArray;
+ dataArray->resize(numberOfCols * numberOfRows);
+ QScatterDataItem *ptrToDataArray = &dataArray->first();
+
+ float angleStep = 360.0f / float(numberOfCols);
+ float latAngleStep = 100.0f / float(numberOfRows);
+
+ for (float i = 0; i < numberOfRows; i++) {
+ float latAngle = float(i) * latAngleStep + 40.0f;
+ float radius = qSin(latAngle * PI / 180.0f) * limit;
+ float y = qCos(latAngle * PI / 180.0f) * 1.0f;
+#ifdef HEDGEHOG
+ float angleZ = (qAtan((y * limit / 2.0f) / radius) * 180.0f / PI);
+ QQuaternion rotationZ = QQuaternion::fromAxisAndAngle(QVector3D(0.0f, 0.0f, 1.0f), angleZ - 90.0f);
+#endif
+ for (float j = 0; j < numberOfCols; j++) {
+ float angle = float(j) * angleStep;
+ float x = qCos(angle * PI / 180.0f) * radius;
+ float z = qSin(angle * PI / 180.0f) * radius;
+
+ float angleY = (qAtan(z / x) * 180.0f / PI);
+ if (x < 0)
+ angleY = 180.0f + angleY;
+ if (x > 0 && z < 0)
+ angleY = 360.0f + angleY;
+#ifdef HEDGEHOG
+ QQuaternion rotationY = QQuaternion::fromAxisAndAngle(QVector3D(0.0f, 1.0f, 0.0f), angleY);
+ QQuaternion rotation = rotationY * rotationZ;
+#else
+ QQuaternion rotation = QQuaternion::fromAxisAndAngle(QVector3D(0.0f, 1.0f, 0.0f), angleY) *
+ QQuaternion::fromAxisAndAngle(QVector3D(1.0f, 0.0f, 0.0f), -90.0f);
+#endif
+
+ ptrToDataArray->setPosition(QVector3D(x, y, z));
+ ptrToDataArray->setRotation(rotation);
+ ptrToDataArray++;
+ }
+ }
+
+ m_graph->seriesList().at(0)->dataProxy()->resetArray(dataArray);
+}
+
+void ScatterDataModifier::enableOptimization(int enabled)
+{
+ if (enabled)
+ m_graph->setOptimizationHints(QAbstract3DGraph::OptimizationStatic);
+ else
+ m_graph->setOptimizationHints(QAbstract3DGraph::OptimizationDefault);
+}
+
+void ScatterDataModifier::changeStyle(int style)
+{
+ QComboBox *comboBox = qobject_cast<QComboBox *>(sender());
+ if (comboBox) {
+ m_style = QAbstract3DSeries::Mesh(comboBox->itemData(style).toInt());
+ if (m_graph->seriesList().size())
+ m_graph->seriesList().at(0)->setMesh(m_style);
+ }
+}
+
+void ScatterDataModifier::changeTheme(int theme)
+{
+ Q3DTheme *currentTheme = m_graph->activeTheme();
+ currentTheme->setType(Q3DTheme::Theme(theme));
+ emit backgroundEnabledChanged(currentTheme->isBackgroundEnabled());
+ emit gridEnabledChanged(currentTheme->isGridEnabled());
+ emit fontChanged(currentTheme->font());
+}
+
+void ScatterDataModifier::changePresetCamera()
+{
+ static int preset = Q3DCamera::CameraPresetFrontLow;
+
+ m_graph->scene()->activeCamera()->setCameraPreset((Q3DCamera::CameraPreset)preset);
+
+ if (++preset > Q3DCamera::CameraPresetDirectlyBelow)
+ preset = Q3DCamera::CameraPresetFrontLow;
+}
+
+void ScatterDataModifier::changeLabelStyle()
+{
+ m_graph->activeTheme()->setLabelBackgroundEnabled(!m_graph->activeTheme()->isLabelBackgroundEnabled());
+}
+
+void ScatterDataModifier::changeFont(const QFont &font)
+{
+ QFont newFont = font;
+ newFont.setPointSizeF(m_fontSize);
+ m_graph->activeTheme()->setFont(newFont);
+}
+
+void ScatterDataModifier::shadowQualityUpdatedByVisual(QAbstract3DGraph::ShadowQuality sq)
+{
+ int quality = int(sq);
+ emit shadowQualityChanged(quality); // connected to a checkbox in main.cpp
+}
+
+void ScatterDataModifier::triggerRotation()
+{
+ if (m_graph->seriesList().size()) {
+ int selectedIndex = m_graph->seriesList().at(0)->selectedItem();
+ if (selectedIndex != QScatter3DSeries::invalidSelectionIndex()) {
+ static float itemAngle = 0.0f;
+ QScatterDataItem item(*(m_graph->seriesList().at(0)->dataProxy()->itemAt(selectedIndex)));
+ QQuaternion itemRotation = QQuaternion::fromAxisAndAngle(0.0f, 0.0f, 1.0f, itemAngle++);
+ item.setRotation(itemRotation);
+ m_graph->seriesList().at(0)->dataProxy()->setItem(selectedIndex, item);
+ } else {
+ static float seriesAngle = 0.0f;
+ QQuaternion rotation = QQuaternion::fromAxisAndAngle(1.0f, 1.0f, 1.0f, seriesAngle++);
+ m_graph->seriesList().at(0)->setMeshRotation(rotation);
+ }
+ }
+}
+
+void ScatterDataModifier::changeShadowQuality(int quality)
+{
+ QAbstract3DGraph::ShadowQuality sq = QAbstract3DGraph::ShadowQuality(quality);
+ m_graph->setShadowQuality(sq);
+}
+
+void ScatterDataModifier::setBackgroundEnabled(int enabled)
+{
+ m_graph->activeTheme()->setBackgroundEnabled((bool)enabled);
+}
+
+void ScatterDataModifier::setGridEnabled(int enabled)
+{
+ m_graph->activeTheme()->setGridEnabled((bool)enabled);
+}
+
+void ScatterDataModifier::toggleRotation()
+{
+ if (m_rotationTimer.isActive())
+ m_rotationTimer.stop();
+ else
+ m_rotationTimer.start(20);
+}
diff --git a/tests/manual/directional/scatterdatamodifier.h b/tests/manual/directional/scatterdatamodifier.h
new file mode 100644
index 00000000..ca4dc4a3
--- /dev/null
+++ b/tests/manual/directional/scatterdatamodifier.h
@@ -0,0 +1,72 @@
+/******************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module.
+**
+** $QT_BEGIN_LICENSE:COMM$
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** $QT_END_LICENSE$
+**
+******************************************************************************/
+
+#ifndef SCATTERDATAMODIFIER_H
+#define SCATTERDATAMODIFIER_H
+
+#include <QtDataVisualization/q3dscatter.h>
+#include <QtDataVisualization/qabstract3dseries.h>
+#include <QtGui/QFont>
+#include <QtCore/QTimer>
+
+using namespace QtDataVisualization;
+
+class ScatterDataModifier : public QObject
+{
+ Q_OBJECT
+public:
+ explicit ScatterDataModifier(Q3DScatter *scatter);
+ ~ScatterDataModifier();
+
+ void addData();
+ void changeStyle();
+ void changePresetCamera();
+ void changeLabelStyle();
+ void changeFont(const QFont &font);
+ void changeFontSize(int fontsize);
+ void enableOptimization(int enabled);
+ void setBackgroundEnabled(int enabled);
+ void setGridEnabled(int enabled);
+ void toggleRotation();
+ void start();
+
+public Q_SLOTS:
+ void changeStyle(int style);
+ void changeTheme(int theme);
+ void changeShadowQuality(int quality);
+ void shadowQualityUpdatedByVisual(QAbstract3DGraph::ShadowQuality shadowQuality);
+ void triggerRotation();
+
+Q_SIGNALS:
+ void backgroundEnabledChanged(bool enabled);
+ void gridEnabledChanged(bool enabled);
+ void shadowQualityChanged(int quality);
+ void fontChanged(QFont font);
+
+private:
+ Q3DScatter *m_graph;
+ int m_fontSize;
+ QAbstract3DSeries::Mesh m_style;
+ bool m_smooth;
+ QTimer m_rotationTimer;
+};
+
+#endif
diff --git a/tests/manual/galaxy/cumulativedistributor.cpp b/tests/manual/galaxy/cumulativedistributor.cpp
new file mode 100644
index 00000000..eb4b26a0
--- /dev/null
+++ b/tests/manual/galaxy/cumulativedistributor.cpp
@@ -0,0 +1,146 @@
+/******************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module.
+**
+** $QT_BEGIN_LICENSE:COMM$
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** $QT_END_LICENSE$
+**
+******************************************************************************/
+
+/*
+ * Galaxy creation code obtained from http://beltoforion.de/galaxy/galaxy_en.html
+ * Thanks to Ingo Berg, great work.
+ * Licensed under a Creative Commons Attribution 3.0 License
+ * http://creativecommons.org/licenses/by/3.0/
+ */
+
+#include "cumulativedistributor.h"
+
+#include <QDebug>
+
+CumulativeDistributor::CumulativeDistributor()
+ : m_pDistFun(NULL),
+ m_vM1(),
+ m_vY1(),
+ m_vX1(),
+ m_vM2(),
+ m_vY2(),
+ m_vX2()
+{
+}
+
+CumulativeDistributor::~CumulativeDistributor()
+{
+}
+
+void CumulativeDistributor::setupRealistic(qreal I0, qreal k, qreal a,
+ qreal RBulge, qreal min, qreal max,
+ int nSteps)
+{
+ m_fMin = min;
+ m_fMax = max;
+ m_nSteps = nSteps;
+
+ m_I0 = I0;
+ m_k = k;
+ m_a = a;
+ m_RBulge = RBulge;
+
+ m_pDistFun = &CumulativeDistributor::Intensity;
+
+ // build the distribution function
+ buildCDF(m_nSteps);
+}
+
+void CumulativeDistributor::buildCDF(int nSteps)
+{
+ qreal h = (m_fMax - m_fMin) / nSteps;
+ qreal x = 0, y = 0;
+
+ m_vX1.clear();
+ m_vY1.clear();
+ m_vX2.clear();
+ m_vM1.clear();
+ m_vM1.clear();
+
+ // Simpson rule for integration of the distribution function
+ m_vY1.push_back(0.0);
+ m_vX1.push_back(0.0);
+ for (int i = 0; i < nSteps; i += 2) {
+ x = (i + 2) * h;
+ y += h/3 * ((this->*m_pDistFun)(m_fMin + i*h) + 4*(this->*m_pDistFun)(m_fMin + (i+1)*h) + (this->*m_pDistFun)(m_fMin + (i+2)*h) );
+
+ m_vM1.push_back((y - m_vY1.back()) / (2*h));
+ m_vX1.push_back(x);
+ m_vY1.push_back(y);
+ }
+
+ // normieren
+ for (int i = 0; i < m_vM1.size(); i++) {
+ m_vY1[i] /= m_vY1.back();
+ m_vM1[i] /= m_vY1.back();
+ }
+
+ m_vY2.clear();
+ m_vM2.clear();
+ m_vY2.push_back(0.0);
+
+ qreal p = 0;
+ h = 1.0 / nSteps;
+ for (int i = 1, k = 0; i < nSteps; ++i) {
+ p = (qreal)i * h;
+
+ for (; m_vY1[k+1] <= p; ++k) {
+ }
+
+ y = m_vX1[k] + (p - m_vY1[k]) / m_vM1[k];
+
+ m_vM2.push_back( (y - m_vY2.back()) / h);
+ m_vX2.push_back(p);
+ m_vY2.push_back(y);
+ }
+}
+
+qreal CumulativeDistributor::valFromProp(qreal fVal)
+{
+ if (fVal < 0.0 || fVal > 1.0)
+ throw std::runtime_error("out of range");
+
+ qreal h = 1.0 / m_vY2.size();
+
+ int i = int(fVal / h);
+ qreal remainder = fVal - i*h;
+
+ int min = qMin(m_vY2.size(), m_vM2.size());
+ if (i >= min)
+ i = min - 1;
+
+ return (m_vY2[i] + m_vM2[i] * remainder);
+}
+
+qreal CumulativeDistributor::IntensityBulge(qreal R, qreal I0, qreal k)
+{
+ return I0 * exp(-k * pow(R, 0.25));
+}
+
+qreal CumulativeDistributor::IntensityDisc(qreal R, qreal I0, qreal a)
+{
+ return I0 * exp(-R/a);
+}
+
+qreal CumulativeDistributor::Intensity(qreal x)
+{
+ return (x < m_RBulge) ? IntensityBulge(x, m_I0, m_k) : IntensityDisc(x - m_RBulge, IntensityBulge(m_RBulge, m_I0, m_k), m_a);
+}
diff --git a/tests/manual/galaxy/cumulativedistributor.h b/tests/manual/galaxy/cumulativedistributor.h
new file mode 100644
index 00000000..d2dbe5b1
--- /dev/null
+++ b/tests/manual/galaxy/cumulativedistributor.h
@@ -0,0 +1,79 @@
+/******************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module.
+**
+** $QT_BEGIN_LICENSE:COMM$
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** $QT_END_LICENSE$
+**
+******************************************************************************/
+
+/*
+ * Galaxy creation code obtained from http://beltoforion.de/galaxy/galaxy_en.html
+ * Thanks to Ingo Berg, great work.
+ * Licensed under a Creative Commons Attribution 3.0 License
+ * http://creativecommons.org/licenses/by/3.0/
+ */
+
+#ifndef CUMULATIVEDISTRIBUTOR_H
+#define CUMULATIVEDISTRIBUTOR_H
+
+#include <QtCore/qglobal.h>
+#include <QtGui/QVector2D>
+#include <QtCore/QVector>
+
+class CumulativeDistributor
+{
+public:
+ typedef qreal (CumulativeDistributor::*dist_fun_t)(qreal x);
+
+ CumulativeDistributor();
+ virtual ~CumulativeDistributor();
+
+ qreal PropFromVal(qreal fVal);
+ qreal ValFromProp(qreal fVal);
+
+ void setupRealistic(qreal I0, qreal k, qreal a, qreal RBulge, qreal min,
+ qreal max, int nSteps);
+ qreal valFromProp(qreal fVal);
+
+private:
+ dist_fun_t m_pDistFun;
+ qreal m_fMin;
+ qreal m_fMax;
+ qreal m_fWidth;
+ int m_nSteps;
+
+ // parameters for realistic star distribution
+ qreal m_I0;
+ qreal m_k;
+ qreal m_a;
+ qreal m_RBulge;
+
+ QVector<qreal> m_vM1;
+ QVector<qreal> m_vY1;
+ QVector<qreal> m_vX1;
+
+ QVector<qreal> m_vM2;
+ QVector<qreal> m_vY2;
+ QVector<qreal> m_vX2;
+
+ void buildCDF(int nSteps);
+
+ qreal IntensityBulge(qreal R, qreal I0, qreal k);
+ qreal IntensityDisc(qreal R, qreal I0, qreal a);
+ qreal Intensity(qreal x);
+};
+
+#endif // CUMULATIVEDISTRIBUTOR_H
diff --git a/tests/manual/galaxy/galaxy.pro b/tests/manual/galaxy/galaxy.pro
new file mode 100644
index 00000000..0b602e16
--- /dev/null
+++ b/tests/manual/galaxy/galaxy.pro
@@ -0,0 +1,23 @@
+android|ios|winrt {
+ error( "This example is not supported for android, ios, or winrt." )
+}
+
+!include( ../tests.pri ) {
+ error( "Couldn't find the tests.pri file!" )
+}
+
+SOURCES += main.cpp \
+ galaxydata.cpp \
+ star.cpp \
+ cumulativedistributor.cpp
+
+HEADERS += \
+ cumulativedistributor.h \
+ galaxydata.h \
+ star.h
+
+QT += widgets
+
+OTHER_FILES += doc/src/* \
+ doc/images/*
+
diff --git a/tests/manual/galaxy/galaxydata.cpp b/tests/manual/galaxy/galaxydata.cpp
new file mode 100644
index 00000000..33a4d16b
--- /dev/null
+++ b/tests/manual/galaxy/galaxydata.cpp
@@ -0,0 +1,481 @@
+/******************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module.
+**
+** $QT_BEGIN_LICENSE:COMM$
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** $QT_END_LICENSE$
+**
+******************************************************************************/
+
+/*
+ * Galaxy creation code obtained from http://beltoforion.de/galaxy/galaxy_en.html
+ * Thanks to Ingo Berg, great work.
+ * Licensed under a Creative Commons Attribution 3.0 License
+ * http://creativecommons.org/licenses/by/3.0/
+ */
+
+#include "galaxydata.h"
+#include "cumulativedistributor.h"
+#include "star.h"
+#include <QtDataVisualization/qscatterdataproxy.h>
+#include <QtDataVisualization/qvalue3daxis.h>
+#include <QtDataVisualization/q3dscene.h>
+#include <QtDataVisualization/q3dcamera.h>
+#include <QtDataVisualization/qscatter3dseries.h>
+#include <QtDataVisualization/q3dtheme.h>
+#include <QtCore/qmath.h>
+#include <QPainter>
+
+#include <QDebug>
+
+using namespace QtDataVisualization;
+
+static const int numOfStars = 70000;
+static const int numOfDust = numOfStars / 2;
+static const int numOfH2 = 200;
+static const qreal rand_max = qreal(RAND_MAX);
+
+GalaxyData::GalaxyData(Q3DScatter *scatter,
+ qreal rad,
+ qreal radCore,
+ qreal deltaAng,
+ qreal ex1,
+ qreal ex2)
+ : m_graph(scatter),
+ m_pStars(0),
+ m_pDust(0),
+ m_pH2(0),
+ m_radGalaxy(rad),
+ m_radCore(radCore),
+ m_angleOffset(deltaAng),
+ m_elEx1(ex1),
+ m_elEx2(ex2),
+ m_radFarField(m_radGalaxy * 2),
+ m_filtered(false),
+ m_minx(9999.9),
+ m_maxx(-9999.0),
+ m_miny(9999.9),
+ m_maxy(-9999.0)
+{
+ m_graph->activeTheme()->setType(Q3DTheme::ThemeEbony);
+ m_graph->setShadowQuality(QAbstract3DGraph::ShadowQualitySoftLow);
+
+ m_graph->axisX()->setRange(-25000.0f, 25000.0f);
+ m_graph->axisZ()->setRange(-25000.0f, 25000.0f);
+ m_graph->setOptimizationHints(QAbstract3DGraph::OptimizationStatic);
+ m_graph->activeTheme()->setBackgroundColor(QColor(31, 31, 31));
+ m_graph->activeTheme()->setWindowColor(QColor(31, 31, 31));
+ m_graph->activeTheme()->setLabelBackgroundColor(QColor(31, 31, 31));
+ m_graph->activeTheme()->setLabelTextColor(QColor(31, 31, 31));
+
+ QObject::connect(m_graph, &QAbstract3DGraph::currentFpsChanged,
+ this, &GalaxyData::handleFpsChange);
+ m_graph->setMeasureFps(true);
+
+ createSeries();
+ createGalaxy();
+}
+
+GalaxyData::~GalaxyData()
+{
+ delete m_graph;
+ if (m_pStars)
+ delete [] m_pStars;
+ if (m_pDust)
+ delete [] m_pDust;
+ if (m_pH2)
+ delete [] m_pH2;
+}
+
+void GalaxyData::createGalaxy()
+{
+ if (m_pStars)
+ delete [] m_pStars;
+ m_pStars = new Star[numOfStars];
+
+ if (m_pDust)
+ delete [] m_pDust;
+ m_pDust = new Star[numOfDust];
+
+ if (m_pH2)
+ delete [] m_pH2;
+ m_pH2 = new Star[numOfH2 * 2];
+
+
+ m_minx = 9999.9;
+ m_maxx = -9999.0;
+ m_miny = 9999.9;
+ m_maxy = -9999.0;
+
+ // First star is the black hole at the center
+ m_pStars[0].m_a = 0;
+ m_pStars[0].m_b = 0;
+ m_pStars[0].m_angle = 0;
+ m_pStars[0].m_theta = 0;
+ m_pStars[0].m_center = QVector2D(0.0f, 0.0f);
+ m_pStars[0].calcXY();
+
+ // second star is at the edge of the core area
+ m_pStars[1].m_a = m_radCore;
+ m_pStars[1].m_b = m_radCore * getExcentricity(m_radCore);
+ m_pStars[1].m_angle = getAngularOffset(m_radCore);
+ m_pStars[1].m_theta = 0;
+ m_pStars[1].m_center = QVector2D(0.0f, 0.0f);
+ m_pStars[1].calcXY();
+ checkMinMax(m_pStars[1]);
+
+ // third star is at the edge of the disk
+ m_pStars[2].m_a = m_radGalaxy;
+ m_pStars[2].m_b = m_radGalaxy * getExcentricity(m_radGalaxy);
+ m_pStars[2].m_angle = getAngularOffset(m_radGalaxy);
+ m_pStars[2].m_theta = 0;
+ m_pStars[2].m_center = QVector2D(0.0f, 0.0f);
+ m_pStars[2].calcXY();
+ checkMinMax(m_pStars[2]);
+
+ CumulativeDistributor cd;
+ cd.setupRealistic(1.0, // Maximalintensität
+ 0.02, // k (bulge)
+ m_radGalaxy/3.0, // disc skalenlänge
+ m_radCore, // bulge radius
+ 0, // start der intensitätskurve
+ m_radFarField, // ende der intensitätskurve
+ 1000.0); // Anzahl der stützstellen
+
+ for (int i = 3; i < numOfStars; ++i) {
+ qreal rad = cd.valFromProp(qreal(qrand()) / rand_max);
+
+ m_pStars[i].m_a = rad;
+ m_pStars[i].m_b = rad * getExcentricity(rad);
+ m_pStars[i].m_angle = getAngularOffset(rad);
+ m_pStars[i].m_theta = 360.0 * ((double)rand() / RAND_MAX);
+ m_pStars[i].m_center = QVector2D(0.0f, 0.0f);
+ m_pStars[i].calcXY();
+
+ checkMinMax(m_pStars[i]);
+ }
+
+ // Initialize Dust
+ qreal x, y, rad;
+ for (int i = 0; i < numOfDust; ++i)
+ {
+ x = 2.0 * m_radGalaxy * ((double)rand() / RAND_MAX) - m_radGalaxy;
+ y = 2.0 * m_radGalaxy * ((double)rand() / RAND_MAX) - m_radGalaxy;
+ rad = sqrt(x*x + y*y);
+
+ m_pDust[i].m_a = rad;
+ m_pDust[i].m_b = rad * getExcentricity(rad);
+ m_pDust[i].m_angle = getAngularOffset(rad);
+ m_pDust[i].m_theta = 360.0 * ((double)rand() / RAND_MAX);
+ m_pDust[i].m_center = QVector2D(0.0f, 0.0f);
+ m_pDust[i].calcXY();
+
+ checkMinMax(m_pDust[i]);
+ }
+
+ // Initialize H2
+ for (int i = 0; i < numOfH2; ++i)
+ {
+ x = 2*(m_radGalaxy) * ((double)rand() / RAND_MAX) - (m_radGalaxy);
+ y = 2*(m_radGalaxy) * ((double)rand() / RAND_MAX) - (m_radGalaxy);
+ rad = sqrt(x*x + y*y);
+
+ int k1 = 2*i;
+ m_pH2[k1].m_a = rad;
+ m_pH2[k1].m_b = rad * getExcentricity(rad);
+ m_pH2[k1].m_angle = getAngularOffset(rad);
+ m_pH2[k1].m_theta = 360.0 * ((double)rand() / RAND_MAX);
+ m_pH2[k1].m_center = QVector2D(0.0f, 0.0f);
+ m_pH2[k1].calcXY();
+
+ int k2 = 2*i + 1;
+ m_pH2[k2].m_a = rad + 1000.0;
+ m_pH2[k2].m_b = rad * getExcentricity(rad);
+ m_pH2[k2].m_angle = m_pH2[k1].m_angle;
+ m_pH2[k2].m_theta = m_pH2[k1].m_theta;
+ m_pH2[k2].m_center = m_pH2[k1].m_center;
+ m_pH2[k2].calcXY();
+ }
+
+ qreal max = qMax(m_maxx, m_maxy);
+ qreal min = -qMin(m_minx, m_miny);
+ max = qMax(min, max);
+ m_range = int((max + 500.0) / 1000.0) * 1000;
+ m_graph->axisX()->setRange(-float(m_range), float(m_range));
+ m_graph->axisZ()->setRange(-float(m_range), float(m_range));
+
+ if (!m_filtered)
+ createNormalDataView();
+ else
+ createFilteredView();
+}
+
+void GalaxyData::createSeries()
+{
+ QScatterDataProxy *proxyNormal = new QScatterDataProxy;
+ m_normalSeries = new QScatter3DSeries(proxyNormal);
+ m_normalSeries->setMesh(QAbstract3DSeries::MeshPoint);
+ m_graph->addSeries(m_normalSeries);
+
+ QScatterDataProxy *proxyDust = new QScatterDataProxy;
+ m_dustSeries = new QScatter3DSeries(proxyDust);
+ m_dustSeries->setMesh(QAbstract3DSeries::MeshPoint);
+ m_graph->addSeries(m_dustSeries);
+
+ QScatterDataProxy *proxyH2 = new QScatterDataProxy;
+ m_H2Series = new QScatter3DSeries(proxyH2);
+ m_H2Series->setMesh(QAbstract3DSeries::MeshPoint);
+ m_graph->addSeries(m_H2Series);
+
+ QScatterDataProxy *proxyFiltered = new QScatterDataProxy;
+ m_filteredSeries = new QScatter3DSeries(proxyFiltered);
+ m_filteredSeries->setMesh(QAbstract3DSeries::MeshCube);
+ m_graph->addSeries(m_filteredSeries);
+
+}
+
+void GalaxyData::createNormalDataView()
+{
+ QScatterDataArray *dataArray = new QScatterDataArray;
+ dataArray->resize(numOfStars);
+ QScatterDataItem *ptrToDataArray = &dataArray->first();
+
+ for (uint i = 0; i < numOfStars; i++) {
+ ptrToDataArray->setPosition(QVector3D(m_pStars[i].m_pos.x(),
+ 0.0f,
+ m_pStars[i].m_pos.y()));
+ ptrToDataArray++;
+ }
+
+ m_normalSeries->dataProxy()->resetArray(dataArray);
+ m_normalSeries->setMesh(QAbstract3DSeries::MeshPoint);
+ m_normalSeries->setBaseColor(Qt::white);
+
+ dataArray = new QScatterDataArray;
+ dataArray->resize(numOfDust);
+ ptrToDataArray = &dataArray->first();
+
+ for (uint i = 0; i < numOfDust; i++) {
+ ptrToDataArray->setPosition(QVector3D(m_pDust[i].m_pos.x(),
+ 0.0f,
+ m_pDust[i].m_pos.y()));
+ ptrToDataArray++;
+ }
+
+ m_dustSeries->dataProxy()->resetArray(dataArray);
+ m_dustSeries->setMesh(QAbstract3DSeries::MeshPoint);
+ m_dustSeries->setBaseColor(QColor(131, 111, 255));
+
+ dataArray = new QScatterDataArray;
+ dataArray->resize(numOfDust);
+ ptrToDataArray = &dataArray->first();
+
+ uint H2Count = numOfH2 * 2;
+ for (uint i = 0; i < H2Count; i++) {
+ ptrToDataArray->setPosition(QVector3D(m_pH2[i].m_pos.x(),
+ 0.0f,
+ m_pH2[i].m_pos.y()));
+ ptrToDataArray++;
+ }
+
+ m_H2Series->dataProxy()->resetArray(dataArray);
+ m_H2Series->setMesh(QAbstract3DSeries::MeshPoint);
+ m_H2Series->setBaseColor(Qt::red);
+}
+
+void GalaxyData::createFilteredView()
+{
+ int steps = (m_range / 1000) * 2;
+ int tableSize = steps * steps;
+ int *table = new int[tableSize];
+ for (int i = 0; i < tableSize; i++)
+ table[i] = 0;
+ qreal add = qreal(m_range);
+ int max = 0;
+
+ for (uint i = 0; i < numOfStars; i++) {
+ int x = int(m_pStars[i].m_pos.x() + add) / 1000;
+ int y = int(m_pStars[i].m_pos.y() + add) / 1000;
+ table[y * steps + x] = table[y * steps + x] + 1;
+
+ if (max < table[y * steps + x])
+ max = table[y * steps + x];
+ }
+
+ // Count how many cells have data
+ int nActiveCell = 0;
+ for (int i = 0; i < tableSize; i++) {
+ if (table[i])
+ nActiveCell++;
+ }
+
+
+ QScatterDataArray *dataArray = new QScatterDataArray;
+ dataArray->resize(nActiveCell);
+ QScatterDataItem *ptrToDataArray = &dataArray->first();
+
+ for (int y = 0; y < steps; y++) {
+ for (int x = 0; x < steps; x++) {
+ if (table[y * steps + x]) {
+ ptrToDataArray->setPosition(QVector3D(float(x) * 1000.0f - add + 500.0f,
+ float(table[y * steps + x]),
+ float(y) * 1000.0f - add + 500.0f));
+ ptrToDataArray++;
+ }
+ }
+ }
+
+ m_filteredSeries->dataProxy()->resetArray(dataArray);
+ m_filteredSeries->setMesh(QAbstract3DSeries::MeshCube);
+ m_filteredSeries->setItemSize(0.1f);
+
+ m_graph->axisY()->setRange(0.0f, float(max + 1));
+
+ qDebug() << "max = " << max;
+}
+
+void GalaxyData::checkMinMax(const Star &star)
+{
+ if (star.m_pos.x() < m_minx)
+ m_minx = star.m_pos.x();
+ if (star.m_pos.x() > m_maxx)
+ m_maxx = star.m_pos.x();
+ if (star.m_pos.y() < m_miny)
+ m_miny = star.m_pos.y();
+ if (star.m_pos.y() > m_maxy)
+ m_maxy = star.m_pos.y();
+}
+
+qreal GalaxyData::getExcentricity(qreal r) const
+{
+ if (r < m_radCore)
+ {
+ // Core region of the galaxy. Innermost part is round
+ // excentricity increasing linear to the border of the core.
+ return 1 + (r / m_radCore) * (m_elEx1-1);
+ } else if (r > m_radCore && r <= m_radGalaxy) {
+ return m_elEx1 + (r - m_radCore) / (m_radGalaxy - m_radCore) * (m_elEx2 - m_elEx1);
+ } else if (r > m_radGalaxy && r < m_radFarField) {
+ // excentricity is slowly reduced to 1.
+ return m_elEx2 + (r - m_radGalaxy) / (m_radFarField - m_radGalaxy) * (1 - m_elEx2);
+ } else {
+ return 1.0;
+ }
+}
+
+qreal GalaxyData::getAngularOffset(qreal rad) const
+{
+ return rad * m_angleOffset;
+}
+
+void GalaxyData::radiusGalaxyChanged(int value)
+{
+ m_radGalaxy = qreal(value);
+ createGalaxy();
+}
+
+void GalaxyData::radiusCoreChanged(int value)
+{
+ m_radCore = qreal(value);
+ createGalaxy();
+}
+
+void GalaxyData::angleOffsetChanged(int value)
+{
+ m_angleOffset = qreal(value) / 100000.0;
+ createGalaxy();
+}
+
+void GalaxyData::eccentricityInnerChanged(int value)
+{
+ m_elEx1 = qreal(value) / 100.0;
+ createGalaxy();
+}
+
+void GalaxyData::eccentricityOuterChanged(int value)
+{
+ m_elEx2 = qreal(value) / 100.0;
+ createGalaxy();
+}
+
+void GalaxyData::setFilteredEnabled(bool enabled)
+{
+ m_filtered = enabled;
+ if (enabled) {
+ QLinearGradient gr(0, 0, 1, 100);
+ gr.setColorAt(0.0, Qt::white);
+ gr.setColorAt(0.04, Qt::green);
+ gr.setColorAt(0.1, Qt::darkGreen);
+ gr.setColorAt(1.0, Qt::red);
+
+ m_filteredSeries->setBaseGradient(gr);
+ m_filteredSeries->setColorStyle(Q3DTheme::ColorStyleRangeGradient);
+
+ m_normalSeries->setVisible(false);
+
+ createFilteredView();
+
+ m_filteredSeries->setVisible(true);
+ } else {
+ m_normalSeries->setColorStyle(Q3DTheme::ColorStyleUniform);
+ m_graph->axisY()->setRange(-1.0f, 1.0f);
+ m_normalSeries->setItemSize(0.0f);
+
+ m_filteredSeries->setVisible(false);
+
+ createNormalDataView();
+
+ m_normalSeries->setVisible(true);
+ }
+}
+
+
+void GalaxyData::setStaticEnabled(bool enabled)
+{
+ if (enabled)
+ m_graph->setOptimizationHints(QAbstract3DGraph::OptimizationStatic);
+ else
+ m_graph->setOptimizationHints(QAbstract3DGraph::OptimizationDefault);
+}
+
+void GalaxyData::setStarsVisible(bool enabled)
+{
+ m_normalSeries->setVisible(enabled);
+}
+
+void GalaxyData::setDustVisible(bool enabled)
+{
+ m_dustSeries->setVisible(enabled);
+}
+
+void GalaxyData::setH2Visible(bool enabled)
+{
+ m_H2Series->setVisible(enabled);
+}
+
+void GalaxyData::resetValues()
+{
+ m_radiusGalaxySlider->setValue(15000);
+ m_radiusCoreSlider->setValue(4000);
+ m_angleOffsetSlider->setValue(40);
+ m_eccentricityInnerSlider->setValue(90);
+ m_eccentricityOuterSlider->setValue(90);
+}
+
+void GalaxyData::handleFpsChange(qreal fps)
+{
+ static const QString fpsPrefix(QStringLiteral("FPS: "));
+ m_fpsLabel->setText(fpsPrefix + QString::number(qRound(fps)));
+}
diff --git a/tests/manual/galaxy/galaxydata.h b/tests/manual/galaxy/galaxydata.h
new file mode 100644
index 00000000..9f6f14cf
--- /dev/null
+++ b/tests/manual/galaxy/galaxydata.h
@@ -0,0 +1,117 @@
+/******************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module.
+**
+** $QT_BEGIN_LICENSE:COMM$
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** $QT_END_LICENSE$
+**
+******************************************************************************/
+
+#ifndef SCATTERDATAMODIFIER_H
+#define SCATTERDATAMODIFIER_H
+
+#include "star.h"
+
+#include <QtDataVisualization/q3dscatter.h>
+#include <QtDataVisualization/qabstract3dseries.h>
+#include <QtGui/QFont>
+#include <QtWidgets/QSlider>
+#include <QtWidgets/QLabel>
+
+using namespace QtDataVisualization;
+
+class GalaxyData : public QObject
+{
+ Q_OBJECT
+public:
+ explicit GalaxyData(Q3DScatter *scatter,
+ qreal rad = 13000,
+ qreal radCore = 4000.0,
+ qreal deltaAng = 0.0004,
+ qreal ex1 = 0.9,
+ qreal ex2 = 0.9);
+ ~GalaxyData();
+
+ qreal getExcentricity(qreal r) const;
+ qreal getAngularOffset(qreal rad) const;
+
+ void radiusGalaxyChanged(int value);
+ void radiusCoreChanged(int value);
+ void angleOffsetChanged(int value);
+ void eccentricityInnerChanged(int value);
+ void eccentricityOuterChanged(int value);
+ void resetValues();
+ void setFilteredEnabled(bool enabled);
+ void setStaticEnabled(bool enabled);
+ void setStarsVisible(bool enabled);
+ void setDustVisible(bool enabled);
+ void setH2Visible(bool enabled);
+ inline void setSliders(QSlider *rg,
+ QSlider *rc,
+ QSlider *ao,
+ QSlider *ei,
+ QSlider *eo) {
+ m_radiusGalaxySlider = rg;
+ m_radiusCoreSlider = rc;
+ m_angleOffsetSlider = ao;
+ m_eccentricityInnerSlider = ei;
+ m_eccentricityOuterSlider = eo;
+ }
+ void setFpsLabel(QLabel *fpsLabel) { m_fpsLabel = fpsLabel; }
+ void handleFpsChange(qreal fps);
+
+private:
+ void createGalaxy();
+ void checkMinMax(const Star &star);
+ void createNormalDataView();
+ void createFilteredView();
+ void createSeries();
+ qreal value;
+
+private:
+ Q3DScatter *m_graph;
+ QScatter3DSeries *m_normalSeries;
+ QScatter3DSeries *m_dustSeries;
+ QScatter3DSeries *m_H2Series;
+ QScatter3DSeries *m_filteredSeries;
+ Star *m_pStars;
+ Star *m_pDust;
+ Star *m_pH2;
+
+ qreal m_elEx1; // Excentricity of the innermost ellipse
+ qreal m_elEx2; // Excentricity of the outermost ellipse
+
+ qreal m_angleOffset; // Angular offset per parsec
+
+ qreal m_radCore; // Radius of the inner core
+ qreal m_radGalaxy; // Radius of the galaxy
+ qreal m_radFarField; // The radius after which all density waves must have circular shape
+
+ QSlider *m_radiusGalaxySlider;
+ QSlider *m_radiusCoreSlider;
+ QSlider *m_angleOffsetSlider;
+ QSlider *m_eccentricityInnerSlider;
+ QSlider *m_eccentricityOuterSlider;
+ QLabel *m_fpsLabel;
+
+ qreal m_minx;
+ qreal m_maxx;
+ qreal m_miny;
+ qreal m_maxy;
+ int m_range;
+ bool m_filtered;
+};
+
+#endif
diff --git a/tests/manual/galaxy/main.cpp b/tests/manual/galaxy/main.cpp
new file mode 100644
index 00000000..ab58e1e9
--- /dev/null
+++ b/tests/manual/galaxy/main.cpp
@@ -0,0 +1,163 @@
+/******************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module.
+**
+** $QT_BEGIN_LICENSE:COMM$
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** $QT_END_LICENSE$
+**
+******************************************************************************/
+
+#include "galaxydata.h"
+
+#include <QtWidgets/QApplication>
+#include <QtWidgets/QWidget>
+#include <QtWidgets/QHBoxLayout>
+#include <QtWidgets/QVBoxLayout>
+#include <QtWidgets/QPushButton>
+#include <QtWidgets/QCheckBox>
+#include <QtWidgets/QComboBox>
+#include <QtWidgets/QFontComboBox>
+#include <QtWidgets/QLabel>
+#include <QtGui/QScreen>
+#include <QtGui/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);
+
+ QWidget *widget = new QWidget;
+ QHBoxLayout *hLayout = new QHBoxLayout(widget);
+ QVBoxLayout *vLayout = new QVBoxLayout();
+ hLayout->addWidget(container, 1);
+ hLayout->addLayout(vLayout);
+ vLayout->setAlignment(Qt::AlignTop);
+
+ widget->setWindowTitle(QStringLiteral("A Galaxy"));
+
+ QSlider *radiusGalaxySlider = new QSlider(Qt::Horizontal, widget);
+ radiusGalaxySlider->setMinimum(1000);
+ radiusGalaxySlider->setMaximum(40000);
+ radiusGalaxySlider->setValue(15000);
+ radiusGalaxySlider->setEnabled(true);
+
+ QSlider *radiusCoreSlider = new QSlider(Qt::Horizontal, widget);
+ radiusCoreSlider->setMinimum(1000);
+ radiusCoreSlider->setMaximum(30000);
+ radiusCoreSlider->setValue(4000);
+ radiusCoreSlider->setEnabled(true);
+
+ QSlider *angleOffsetSlider = new QSlider(Qt::Horizontal, widget);
+ angleOffsetSlider->setMinimum(10);
+ angleOffsetSlider->setMaximum(70);
+ angleOffsetSlider->setValue(40);
+ angleOffsetSlider->setEnabled(true);
+
+ QSlider *eccentricityInnerSlider = new QSlider(Qt::Horizontal, widget);
+ eccentricityInnerSlider->setMinimum(10);
+ eccentricityInnerSlider->setMaximum(200);
+ eccentricityInnerSlider->setValue(90);
+ eccentricityInnerSlider->setEnabled(true);
+
+ QSlider *eccentricityOuterSlider = new QSlider(Qt::Horizontal, widget);
+ eccentricityOuterSlider->setMinimum(10);
+ eccentricityOuterSlider->setMaximum(200);
+ eccentricityOuterSlider->setValue(90);
+ eccentricityOuterSlider->setEnabled(true);
+
+ QCheckBox *staticCheckBox = new QCheckBox(widget);
+ staticCheckBox->setText(QStringLiteral("Static"));
+ staticCheckBox->setChecked(false);
+
+ QCheckBox *starsCheckBox = new QCheckBox(widget);
+ starsCheckBox->setText(QStringLiteral("Stars"));
+ starsCheckBox->setChecked(true);
+
+ QCheckBox *dustCheckBox = new QCheckBox(widget);
+ dustCheckBox->setText(QStringLiteral("Dust"));
+ dustCheckBox->setChecked(true);
+
+ QCheckBox *H2CheckBox = new QCheckBox(widget);
+ H2CheckBox->setText(QStringLiteral("H2"));
+ H2CheckBox->setChecked(true);
+
+ QPushButton *resetButton = new QPushButton(widget);
+ resetButton->setText(QStringLiteral("Reset values"));
+
+ QCheckBox *filteredCheckBox = new QCheckBox(widget);
+ filteredCheckBox->setText(QStringLiteral("Filtered"));
+ filteredCheckBox->setChecked(false);
+
+ QLabel *fpsLabel = new QLabel(QStringLiteral(""));
+
+ vLayout->addWidget(new QLabel(QStringLiteral("Galaxy radius")));
+ vLayout->addWidget(radiusGalaxySlider);
+ vLayout->addWidget(new QLabel(QStringLiteral("Core radius")));
+ vLayout->addWidget(radiusCoreSlider);
+ vLayout->addWidget(new QLabel(QStringLiteral("Angle offset")));
+ vLayout->addWidget(angleOffsetSlider);
+ vLayout->addWidget(new QLabel(QStringLiteral("Eccentricity inner")));
+ vLayout->addWidget(eccentricityInnerSlider);
+ vLayout->addWidget(new QLabel(QStringLiteral("Eccentricity outer")));
+ vLayout->addWidget(eccentricityOuterSlider);
+ vLayout->addWidget(staticCheckBox);
+ vLayout->addWidget(starsCheckBox);
+ vLayout->addWidget(dustCheckBox);
+ vLayout->addWidget(H2CheckBox);
+ vLayout->addWidget(resetButton);
+ vLayout->addWidget(filteredCheckBox);
+ vLayout->addWidget(fpsLabel);
+
+ GalaxyData *modifier = new GalaxyData(graph);
+
+ QObject::connect(radiusGalaxySlider, &QSlider::valueChanged,
+ modifier, &GalaxyData::radiusGalaxyChanged);
+ QObject::connect(radiusCoreSlider, &QSlider::valueChanged,
+ modifier, &GalaxyData::radiusCoreChanged);
+ QObject::connect(angleOffsetSlider, &QSlider::valueChanged,
+ modifier, &GalaxyData::angleOffsetChanged);
+ QObject::connect(eccentricityInnerSlider, &QSlider::valueChanged,
+ modifier, &GalaxyData::eccentricityInnerChanged);
+ QObject::connect(eccentricityOuterSlider, &QSlider::valueChanged,
+ modifier, &GalaxyData::eccentricityOuterChanged);
+ QObject::connect(resetButton, &QPushButton::clicked,
+ modifier, &GalaxyData::resetValues);
+ QObject::connect(filteredCheckBox, &QCheckBox::stateChanged,
+ modifier, &GalaxyData::setFilteredEnabled);
+ QObject::connect(staticCheckBox, &QCheckBox::stateChanged,
+ modifier, &GalaxyData::setStaticEnabled);
+ QObject::connect(starsCheckBox, &QCheckBox::stateChanged,
+ modifier, &GalaxyData::setStarsVisible);
+ QObject::connect(dustCheckBox, &QCheckBox::stateChanged,
+ modifier, &GalaxyData::setDustVisible);
+ QObject::connect(H2CheckBox, &QCheckBox::stateChanged,
+ modifier, &GalaxyData::setH2Visible);
+
+ modifier->setSliders(radiusGalaxySlider, radiusCoreSlider, angleOffsetSlider,
+ eccentricityInnerSlider, eccentricityOuterSlider);
+ modifier->setFpsLabel(fpsLabel);
+
+ widget->show();
+ return app.exec();
+}
diff --git a/tests/manual/galaxy/star.cpp b/tests/manual/galaxy/star.cpp
new file mode 100644
index 00000000..3a7db28a
--- /dev/null
+++ b/tests/manual/galaxy/star.cpp
@@ -0,0 +1,54 @@
+/******************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module.
+**
+** $QT_BEGIN_LICENSE:COMM$
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** $QT_END_LICENSE$
+**
+******************************************************************************/
+
+#include "star.h"
+
+#include <QtCore/qmath.h>
+
+static const double DEG_TO_RAD = M_PI / 180.0;
+
+Star::Star()
+ : m_theta(0),
+ m_a(0),
+ m_b(0),
+ m_center(QVector2D(0.0f, 0.0f))
+{
+}
+
+const void Star::calcXY()
+{
+ qreal &a = m_a;
+ qreal &b = m_b;
+ qreal &theta = m_theta;
+ const QVector2D &p = m_center;
+
+ qreal beta = -m_angle;
+ qreal alpha = theta * DEG_TO_RAD;
+
+ // temporaries to save cpu time
+ qreal cosalpha = qCos(alpha);
+ qreal sinalpha = qSin(alpha);
+ qreal cosbeta = qCos(beta);
+ qreal sinbeta = qSin(beta);
+
+ m_pos = QVector2D(p.x() + (a * cosalpha * cosbeta - b * sinalpha * sinbeta),
+ p.y() + (a * cosalpha * sinbeta + b * sinalpha * cosbeta));
+}
diff --git a/tests/manual/galaxy/star.h b/tests/manual/galaxy/star.h
new file mode 100644
index 00000000..848ad9c0
--- /dev/null
+++ b/tests/manual/galaxy/star.h
@@ -0,0 +1,46 @@
+/******************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module.
+**
+** $QT_BEGIN_LICENSE:COMM$
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** $QT_END_LICENSE$
+**
+******************************************************************************/
+
+#ifndef STAR_H
+#define STAR_H
+
+#include <QtCore/qglobal.h>
+#include <QtGui/QVector2D>
+
+class Star
+{
+public:
+ Star();
+ const void calcXY();
+
+ qreal m_theta; // position auf der ellipse
+// qreal m_velTheta; // angular velocity
+ qreal m_angle; // Schräglage der Ellipse
+ qreal m_a; // kleine halbachse
+ qreal m_b; // große halbachse
+// qreal m_temp; // star temperature
+// qreal m_mag; // brightness;
+ QVector2D m_center; // center of the elliptical orbit
+// QVector2D m_vel; // Current velocity (calculated)
+ QVector2D m_pos; // current position in kartesion koordinates
+};
+
+#endif // STAR_H
diff --git a/tests/manual/itemmodeltest/itemmodeltest.pro b/tests/manual/itemmodeltest/itemmodeltest.pro
new file mode 100644
index 00000000..47f12915
--- /dev/null
+++ b/tests/manual/itemmodeltest/itemmodeltest.pro
@@ -0,0 +1,7 @@
+!include( ../tests.pri ) {
+ error( "Couldn't find the tests.pri file!" )
+}
+
+SOURCES += main.cpp
+
+QT += widgets
diff --git a/tests/manual/itemmodeltest/main.cpp b/tests/manual/itemmodeltest/main.cpp
new file mode 100644
index 00000000..a3a5f771
--- /dev/null
+++ b/tests/manual/itemmodeltest/main.cpp
@@ -0,0 +1,318 @@
+/******************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the Qt Data Visualization module.
+**
+** $QT_BEGIN_LICENSE:COMM$
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** $QT_END_LICENSE$
+**
+******************************************************************************/
+
+#include <QtDataVisualization/q3dbars.h>
+#include <QtDataVisualization/q3dsurface.h>
+#include <QtDataVisualization/qcategory3daxis.h>
+#include <QtDataVisualization/qitemmodelbardataproxy.h>
+#include <QtDataVisualization/qitemmodelsurfacedataproxy.h>
+#include <QtDataVisualization/qvalue3daxis.h>
+#include <QtDataVisualization/q3dscene.h>
+#include <QtDataVisualization/q3dcamera.h>
+#include <QtDataVisualization/qbar3dseries.h>
+#include <QtDataVisualization/q3dtheme.h>
+
+#include <QtWidgets/QApplication>
+#include <QtWidgets/QVBoxLayout>
+#include <QtWidgets/QTableWidget>
+#include <QtGui/QScreen>
+#include <QtCore/QTimer>
+#include <QtCore/QDebug>
+#include <QtWidgets/QHeaderView>
+#include <QtWidgets/QPushButton>
+
+#define USE_STATIC_DATA
+
+using namespace QtDataVisualization;
+
+class GraphDataGenerator : public QObject
+{
+public:
+ explicit GraphDataGenerator(Q3DBars *bargraph, Q3DSurface * surfaceGraph,
+ QTableWidget *tableWidget);
+ ~GraphDataGenerator();
+
+ void setupModel();
+ void addRow();
+ void start();
+ void selectFromTable(const QPoint &selection);
+ void selectedFromTable(int currentRow, int currentColumn, int previousRow, int previousColumn);
+ void fixTableSize();
+ void changeSelectedButtonClicked();
+
+private:
+ Q3DBars *m_barGraph;
+ Q3DSurface *m_surfaceGraph;
+ 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, Q3DSurface * surfaceGraph,
+ QTableWidget *tableWidget)
+ : m_barGraph(bargraph),
+ m_surfaceGraph(surfaceGraph),
+ 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 them
+ m_barGraph->setBarThickness(1.0f);
+ m_barGraph->setBarSpacing(QSizeF(0.2, 0.2));
+
+#ifndef USE_STATIC_DATA
+ // Set up sample space; make it as deep as it's wide
+ m_barGraph->rowAxis()->setRange(0, m_rowCount);
+ m_barGraph->columnAxis()->setRange(0, m_columnCount);
+ m_tableWidget->setColumnCount(m_columnCount);
+
+ // Set selection mode to full
+ m_barGraph->setSelectionMode(QAbstract3DGraph::SelectionItemRowAndColumn);
+
+ // Hide axis labels by explicitly setting one empty string as label list
+ m_barGraph->rowAxis()->setLabels(QStringList(QString()));
+ m_barGraph->columnAxis()->setLabels(QStringList(QString()));
+
+ m_barGraph->seriesList().at(0)->setItemLabelFormat(QStringLiteral("@valueLabel"));
+#else
+ // Set selection mode to slice row
+ m_barGraph->setSelectionMode(
+ QAbstract3DGraph::SelectionItemAndRow | QAbstract3DGraph::SelectionSlice);
+ m_surfaceGraph->setSelectionMode(
+ QAbstract3DGraph::SelectionItemAndRow | QAbstract3DGraph::SelectionSlice);
+#endif
+}
+
+GraphDataGenerator::~GraphDataGenerator()
+{
+ if (m_dataTimer) {
+ m_dataTimer->stop();
+ delete m_dataTimer;
+ }
+ delete m_barGraph;
+ delete m_surfaceGraph;
+}
+
+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
+ 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);
+#endif
+}
+
+void GraphDataGenerator::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
+ const char *hours[5][7] =
+ // Mon Tue Wed Thu Fri Sat Sun
+ {{"9/10/2.0/30", "9/11/1.0/30", "9/12/3.0/30", "9/13/0.2/30", "9/14/1.0/30", "9/15/5.0/30", "9/16/10.0/30"}, // week 1
+ {"8/10/0.5/45", "8/11/1.0/45", "8/12/3.0/45", "8/13/1.0/45", "8/14/2.0/45", "8/15/2.0/45", "8/16/3.0/45"}, // week 2
+ {"7/10/1.0/60", "7/11/1.0/60", "7/12/2.0/60", "7/13/1.0/60", "7/14/4.0/60", "7/15/4.0/60", "7/16/4.0/60"}, // week 3
+ {"6/10/0.0/75", "6/11/1.0/75", "6/12/0.0/75", "6/13/0.0/75", "6/14/2.0/75", "6/15/2.0/75", "6/16/0.3/75"}, // week 4
+ {"5/10/3.0/90", "5/11/3.0/90", "5/12/6.0/90", "5/13/2.0/90", "5/14/2.0/90", "5/15/1.0/90", "5/16/1.0/90"}}; // week 5
+
+ // Add labels
+ m_barGraph->rowAxis()->setTitle("Week of year");
+ m_barGraph->columnAxis()->setTitle("Day of week");
+ m_barGraph->valueAxis()->setTitle("Hours spent on the Internet");
+ m_barGraph->valueAxis()->setLabelFormat("%.1f h");
+
+ m_surfaceGraph->axisZ()->setTitle("Week of year");
+ m_surfaceGraph->axisX()->setTitle("Day of week");
+ m_surfaceGraph->axisY()->setTitle("Hours spent on the Internet");
+ m_surfaceGraph->axisY()->setLabelFormat("%.1f h");
+
+ 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);
+
+ 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]);
+ }
+ }
+}
+
+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,
+ ((float)i / (float)m_columnCount) / 2.0f
+ + (float)(rand() % 30) / 100.0f);
+ }
+ m_tableWidget->resizeColumnsToContents();
+}
+
+void GraphDataGenerator::selectFromTable(const QPoint &selection)
+{
+ m_tableWidget->setFocus();
+ m_tableWidget->setCurrentCell(selection.x(), selection.y());
+}
+
+void GraphDataGenerator::selectedFromTable(int currentRow, int currentColumn,
+ int previousRow, int previousColumn)
+{
+ Q_UNUSED(previousRow)
+ Q_UNUSED(previousColumn)
+ m_barGraph->seriesList().at(0)->setSelectedBar(QPoint(currentRow, currentColumn));
+ m_surfaceGraph->seriesList().at(0)->setSelectedPoint(QPoint(currentRow, currentColumn));
+}
+
+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);
+}
+
+void GraphDataGenerator::changeSelectedButtonClicked()
+{
+ // Change all selected cells to a random value 1-10
+ QVariant value = QVariant::fromValue(float((rand() % 10) + 1));
+ QList<QTableWidgetItem *> selectedItems = m_tableWidget->selectedItems();
+ foreach (QTableWidgetItem *item, selectedItems) {
+ QString oldData = item->data(Qt::DisplayRole).toString();
+ item->setData(Qt::DisplayRole,
+ oldData.left(5)
+ .append(QString::number(value.toReal()))
+ .append("/")
+ .append(QString::number(value.toReal() * 10)));
+ }
+}
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+ Q3DBars *barGraph = new Q3DBars();
+ Q3DSurface *surfaceGraph = new Q3DSurface();
+ QWidget *barContainer = QWidget::createWindowContainer(barGraph);
+ QWidget *surfaceContainer = QWidget::createWindowContainer(surfaceGraph);
+
+ barContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ barContainer->setFocusPolicy(Qt::StrongFocus);
+ surfaceContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ surfaceContainer->setFocusPolicy(Qt::StrongFocus);
+
+ QWidget widget;
+ QVBoxLayout *mainLayout = new QVBoxLayout(&widget);
+ QHBoxLayout *graphLayout = new QHBoxLayout();
+ QVBoxLayout *buttonLayout = new QVBoxLayout();
+ QHBoxLayout *bottomLayout = new QHBoxLayout();
+ QTableWidget *tableWidget = new QTableWidget(&widget);
+ QPushButton *changeSelectedButton = new QPushButton(&widget);
+ changeSelectedButton->setText(QStringLiteral("Change Selected"));
+
+ buttonLayout->addWidget(changeSelectedButton);
+ graphLayout->addWidget(barContainer);
+ graphLayout->addWidget(surfaceContainer);
+ bottomLayout->addLayout(buttonLayout);
+ bottomLayout->addWidget(tableWidget);
+ mainLayout->addLayout(graphLayout);
+ mainLayout->addLayout(bottomLayout);
+
+ tableWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
+ tableWidget->setAlternatingRowColors(true);
+ widget.setWindowTitle(QStringLiteral("Hours spent on the Internet"));
+
+ // Since we are dealing with QTableWidget, the model will already have data sorted properly
+ // into rows and columns, so we simply set useModelCategories property to true to utilize this.
+ QItemModelBarDataProxy *barProxy = new QItemModelBarDataProxy(tableWidget->model());
+ QItemModelSurfaceDataProxy *surfaceProxy = new QItemModelSurfaceDataProxy(tableWidget->model());
+ barProxy->setUseModelCategories(true);
+ surfaceProxy->setUseModelCategories(true);
+ barProxy->setRotationRole(tableWidget->model()->roleNames().value(Qt::DisplayRole));
+ barProxy->setValueRolePattern(QRegExp(QStringLiteral("^(\\d*)(\\/)(\\d*)\\/(\\d*[\\.\\,]?\\d*)\\/\\d*[\\.\\,]?\\d*$")));
+ barProxy->setRotationRolePattern(QRegExp(QStringLiteral("^(\\d*)(\\/)\\d*\\/\\d*([\\.\\,]?)\\d*(\\/)(\\d*[\\.\\,]?\\d*)$")));
+ barProxy->setValueRoleReplace(QStringLiteral("\\4"));
+ barProxy->setRotationRoleReplace(QStringLiteral("\\5"));
+ surfaceProxy->setXPosRole(tableWidget->model()->roleNames().value(Qt::DisplayRole));
+ surfaceProxy->setZPosRole(tableWidget->model()->roleNames().value(Qt::DisplayRole));
+ surfaceProxy->setXPosRolePattern(QRegExp(QStringLiteral("^(\\d*)\\/(\\d*)\\/\\d*[\\.\\,]?\\d*\\/\\d*[\\.\\,]?\\d*$")));
+ surfaceProxy->setXPosRoleReplace(QStringLiteral("\\2"));
+ surfaceProxy->setYPosRolePattern(QRegExp(QStringLiteral("^\\d*(\\/)(\\d*)\\/(\\d*[\\.\\,]?\\d*)\\/\\d*[\\.\\,]?\\d*$")));
+ surfaceProxy->setYPosRoleReplace(QStringLiteral("\\3"));
+ surfaceProxy->setZPosRolePattern(QRegExp(QStringLiteral("^(\\d*)(\\/)(\\d*)\\/\\d*[\\.\\,]?\\d*\\/\\d*[\\.\\,]?\\d*$")));
+ surfaceProxy->setZPosRoleReplace(QStringLiteral("\\1"));
+ QBar3DSeries *barSeries = new QBar3DSeries(barProxy);
+ QSurface3DSeries *surfaceSeries = new QSurface3DSeries(surfaceProxy);
+ barSeries->setMesh(QAbstract3DSeries::MeshPyramid);
+ barGraph->addSeries(barSeries);
+ surfaceGraph->addSeries(surfaceSeries);
+
+ barGraph->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPresetBehind);
+ surfaceGraph->scene()->activeCamera()->setCameraPreset(Q3DCamera::CameraPresetFront);
+
+ GraphDataGenerator generator(barGraph, surfaceGraph, tableWidget);
+ QObject::connect(barSeries, &QBar3DSeries::selectedBarChanged, &generator,
+ &GraphDataGenerator::selectFromTable);
+ QObject::connect(surfaceSeries, &QSurface3DSeries::selectedPointChanged, &generator,
+ &GraphDataGenerator::selectFromTable);
+ QObject::connect(tableWidget, &QTableWidget::currentCellChanged, &generator,
+ &GraphDataGenerator::selectedFromTable);
+ QObject::connect(changeSelectedButton, &QPushButton::clicked, &generator,
+ &GraphDataGenerator::changeSelectedButtonClicked);
+
+ QSize screenSize = barGraph->screen()->size();
+ widget.resize(QSize(screenSize.width() / 2, screenSize.height() / 2));
+ widget.show();
+ generator.start();
+ return app.exec();
+}
diff --git a/tests/manual/kinectsurface/QtKinectWrapper/00openni_notes.txt b/tests/manual/kinectsurface/QtKinectWrapper/00openni_notes.txt
new file mode 100644
index 00000000..2487a1ff
--- /dev/null
+++ b/tests/manual/kinectsurface/QtKinectWrapper/00openni_notes.txt
@@ -0,0 +1,2 @@
+OpenNI/Include: contains includes of OpenNI-1.5.4
+
diff --git a/tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/ARC/XnOSARC.h b/tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/ARC/XnOSARC.h
new file mode 100644
index 00000000..0a183724
--- /dev/null
+++ b/tests/manual/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/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/ARC/XnPlatformARC.h b/tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/ARC/XnPlatformARC.h
new file mode 100644
index 00000000..01bebafe
--- /dev/null
+++ b/tests/manual/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/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/Android-Arm/XnPlatformAndroid-Arm.h b/tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/Android-Arm/XnPlatformAndroid-Arm.h
new file mode 100644
index 00000000..948a47ea
--- /dev/null
+++ b/tests/manual/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/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/IXnNodeAllocator.h b/tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/IXnNodeAllocator.h
new file mode 100644
index 00000000..1571e881
--- /dev/null
+++ b/tests/manual/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/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/Linux-Arm/XnPlatformLinux-Arm.h b/tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/Linux-Arm/XnPlatformLinux-Arm.h
new file mode 100644
index 00000000..877e4e72
--- /dev/null
+++ b/tests/manual/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/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/Linux-x86/XnOSLinux-x86.h b/tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/Linux-x86/XnOSLinux-x86.h
new file mode 100644
index 00000000..0cbd12fc
--- /dev/null
+++ b/tests/manual/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/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/Linux-x86/XnPlatformLinux-x86.h b/tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/Linux-x86/XnPlatformLinux-x86.h
new file mode 100644
index 00000000..1b91a388
--- /dev/null
+++ b/tests/manual/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/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/MacOSX/XnPlatformMacOSX.h b/tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/MacOSX/XnPlatformMacOSX.h
new file mode 100644
index 00000000..cb46dd7d
--- /dev/null
+++ b/tests/manual/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/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/Win32/XnOSWin32.h b/tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/Win32/XnOSWin32.h
new file mode 100644
index 00000000..c821744d
--- /dev/null
+++ b/tests/manual/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/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/Win32/XnPlatformWin32.h b/tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/Win32/XnPlatformWin32.h
new file mode 100644
index 00000000..efc26ead
--- /dev/null
+++ b/tests/manual/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/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/Win32/usb100.h b/tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/Win32/usb100.h
new file mode 100644
index 00000000..63c87b58
--- /dev/null
+++ b/tests/manual/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/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnAlgorithms.h b/tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnAlgorithms.h
new file mode 100644
index 00000000..a829bcbb
--- /dev/null
+++ b/tests/manual/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/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnArray.h b/tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnArray.h
new file mode 100644
index 00000000..d90cff0c
--- /dev/null
+++ b/tests/manual/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/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnBaseNode.h b/tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnBaseNode.h
new file mode 100644
index 00000000..a4df6c11
--- /dev/null
+++ b/tests/manual/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/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnBitSet.h b/tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnBitSet.h
new file mode 100644
index 00000000..89ad6450
--- /dev/null
+++ b/tests/manual/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/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnCallback.h b/tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnCallback.h
new file mode 100644
index 00000000..4d2418c8
--- /dev/null
+++ b/tests/manual/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/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnCodecIDs.h b/tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnCodecIDs.h
new file mode 100644
index 00000000..f90025d0
--- /dev/null
+++ b/tests/manual/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/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnContext.h b/tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnContext.h
new file mode 100644
index 00000000..fb6414c4
--- /dev/null
+++ b/tests/manual/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/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnCppWrapper.h b/tests/manual/kinectsurface/QtKinectWrapper/OpenNI/Include/XnCppWrapper.h
new file mode 100644
index 00000000..1984be3d
--- /dev/null
+++ b/tests/manual/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
<